From c360fd7e2c2a1de0e318d185533f9789dc84a9c4 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 6 May 2019 09:27:44 +0200 Subject: [PATCH 001/326] Use exiv2 for metadata handling --- .gitignore | 1 - CMakeLists.txt | 23 +- clean.bat | 4 - rtengine/CMakeLists.txt | 6 +- rtengine/dcp.cc | 437 +++- rtengine/dfmanager.cc | 2 +- rtengine/dynamicprofile.cc | 2 +- rtengine/ffmanager.cc | 2 +- rtengine/histmatching.cc | 6 +- rtengine/imagedata.cc | 1543 ++++---------- rtengine/imagedata.h | 110 +- rtengine/imageio.cc | 434 +--- rtengine/imageio.h | 30 +- rtengine/improccoordinator.cc | 21 +- rtengine/improcfun.cc | 5 +- rtengine/iptcpairs.h | 49 - rtengine/previewimage.cc | 3 +- rtengine/procparams.cc | 69 +- rtengine/procparams.h | 86 +- rtengine/rawimagesource.cc | 3 +- rtengine/rawmetadatalocation.h | 41 - rtengine/rtengine.h | 73 +- rtengine/rtthumbnail.cc | 57 +- rtengine/rtthumbnail.h | 6 +- rtengine/simpleprocess.cc | 23 +- rtexif/CMakeLists.txt | 17 - rtexif/canonattribs.cc | 2078 ------------------- rtexif/fujiattribs.cc | 316 --- rtexif/kodakattribs.cc | 165 -- rtexif/nikonattribs.cc | 1271 ------------ rtexif/olympusattribs.cc | 846 -------- rtexif/panasonicattribs.cc | 142 -- rtexif/pentaxattribs.cc | 2219 -------------------- rtexif/rtexif.cc | 3488 -------------------------------- rtexif/rtexif.h | 690 ------- rtexif/sonyminoltaattribs.cc | 2640 ------------------------ rtexif/stdattribs.cc | 931 --------- rtgui/CMakeLists.txt | 2 +- rtgui/cacheimagedata.cc | 4 - rtgui/cacheimagedata.h | 42 +- rtgui/editorpanel.cc | 14 +- rtgui/exifpanel.cc | 567 ++---- rtgui/exifpanel.h | 54 +- rtgui/iptcpanel.cc | 140 +- rtgui/resize.cc | 1 + rtgui/shcselector.cc | 1 + rtgui/thumbnail.cc | 111 +- rtgui/thumbnail.h | 2 +- tools/generateRtexifUpdates | 92 - 49 files changed, 1359 insertions(+), 17510 deletions(-) delete mode 100644 rtengine/iptcpairs.h delete mode 100644 rtengine/rawmetadatalocation.h delete mode 100644 rtexif/CMakeLists.txt delete mode 100644 rtexif/canonattribs.cc delete mode 100644 rtexif/fujiattribs.cc delete mode 100644 rtexif/kodakattribs.cc delete mode 100644 rtexif/nikonattribs.cc delete mode 100644 rtexif/olympusattribs.cc delete mode 100644 rtexif/panasonicattribs.cc delete mode 100644 rtexif/pentaxattribs.cc delete mode 100644 rtexif/rtexif.cc delete mode 100644 rtexif/rtexif.h delete mode 100644 rtexif/sonyminoltaattribs.cc delete mode 100644 rtexif/stdattribs.cc delete mode 100755 tools/generateRtexifUpdates diff --git a/.gitignore b/.gitignore index 21ebf986a..331bf634f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ Release rtdata/rawtherapee.desktop rtengine/librtengine.a -rtexif/librtexif.a rtgui/config.h rtgui/version.h rtgui/rawtherapee diff --git a/CMakeLists.txt b/CMakeLists.txt index f13231586..c907824c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,24 @@ 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) +# Require exiv2 >= 0.24 to make sure everything we need is available +#find_package(Exiv2 0.24 REQUIRED) +pkg_check_modules(EXIV2 REQUIRED exiv2>=0.24) +#include_directories(SYSTEM ${Exiv2_INCLUDE_DIRS}) +#list(APPEND LIBS ${EXIV2_LIBRARIES}) +add_definitions(${EXIV2_DEFINITIONS}) +set(_exiv2_libs ${EXIV2_LIBRARIES}) +set(EXIV2_LIBRARIES "") +foreach(l ${_exiv2_libs}) + set(_el "_el-NOTFOUND") + if(EXIV2_LIBRARY_DIRS) + find_library(_el ${l} PATHS ${EXIV2_LIBRARY_DIRS} NO_DEFAULT_PATH) + else() + find_library(_el ${l} PATHS ${EXIV2_LIBRARY_DIRS}) + endif() + set(EXIV2_LIBRARIES ${EXIV2_LIBRARIES} ${_el}) +endforeach() + if(WIN32) add_definitions(-DWIN32) add_definitions(-D_WIN32) @@ -333,7 +351,6 @@ endif() pkg_check_modules(LCMS REQUIRED lcms2>=2.6) pkg_check_modules(EXPAT REQUIRED expat>=2.1) pkg_check_modules(FFTW3F REQUIRED fftw3f) -pkg_check_modules(IPTCDATA REQUIRED libiptcdata) pkg_check_modules(TIFF REQUIRED libtiff-4>=4.0.4) find_package(JPEG REQUIRED) find_package(PNG REQUIRED) @@ -398,6 +415,7 @@ if(OPENMP_FOUND) set(CMAKE_REQUIRED_INCLUDES ${FFTW3F_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES) foreach(l ${FFTW3F_LIBRARIES}) + set(_f "_f-NOTFOUND") find_library(_f ${l} PATHS ${FFTW3F_LIBRARY_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_f}) endforeach() @@ -538,11 +556,13 @@ foreach(l ${LENSFUN_LIBRARIES}) # the NO_DEFAULT_PATH is to make sure we find the lensfun version we # want, and not the system's one (e.g. if we have a custom version # installed in a non-standard location) + set(_l "_l-NOTFOUND") find_library(_l ${l} PATHS ${LENSFUN_LIBRARY_DIRS} NO_DEFAULT_PATH) else() # LENSFUN_LIBRARY_DIRS can be empty if lensfun is installed in the # default path. In this case, adding NO_DEFAULT_PATH would make # find_library fail... + set(_l "_l-NOTFOUND") find_library(_l ${l}) endif() set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_l}) @@ -557,7 +577,6 @@ int main() }" LENSFUN_HAS_LOAD_DIRECTORY) -add_subdirectory(rtexif) add_subdirectory(rtengine) add_subdirectory(rtgui) add_subdirectory(rtdata) diff --git a/clean.bat b/clean.bat index 6a549821e..52e77f954 100644 --- a/clean.bat +++ b/clean.bat @@ -4,24 +4,20 @@ del .\install_manifest.txt rmdir /s /q .\CMakeFiles rmdir /s /q .\rtengine\CMakeFiles -rmdir /s /q .\rtexif\CMakeFiles rmdir /s /q .\rtgui\CMakeFiles rmdir /s /q .\rtdata\CMakeFiles del .\cmake_* del .\rtengine\cmake_* -del .\rtexif\cmake_* del .\rtgui\cmake_* del .\rtdata\cmake_* del .\Makefile del .\rtengine\Makefile -del .\rtexif\Makefile del .\rtgui\Makefile del .\rtdata\Makefile del .\rtengine\librtengine.so del .\rtengine\librtengine.a del .\rtgui\rawtherapee -del .\rtexif\librtexif.so del .\rtexif\librtexif.a diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index a1037f5a3..4f4dd1beb 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -11,9 +11,10 @@ include_directories(${EXTRA_INCDIR} ${LCMS_INCLUDE_DIRS} ${LENSFUN_INCLUDE_DIRS} ${RSVG_INCLUDE_DIRS} + ${EXIV2_INCLUDE_DIRS} ) -link_directories("${PROJECT_SOURCE_DIR}/rtexif" +link_directories( ${EXPAT_LIBRARY_DIRS} ${EXTRA_LIBDIR} ${FFTW3F_LIBRARY_DIRS} @@ -170,7 +171,7 @@ endif() set_target_properties(rtengine PROPERTIES COMPILE_FLAGS "${RTENGINE_CXX_FLAGS}") -target_link_libraries(rtengine rtexif +target_link_libraries(rtengine ${EXPAT_LIBRARIES} ${EXTRA_LIB} ${FFTW3F_LIBRARIES} @@ -186,6 +187,7 @@ target_link_libraries(rtengine rtexif ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} + ${EXIV2_LIBRARIES} ) install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 1c99b682c..0f5b32d34 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -39,10 +39,8 @@ extern const Settings* settings; } using namespace rtengine; -using namespace rtexif; -namespace -{ +namespace { // This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here @@ -444,7 +442,308 @@ std::map getAliases(const Glib::ustring& profile_dir) return res; } -} + +class DCPMetadata { + enum TagType { + INVALID = 0, + BYTE = 1, + ASCII = 2, + SHORT = 3, + LONG = 4, + RATIONAL = 5, + SBYTE = 6, + UNDEFINED = 7, + SSHORT = 8, + SLONG = 9, + SRATIONAL = 10, + FLOAT = 11, + DOUBLE = 12 + }; + + enum ByteOrder { + UNKNOWN = 0, + INTEL = 0x4949, + MOTOROLA = 0x4D4D + }; + +public: + explicit DCPMetadata(FILE *file): order_(UNKNOWN), file_(file) {} + + bool parse() + { + int offset = 0; + FILE *f = file_; + + if (!f) { +#ifndef NDEBUG + std::cerr << "ERROR : no file opened !" << std::endl; +#endif + return false; + } + setlocale(LC_NUMERIC, "C"); // to set decimal point in sscanf + + // read tiff header + fseek(f, 0, SEEK_SET); + unsigned short bo; + fread(&bo, 1, 2, f); + order_ = ByteOrder(int(bo)); + + get2(f, order_); + if (!offset) { + offset = get4(f, order_); + } + + // seek to IFD + fseek(f, offset, SEEK_SET); + + // first read the IFD directory + int numtags = get2(f, order_); + + if (numtags <= 0 || numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit + return false; + } + + int base = 0; + for (int i = 0; i < numtags; i++) { + Tag t; + if (parse_tag(t, f, base, order_)) { + tags_[t.id] = std::move(t); + } + } + + return true; + } + + bool find(int id) const + { + return tags_.find(id) != tags_.end(); + } + + std::string toString(int id) + { + auto it = tags_.find(id); + if (it != tags_.end()) { + auto &t = it->second; + if (t.type == ASCII) { + std::ostringstream buf; + unsigned char *value = &(t.value[0]); + buf << value; + return buf.str(); + } + } + return ""; + } + + int toInt(int id, int ofs=0, TagType astype=INVALID) + { + auto it = tags_.find(id); + if (it == tags_.end()) { + return 0; + } + + auto &t = it->second; + int a; + unsigned char *value = &(t.value[0]); + + if (astype == INVALID) { + astype = t.type; + } + + switch (astype) { + case SBYTE: + return reinterpret_cast(value)[ofs]; + + case BYTE: + return value[ofs]; + + case SSHORT: + return int2_to_signed(sget2(value + ofs, order_)); + + case SHORT: + return sget2(value + ofs, order_); + + case SLONG: + case LONG: + return sget4 (value + ofs, order_); + + case SRATIONAL: + case RATIONAL: + a = sget4(value + ofs + 4, order_); + return a == 0 ? 0 : int(sget4(value + ofs, order_)) / a; + + case FLOAT: + return toDouble(id, ofs); + + default: + return 0; + } + } + + int toShort(int id, int ofs=0) + { + return toInt(id, ofs, SHORT); + } + + double toDouble(int id, int ofs=0) + { + auto it = tags_.find(id); + if (it == tags_.end()) { + return 0.0; + } + + auto &t = it->second; + + union IntFloat { + uint32_t i; + float f; + } conv; + + int ud, dd; + unsigned char *value = &(t.value[0]); + + switch (t.type) { + case SBYTE: + return int((reinterpret_cast (value))[ofs]); + + case BYTE: + return int(value[ofs]); + + case SSHORT: + return int2_to_signed(sget2(value + ofs, order_)); + + case SHORT: + return sget2(value + ofs, order_); + + case SLONG: + case LONG: + return sget4(value + ofs, order_); + + case SRATIONAL: + case RATIONAL: + ud = sget4(value + ofs, order_); + dd = sget4(value + ofs + 4, order_); + return (dd ? double(ud)/double(dd) : 0.0); + + case FLOAT: + conv.i = sget4(value + ofs, order_); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + + default: + return 0.; + } + } + + unsigned int getCount(int id) + { + auto it = tags_.find(id); + if (it != tags_.end()) { + return it->second.count; + } + return 0; + } + +private: + static unsigned short sget2(unsigned char *s, ByteOrder order) + { + if (order == INTEL) { + return s[0] | s[1] << 8; + } else { + return s[0] << 8 | s[1]; + } + } + + static int sget4(unsigned char *s, ByteOrder order) + { + if (order == INTEL) { + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + } else { + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; + } + } + + static unsigned short get2(FILE* f, ByteOrder order) + { + unsigned char str[2] = { 0xff, 0xff }; + fread (str, 1, 2, f); + return sget2(str, order); + } + + static int get4(FILE *f, ByteOrder order) + { + unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; + fread (str, 1, 4, f); + return sget4 (str, order); + } + + static short int int2_to_signed(short unsigned int i) + { + union { + short unsigned int i; + short int s; + } u; + u.i = i; + return u.s; + } + + static int getTypeSize(TagType type) + { + return ("11124811248484"[type < 14 ? type : 0] - '0'); + } + + struct Tag { + int id; + std::vector value; + TagType type; + unsigned int count; + + Tag(): id(0), value(), type(INVALID), count(0) {} + }; + + bool parse_tag(Tag &t, FILE *f, int base, ByteOrder order) + { + t.id = get2(f, order); + t.type = (TagType)get2(f, order); + t.count = get4(f, order); + + if (!t.count) { + t.count = 1; + } + + // filter out invalid tags + // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, + // (only a small part of it will actually be parsed though) + if ((int)t.type < 1 || (int)t.type > 12 || t.count > 10 * 1024 * 1024) { + t.type = INVALID; + return false; + } + + // store next Tag's position in file + int save = ftell(f) + 4; + + // load value field (possibly seek before) + int valuesize = t.count * getTypeSize(t.type); + + if (valuesize > 4) { + fseek(f, get4(f, order) + base, SEEK_SET); + } + + // read value + t.value.resize(valuesize + 1); + auto readSize = fread(&(t.value[0]), 1, valuesize, f); + t.value[readSize] = '\0'; + + // seek back to the saved position + fseek(f, save, SEEK_SET); + return true; + } + + std::unordered_map tags_; + ByteOrder order_; + FILE *file_; +}; + +} // namespace + struct DCPProfile::ApplyState::Data { float pro_photo[3][3]; @@ -478,7 +777,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : delta_info.hue_step = delta_info.val_step = look_info.hue_step = look_info.val_step = 0; constexpr int tiff_float_size = 4; - enum class TagKey : int { + enum TagKey { COLOR_MATRIX_1 = 50721, COLOR_MATRIX_2 = 50722, PROFILE_HUE_SAT_MAP_DIMS = 50937, @@ -764,54 +1063,48 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : return; } - ExifManager exifManager(file, nullptr, true); - exifManager.parseTIFF(false); - std::unique_ptr tagDir(exifManager.roots.at(0)); + DCPMetadata md(file); + if (!md.parse()) { + printf ("Unable to load DCP profile '%s' !", filename.c_str()); + return; + } - Tag* tag = tagDir->getTag(toUnderlying(TagKey::CALIBRATION_ILLUMINANT_1)); light_source_1 = - tag - ? tag->toInt(0, rtexif::SHORT) - : -1; - tag = tagDir->getTag(toUnderlying(TagKey::CALIBRATION_ILLUMINANT_2)); + md.find(CALIBRATION_ILLUMINANT_1) ? + md.toShort(CALIBRATION_ILLUMINANT_1) : + -1; light_source_2 = - tag - ? tag->toInt(0, rtexif::SHORT) - : -1; + md.find(CALIBRATION_ILLUMINANT_2) ? + md.toShort(CALIBRATION_ILLUMINANT_2) : + -1; temperature_1 = calibrationIlluminantToTemperature(light_source_1); temperature_2 = calibrationIlluminantToTemperature(light_source_2); - const bool has_second_hue_sat = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_2)); // Some profiles have two matrices, but just one huesat + const bool has_second_hue_sat = md.find(PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat // Fetch Forward Matrices, if any - tag = tagDir->getTag(toUnderlying(TagKey::FORWARD_MATRIX_1)); - - if (tag) { - has_forward_matrix_1 = true; + has_forward_matrix_1 = md.find(FORWARD_MATRIX_1); + if (has_forward_matrix_1) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_1[row][col] = tag->toDouble((col + row * 3) * 8); + forward_matrix_1[row][col] = md.toDouble(FORWARD_MATRIX_1, (col + row * 3) * 8); } } } - tag = tagDir->getTag(toUnderlying(TagKey::FORWARD_MATRIX_2)); - - if (tag) { - has_forward_matrix_2 = true; + has_forward_matrix_2 = md.find(FORWARD_MATRIX_2); + if (has_forward_matrix_2) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_2[row][col] = tag->toDouble((col + row * 3) * 8); + forward_matrix_2[row][col] = md.toDouble(FORWARD_MATRIX_2, (col + row * 3) * 8); } } } // Color Matrix (one is always there) - tag = tagDir->getTag(toUnderlying(TagKey::COLOR_MATRIX_1)); - - if (!tag) { + if (!md.find(COLOR_MATRIX_1)) { std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; fclose(file); return; @@ -821,29 +1114,24 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - color_matrix_1[row][col] = tag->toDouble((col + row * 3) * 8); + color_matrix_1[row][col] = md.toDouble(COLOR_MATRIX_1, (col + row * 3) * 8); } } - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_DIMS)); + if (md.find(PROFILE_LOOK_TABLE_DIMS)) { + look_info.hue_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 0); + look_info.sat_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 4); + look_info.val_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 8); - if (tag) { - look_info.hue_divisions = tag->toInt(0); - look_info.sat_divisions = tag->toInt(4); - look_info.val_divisions = tag->toInt(8); - - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_ENCODING)); - look_info.srgb_gamma = tag && tag->toInt(0); - - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_LOOK_TABLE_DATA)); - look_info.array_count = tag->getCount() / 3; + look_info.srgb_gamma = md.find(PROFILE_LOOK_TABLE_ENCODING) && md.toInt(PROFILE_LOOK_TABLE_ENCODING); + look_info.array_count = md.getCount(PROFILE_LOOK_TABLE_DATA) / 3; look_table.resize(look_info.array_count); for (unsigned int i = 0; i < look_info.array_count; i++) { - look_table[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); - look_table[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); - look_table[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + look_table[i].hue_shift = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); + look_table[i].sat_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); + look_table[i].val_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); } // Precalculated constants for table application @@ -860,25 +1148,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : look_info.pc.val_step = look_info.hue_divisions * look_info.pc.hue_step; } - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DIMS)); + if (md.find(PROFILE_HUE_SAT_MAP_DIMS)) { + delta_info.hue_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 0); + delta_info.sat_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 4); + delta_info.val_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 8); - if (tag) { - delta_info.hue_divisions = tag->toInt(0); - delta_info.sat_divisions = tag->toInt(4); - delta_info.val_divisions = tag->toInt(8); - - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_ENCODING)); - delta_info.srgb_gamma = tag && tag->toInt(0); - - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_1)); - delta_info.array_count = tag->getCount() / 3; + delta_info.srgb_gamma = md.find(PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(PROFILE_HUE_SAT_MAP_ENCODING); + delta_info.array_count = md.getCount(PROFILE_HUE_SAT_MAP_DATA_1) / 3; deltas_1.resize(delta_info.array_count); for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_1[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); - deltas_1[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); - deltas_1[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + deltas_1[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); + deltas_1[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); + deltas_1[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); } delta_info.pc.h_scale = @@ -898,13 +1181,13 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Second matrix has_color_matrix_2 = true; - tag = tagDir->getTag(toUnderlying(TagKey::COLOR_MATRIX_2)); + bool cm2 = md.find(COLOR_MATRIX_2); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { color_matrix_2[row][col] = - tag - ? tag->toDouble((col + row * 3) * 8) + cm2 + ? md.toDouble(COLOR_MATRIX_2, (col + row * 3) * 8) : color_matrix_1[row][col]; } } @@ -914,27 +1197,21 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : deltas_2.resize(delta_info.array_count); // Saturation maps. Need to be unwinded. - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_HUE_SAT_MAP_DATA_2)); - for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_2[i].hue_shift = tag->toDouble((i * 3) * tiff_float_size); - deltas_2[i].sat_scale = tag->toDouble((i * 3 + 1) * tiff_float_size); - deltas_2[i].val_scale = tag->toDouble((i * 3 + 2) * tiff_float_size); + deltas_2[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); + deltas_2[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); + deltas_2[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); } } } - tag = tagDir->getTag(toUnderlying(TagKey::BASELINE_EXPOSURE_OFFSET)); - - if (tag) { - has_baseline_exposure_offset = true; - baseline_exposure_offset = tag->toDouble(); + has_baseline_exposure_offset = md.find(BASELINE_EXPOSURE_OFFSET); + if (has_baseline_exposure_offset) { + baseline_exposure_offset = md.toDouble(BASELINE_EXPOSURE_OFFSET); } // Read tone curve points, if any, but disable to RTs own profiles - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_TONE_CURVE)); - - if (tag) { + if (md.find(PROFILE_TONE_CURVE)) { std::vector curve_points = { static_cast(DCT_Spline) // The first value is the curve type }; @@ -942,9 +1219,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Push back each X/Y coordinates in a loop bool curve_is_linear = true; - for (int i = 0; i < tag->getCount(); i += 2) { - const double x = tag->toDouble((i + 0) * tiff_float_size); - const double y = tag->toDouble((i + 1) * tiff_float_size); + for (unsigned int i = 0, n = md.getCount(PROFILE_TONE_CURVE); i < n; i += 2) { + const double x = md.toDouble(PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); + const double y = md.toDouble(PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); if (x != y) { curve_is_linear = false; @@ -960,9 +1237,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); } } else { - tag = tagDir->getTag(toUnderlying(TagKey::PROFILE_TONE_COPYRIGHT)); - - if (tag && tag->valueToString().find("Adobe Systems") != std::string::npos) { + if (md.find(PROFILE_TONE_COPYRIGHT) && md.toString(PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { // An Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that std::vector curve_points = { static_cast(DCT_Spline) diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 5f1035a8e..34475f545 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -383,7 +383,7 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) return &(iter->second); } - FramesData idata(filename, std::unique_ptr(new RawMetaDataLocation(ri.get_exifBase(), ri.get_ciffBase(), ri.get_ciffLen())), true); + FramesData idata(filename); /* Files are added in the map, divided by same maker/model,ISO and shutter*/ std::string key(dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed())); iter = dfList.find(key); diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 7b7f2a517..7939936e9 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -81,7 +81,7 @@ bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const && expcomp (im->getExpComp()) && camera (im->getCamera()) && lens (im->getLens()) - && imagetype(im->getImageType(0))); + && imagetype(im->getImageType())); } namespace diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 6b0302d1e..89b5c7154 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -332,7 +332,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) return &(iter->second); } - FramesData idata(filename, std::unique_ptr(new RawMetaDataLocation(ri.get_exifBase(), ri.get_ciffBase(), ri.get_ciffLen())), true); + FramesData idata(filename); /* Files are added in the map, divided by same maker/model,lens and aperture*/ std::string key(ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber())); iter = ffList.find(key); diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index e48f2017a..5a17ab6ec 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -278,10 +278,9 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st std::unique_ptr source; { - RawMetaDataLocation rml; eSensorType sensor_type; int w, h; - std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, true, true)); + std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), sensor_type, w, h, 1, false, true, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: no thumbnail found, generating a neutral curve" << std::endl; @@ -310,11 +309,10 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st std::unique_ptr target; { - RawMetaDataLocation rml; eSensorType sensor_type; double scale; int w = fw / skip, h = fh / skip; - std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false, true)); + std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), sensor_type, w, h, 1, false, false, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4e38c612a..e0f6b50a3 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -20,69 +20,78 @@ #include #include #include +#include #include "imagedata.h" -#include "iptcpairs.h" #include "imagesource.h" #include "rt_math.h" -#include "procparams.h" - #pragma GCC diagnostic warning "-Wextra" #define PRINT_HDR_PS_DETECTION 0 using namespace rtengine; -extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile); -namespace -{ +// namespace { -Glib::ustring to_utf8 (const std::string& str) +// Glib::ustring to_utf8 (const std::string& str) +// { +// try { +// return Glib::locale_to_utf8 (str); +// } catch (Glib::Error&) { +// return Glib::convert_with_fallback (str, "UTF-8", "ISO-8859-1", "?"); +// } +// } + +// } // namespace + + +namespace rtengine { + +extern const Settings *settings; + +Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname) { - try { - return Glib::locale_to_utf8 (str); - } catch (Glib::Error&) { - return Glib::convert_with_fallback (str, "UTF-8", "ISO-8859-1", "?"); - } +#ifdef EXV_UNICODE_PATH + auto *ws = g_utf8_to_utf16(fname.c_str(), -1, NULL, NULL, NULL); + std::wstring wfname(ws); + g_free(ws); + auto image = Exiv2::ImageFactory::open(wfname); +#else + auto image = Exiv2::ImageFactory::open(fname); +#endif + return image; } -template -T getFromFrame( - const std::vector>& frames, - std::size_t frame, - const std::function& function -) +} // namespace rtengine + + + +FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname) { - if (frame < frames.size()) { - return function(*frames[frame]); - } - if (!frames.empty()) { - return function(*frames[0]); - } - return {}; + return new FramesData(fname); } -} - -FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) +FramesData::FramesData(const Glib::ustring &fname): + ok_(false), + fname_(fname), + dcrawFrameCount(0), + time(), + timeStamp(), + iso_speed(0), + aperture(0.), + focal_len(0.), + focal_len35mm(0.), + focus_dist(0.f), + shutter(0.), + expcomp(0.), + make("Unknown"), + model("Unknown"), + orientation("Unknown"), + lens("Unknown"), + sampleFormat(IIOSF_UNKNOWN), + isPixelShift(false), + isHDR(false) { - return new FramesData (fname, std::move(rml), firstFrameOnly); -} - -FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) - : frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), - shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), lens("Unknown"), - sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) -{ - memset (&time, 0, sizeof(time)); - - if (!frameRootDir) { - return; - } - - rtexif::Tag* tag; - rtexif::TagDirectory* newFrameRootDir = frameRootDir; - memset(&time, 0, sizeof(time)); timeStamp = 0; iso_speed = 0; @@ -98,1082 +107,476 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* orientation.clear(); lens.clear(); - tag = newFrameRootDir->findTag("Make"); - if (!tag) { - newFrameRootDir = rootDir; - tag = newFrameRootDir->findTag("Make"); - if (!tag) { - // For some raw files (like Canon's CR2 files), the metadata are contained in the first root directory - newFrameRootDir = firstRootDir; - tag = newFrameRootDir->findTag("Make"); + try { + auto image = open_exiv2(fname); + image->readMetadata(); + auto &exif = image->exifData(); + ok_ = true; + + // taken and adapted from darktable (src/common/exif.cc) +/* + This file is part of darktable, + copyright (c) 2009--2013 johannes hanika. + copyright (c) 2011 henrik andersson. + copyright (c) 2012-2017 tobias ellinghaus. + + 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 . + */ + + Exiv2::ExifData::const_iterator pos; + + const auto find_exif_tag = + [&](const std::string &name) -> bool + { + pos = exif.findKey(Exiv2::ExifKey(name)); + return (pos != exif.end() && pos->size()); + }; + + const auto find_tag = + [&](decltype(Exiv2::make) func) -> bool + { + pos = func(exif); + return pos != exif.end() && pos->size(); + }; + + /* List of tag names taken from exiv2's printSummary() in actions.cpp */ + + if (find_tag(Exiv2::make)) { + make = pos->print(&exif); } - } - if (tag) { - make = tag->valueToString(); - // Same dcraw treatment - for (const auto& corp : { - "Canon", - "NIKON", - "EPSON", - "KODAK", - "Kodak", - "OLYMPUS", - "PENTAX", - "RICOH", - "MINOLTA", - "Minolta", - "Konica", - "CASIO", - "Sinar", - "Phase One", - "SAMSUNG", - "Mamiya", - "MOTOROLA", - "Leaf", - "Panasonic" - }) { - if (make.find(corp) != std::string::npos) { // Simplify company names - make = corp; - break; + + if (find_tag(Exiv2::model)) { + model = pos->print(&exif); + } + + if (make.size() > 0) { + for (const auto& corp : { + "Canon", + "NIKON", + "EPSON", + "KODAK", + "Kodak", + "OLYMPUS", + "PENTAX", + "RICOH", + "MINOLTA", + "Minolta", + "Konica", + "CASIO", + "Sinar", + "Phase One", + "SAMSUNG", + "Mamiya", + "MOTOROLA", + "Leaf", + "Panasonic" + }) { + if (make.find(corp) != std::string::npos) { // Simplify company names + make = corp; + break; + } } - } - + } make.erase(make.find_last_not_of(' ') + 1); - } - - tag = newFrameRootDir->findTagUpward("Model"); - if (tag) { - model = tag->valueToString(); - } - - if (!model.empty()) { - std::string::size_type i = 0; - - if ( - make.find("KODAK") != std::string::npos - && ( - (i = model.find(" DIGITAL CAMERA")) != std::string::npos - || (i = model.find(" Digital Camera")) != std::string::npos - || (i = model.find("FILE VERSION")) != std::string::npos - ) - ) { - model.resize(i); - } - model.erase(model.find_last_not_of(' ') + 1); - if (!strncasecmp(model.c_str(), make.c_str(), make.size())) { - if (model.size() >= make.size() && model[make.size()] == ' ') { - model.erase(0, make.size() + 1); + if (make.length() > 0 && model.find(make + " ") == 0) { + model = model.substr(make.length() + 1); + } + + if (find_tag(Exiv2::exposureTime)) { + shutter = pos->toFloat(); + } + + if (find_tag(Exiv2::fNumber)) { + aperture = pos->toFloat(); + } + + /* Read ISO speed - Nikon happens to return a pair for Lo and Hi modes */ + if (find_tag(Exiv2::isoSpeed)) { + // if standard exif iso tag, use the old way of interpreting the return value to be more regression-save + if (strcmp(pos->key().c_str(), "Exif.Photo.ISOSpeedRatings") == 0) { + int isofield = pos->count() > 1 ? 1 : 0; + iso_speed = pos->toFloat(isofield); + } else { + std::string str = pos->print(); + iso_speed = std::atof(str.c_str()); + } + } + // some newer cameras support iso settings that exceed the 16 bit of exif's ISOSpeedRatings + if (iso_speed == 65535 || iso_speed == 0) { + if (find_exif_tag("Exif.PentaxDng.ISO") || find_exif_tag("Exif.Pentax.ISO")) { + std::string str = pos->print(); + iso_speed = std::atof(str.c_str()); + } else if((!g_strcmp0(make.c_str(), "SONY") || !g_strcmp0(make.c_str(), "Canon")) + && find_exif_tag("Exif.Photo.RecommendedExposureIndex")) { + iso_speed = pos->toFloat(); } } - if (model.find( "Digital Camera ") != std::string::npos) { - model.erase(0, 15); - } - } else { - model = "Unknown"; - } - - if (model == "Unknown") { - tag = newFrameRootDir->findTag("UniqueCameraModel"); - if (tag) { - model = tag->valueToString(); - } - } - - tag = newFrameRootDir->findTagUpward("Orientation"); - if (tag) { - orientation = tag->valueToString (); - } - - tag = newFrameRootDir->findTagUpward("MakerNote"); - rtexif::TagDirectory* mnote = nullptr; - if (tag) { - mnote = tag->getDirectory(); - } - - rtexif::TagDirectory* exif = nullptr; - tag = newFrameRootDir->findTagUpward("Exif"); - if (tag) { - exif = tag->getDirectory (); - } - - if (exif) { - - // standard exif tags - if ((tag = exif->getTag ("ShutterSpeedValue"))) { - shutter = tag->toDouble (); - } - - if ((tag = exif->getTag ("ExposureTime"))) { - shutter = tag->toDouble (); - } - - if ((tag = exif->getTag ("ApertureValue"))) { - aperture = tag->toDouble (); - } - - if ((tag = exif->getTag ("FNumber"))) { - aperture = tag->toDouble (); - } - - if ((tag = exif->getTag ("ExposureBiasValue"))) { - expcomp = tag->toDouble (); - } - - if ((tag = exif->getTag ("FocalLength"))) { - focal_len = tag->toDouble (); - } - - if ((tag = exif->getTag ("FocalLengthIn35mmFilm"))) { - focal_len35mm = tag->toDouble (); - } - - // Focus distance from EXIF or XMP. MakerNote ones are scattered and partly encrypted - int num = -3, denom = -3; - - // First try, official EXIF. Set by Adobe on some DNGs - tag = exif->getTag("SubjectDistance"); - - if (tag) { - int num, denom; - tag->toRational(num, denom); - } else { - // Second try, XMP data - char sXMPVal[64]; - - if (newFrameRootDir->getXMPTagValue("aux:ApproximateFocusDistance", sXMPVal)) { - sscanf(sXMPVal, "%d/%d", &num, &denom); + if (find_tag(Exiv2::focalLength)) { + // This works around a bug in exiv2 the developers refuse to fix + // For details see http://dev.exiv2.org/issues/1083 + if (pos->key() == "Exif.Canon.FocalLength" && pos->count() == 4) { + focal_len = pos->toFloat(1); + } else { + focal_len = pos->toFloat(); } } - if (num != -3) { - if ((denom == 1 && num >= 10000) || num < 0 || denom < 0) { - focus_dist = 10000; // infinity - } else if (denom > 0) { - focus_dist = (float)num / denom; - } + if (find_exif_tag("Exif.Photo.FocalLengthIn35mmFilm")) { + focal_len35mm = pos->toFloat(); } - if ((tag = exif->getTag ("ISOSpeedRatings"))) { - iso_speed = tag->toDouble (); + if (find_tag(Exiv2::subjectDistance)) { + focus_dist = (0.01 * pow(10, pos->toFloat() / 40)); + } + + if (find_tag(Exiv2::orientation)) { + orientation = pos->print(&exif); } - if ((tag = exif->findTag("DateTimeOriginal", true))) { - if (sscanf ((const char*)tag->getValue(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { - time.tm_year -= 1900; - time.tm_mon -= 1; - time.tm_isdst = -1; - timeStamp = mktime(&time); - } + if (find_tag(Exiv2::lensName)) { + lens = pos->print(&exif); + } + if (lens.empty()) { + lens = "Unknown"; } - tag = exif->findTag ("SerialNumber"); - - if(!tag) { - tag = exif->findTag ("InternalSerialNumber"); + std::string datetime_taken; + if (find_exif_tag("Exif.Image.DateTimeOriginal")) { + datetime_taken = pos->print(&exif); + } else if(find_exif_tag("Exif.Photo.DateTimeOriginal")) { + datetime_taken = pos->print(&exif); + } + if (sscanf(datetime_taken.c_str(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { + time.tm_year -= 1900; + time.tm_mon -= 1; + time.tm_isdst = -1; + timeStamp = mktime(&time); } - if (tag) { - serial = tag->valueToString(); + if (find_exif_tag("Exif.Image.ExposureBiasValue")) { + expcomp = pos->toFloat(); } - // guess lens... - lens = "Unknown"; + // ----------------------- + // Special file type detection (HDR, PixelShift) + // ------------------------ + uint16 bitspersample = 0, samplesperpixel = 0, sampleformat = 0, photometric = 0, compression = 0; + auto bps = exif.findKey(Exiv2::ExifKey("Exif.Image.BitsPerSample")); + auto spp = exif.findKey(Exiv2::ExifKey("Exif.Image.SamplesPerPixel")); + auto sf = exif.findKey(Exiv2::ExifKey("Exif.Image.SampleFormat")); + auto pi = exif.findKey(Exiv2::ExifKey("Exif.Image.PhotometricInterpretation")); + auto c = exif.findKey(Exiv2::ExifKey("Exif.Image.Compression")); - // Sometimes (e.g. DNG) EXIF already contains lens data - - if(!make.compare (0, 8, "FUJIFILM")) { - if(exif->getTag ("LensModel")) { - lens = exif->getTag ("LensModel")->valueToString (); - } - } else if(!make.compare (0, 4, "SONY")) { - if (iso_speed == 65535 || iso_speed == 0) { - rtexif::Tag* isoTag = exif->getTag ("RecommendedExposureIndex"); - - if(isoTag) { - iso_speed = isoTag->toDouble(); - } - } - - } - - if (lens == "Unknown") { - const auto lens_from_make_and_model = - [this, exif]() -> bool - { - if (!exif) { - return false; - } - - const rtexif::Tag* const lens_model = exif->getTag(0xA434); - - if (lens_model) { - const rtexif::Tag* const lens_make = exif->getTag(0xA433); - const std::string make = - lens_make - ? lens_make->valueToString() - : std::string(); - const std::string model = lens_model->valueToString(); - - if (!model.empty()) { - lens = make; - - if (!lens.empty()) { - lens += ' '; - } - - lens += model; - - return true; - } - } - - return false; - }; - - if (mnote) { - - if (!make.compare (0, 5, "NIKON")) { - // ISO at max value supported, check manufacturer specific - if (iso_speed == 65535 || iso_speed == 0) { - rtexif::Tag* isoTag = mnote->getTagP("ISOInfo/ISO"); - - if (isoTag) { - iso_speed = isoTag->toInt(); - } - } - - bool lensOk = false; - - if (mnote->getTag ("LensData")) { - std::string ldata = mnote->getTag ("LensData")->valueToString (); - size_t pos; - - if (ldata.size() > 10 && (pos = ldata.find ("Lens = ")) != Glib::ustring::npos) { - lens = ldata.substr (pos + 7); - - if (lens.compare (0, 7, "Unknown")) { - lensOk = true; - } else { - size_t pos = lens.find("$FL$"); // is there a placeholder for focallength? - - if(pos != Glib::ustring::npos) { // then fill in focallength - lens = lens.replace(pos, 4, exif->getTag ("FocalLength")->valueToString ()); - - if(mnote->getTag ("LensType")) { - std::string ltype = mnote->getTag ("LensType")->valueToString (); - - if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens, should be always - lens = lens.replace(0, 7, "MF"); - } - - lensOk = true; - } - } - } - // If MakeNotes are vague, fall back to Exif LensMake and LensModel if set - // https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#LensType - if (lens == "Manual Lens No CPU") { - lens_from_make_and_model(); - } - } - } - - if (!lensOk && mnote->getTag ("Lens")) { - std::string ldata = mnote->getTag ("Lens")->valueToString (); - size_t i = 0, j = 0; - double n[4] = {0.0}; - - for (int m = 0; m < 4; m++) { - while (i < ldata.size() && ldata[i] != '/') { - i++; - } - - int nom = atoi(ldata.substr(j, i).c_str()); - j = i + 1; - i++; - - while (i < ldata.size() && ldata[i] != ',') { - i++; - } - - int den = atoi(ldata.substr(j, i).c_str()); - j = i + 2; - i += 2; - n[m] = (double) nom / std::max(den,1); - } - - std::ostringstream str; - - if (n[0] == n[1]) { - str << "Unknown " << n[0] << "mm F/" << n[2]; - } else if (n[2] == n[3]) { - str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2]; - } else { - str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2] << "-" << n[3]; - } - - lens = str.str(); - - // Look whether it's MF or AF - if(mnote->getTag ("LensType")) { - std::string ltype = mnote->getTag ("LensType")->valueToString (); - - if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens - lens = lens.replace(0, 7, "MF"); // replace 'Unknwon' with 'MF' - } else { - lens = lens.replace(0, 7, "AF"); // replace 'Unknwon' with 'AF' - } - } - } - } else if (!make.compare (0, 5, "Canon")) { - // ISO at max value supported, check manufacturer specific - if (iso_speed == 65535 || iso_speed == 0) { - rtexif::Tag* baseIsoTag = mnote->getTagP("CanonShotInfo/BaseISO"); - - if (baseIsoTag) { - iso_speed = baseIsoTag->toInt(); - } - } - - int found = false; - // canon EXIF have a string for lens model - rtexif::Tag *lt = mnote->getTag("LensType"); - - if ( lt ) { - if (lt->toInt()) { - std::string ldata = lt->valueToString (); - - if (ldata.size() > 1) { - found = true; - lens = "Canon " + ldata; - } - } else { - found = lens_from_make_and_model(); - } - } - - const std::string::size_type first_space_pos = lens.find(' '); - const std::string::size_type remaining_size = - first_space_pos != std::string::npos - ? lens.size() - first_space_pos - : 0; - - if( !found || remaining_size < 7U ) { - lt = mnote->findTag("LensID"); - - if ( lt ) { - std::string ldata = lt->valueToString (); - - if (ldata.size() > 1) { - lens = ldata; - } - } - } - } else if (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX"))) { - // ISO at max value supported, check manufacturer specific - if (iso_speed == 65535 || iso_speed == 0) { - rtexif::Tag* baseIsoTag = mnote->getTag("ISO"); - if (baseIsoTag) { - std::string isoData = baseIsoTag->valueToString(); - if (isoData.size() > 1) { - iso_speed = stoi(isoData); - } - } - } - if (mnote->getTag ("LensType")) { - lens = mnote->getTag ("LensType")->valueToString(); - // If MakeNotes are vague, fall back to Exif LensMake and LensModel if set - // https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html#LensType - if (lens == "M-42 or No Lens" || lens == "K or M Lens" || lens == "A Series Lens" || lens == "Sigma") { - lens_from_make_and_model(); - } - } else { - lens_from_make_and_model(); - } - - // Try to get the FocalLength from the LensInfo structure, where length below 10mm will be correctly set - rtexif::Tag* flt = mnote->getTagP ("LensInfo/FocalLength"); - - if (flt) { - // Don't replace Exif focal_len if Makernotes focal_len is 0 - if (flt->toDouble() > 0) { - focal_len = flt->toDouble (); - } - } else if ((flt = mnote->getTagP ("FocalLength"))) { - rtexif::Tag* flt = mnote->getTag ("FocalLength"); - focal_len = flt->toDouble (); - } - - if (mnote->getTag ("FocalLengthIn35mmFilm")) { - focal_len35mm = mnote->getTag ("FocalLengthIn35mmFilm")->toDouble (); - } - } else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) { - if (mnote->getTag ("LensID")) { - lens = mnote->getTag ("LensID")->valueToString (); - if (lens == "Unknown") { - lens_from_make_and_model(); - } - } - } else if (!make.compare (0, 7, "OLYMPUS")) { - if (mnote->getTag ("Equipment")) { - rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory (); - - if (eq->getTag ("LensType")) { - lens = eq->getTag ("LensType")->valueToString (); - } - } - if (lens == "Unknown") { - lens_from_make_and_model(); - } - } else if (mnote && !make.compare (0, 9, "Panasonic")) { - if (mnote->getTag ("LensType")) { - std::string panalens = mnote->getTag("LensType")->valueToString(); - - if (panalens.find("LUMIX") != Glib::ustring::npos) { - lens = "Panasonic " + panalens; - } - else { - lens = panalens; - } - } - } - } else if (exif->getTag ("DNGLensInfo")) { - lens = exif->getTag ("DNGLensInfo")->valueToString (); - } else if (!lens_from_make_and_model() && exif->getTag ("LensInfo")) { - lens = exif->getTag ("LensInfo")->valueToString (); - } - } - } - - rtexif::Tag* t = newFrameRootDir->getTag(0x83BB); - if (t) { - iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); - } - - - // ----------------------- Special file type detection (HDR, PixelShift) ------------------------ - - - uint16 bitspersample = 0, samplesperpixel = 0, sampleformat = 0, photometric = 0, compression = 0; - const rtexif::Tag* const bps = frameRootDir->findTag("BitsPerSample"); - const rtexif::Tag* const spp = frameRootDir->findTag("SamplesPerPixel"); - const rtexif::Tag* const sf = frameRootDir->findTag("SampleFormat"); - const rtexif::Tag* const pi = frameRootDir->findTag("PhotometricInterpretation"); - const rtexif::Tag* const c = frameRootDir->findTag("Compression"); - - if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { - const rtexif::Tag* const hdr = mnote->findTag("HDR"); - if (hdr) { - if (hdr->toInt() > 0) { - isHDR = true; -#if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> \"HDR\" tag found\n"); -#endif - } - } else { - const rtexif::Tag* const dm = mnote->findTag("DriveMode"); - if (dm) { - char buffer[60]; - dm->toString(buffer, 3); - buffer[3] = 0; - if (!strcmp(buffer, "HDR")) { + if ((!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { +// if (find_exif_tag("Exif.Pentax.HDR") && pos->toLong() > 0) { +// isHDR = true; +// #if PRINT_HDR_PS_DETECTION +// printf("HDR detected ! -> \"HDR\" tag found\n"); +// #endif +// } else + if (find_exif_tag("Exif.Pentax.DriveMode")) { + std::string buf = pos->toString(3); + buf[3] = 0; + if (!strcmp(buf.c_str(), "HDR")) { isHDR = true; #if PRINT_HDR_PS_DETECTION printf("HDR detected ! -> DriveMode = \"HDR\"\n"); #endif } } - } - if (!isHDR) { - const rtexif::Tag* const q = mnote->findTag("Quality"); - if (q && (q->toInt() == 7 || q->toInt() == 8)) { + if (!isHDR && find_exif_tag("Exif.Pentax.Quality") && + (pos->toLong() == 7 || pos->toLong() == 8)) { isPixelShift = true; #if PRINT_HDR_PS_DETECTION printf("PixelShift detected ! -> \"Quality\" = 7\n"); #endif } } - } - sampleFormat = IIOSF_UNKNOWN; + sampleFormat = IIOSF_UNKNOWN; - if (!sf) - /* - * WARNING: This is a dirty hack! - * We assume that files which doesn't contain the TIFFTAG_SAMPLEFORMAT tag - * (which is the case with uncompressed TIFFs produced by RT!) are RGB files, - * but that may be not true. --- Hombre - */ - { - sampleformat = SAMPLEFORMAT_UINT; - } else { - sampleformat = sf->toInt(); - } - - if ( - !bps - || !spp - || !pi - ) { - return; - } - - bitspersample = bps->toInt(); - samplesperpixel = spp->toInt(); - - photometric = pi->toInt(); - if (photometric == PHOTOMETRIC_LOGLUV) { - if (!c) { - compression = COMPRESSION_NONE; + if (sf == exif.end()) + /* + * WARNING: This is a dirty hack! + * We assume that files which doesn't contain the TIFFTAG_SAMPLEFORMAT tag + * (which is the case with uncompressed TIFFs produced by RT!) are RGB files, + * but that may be not true. --- Hombre + */ + { + sampleformat = SAMPLEFORMAT_UINT; } else { - compression = c->toInt(); + sampleformat = sf->toLong(); } - } - if (photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_MINISBLACK) { - if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { - if (bitspersample == 8) { - sampleFormat = IIOSF_UNSIGNED_CHAR; - } else if (bitspersample <= 16) { - sampleFormat = IIOSF_UNSIGNED_SHORT; - } - } else if (sampleformat == SAMPLEFORMAT_IEEEFP) { - if (bitspersample==16) { - sampleFormat = IIOSF_FLOAT16; - isHDR = true; -#if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); -#endif - } - else if (bitspersample == 24) { - sampleFormat = IIOSF_FLOAT24; - isHDR = true; -#if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); -#endif - } - else if (bitspersample == 32) { - sampleFormat = IIOSF_FLOAT32; - isHDR = true; -#if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); -#endif + if (bps == exif.end() || spp == exif.end() || pi == exif.end()) { + return; + } + + bitspersample = bps->toLong(); + samplesperpixel = spp->toLong(); + + photometric = pi->toLong(); + if (photometric == PHOTOMETRIC_LOGLUV) { + if (c == exif.end()) { + compression = COMPRESSION_NONE; + } else { + compression = c->toLong(); } } - } else if (photometric == PHOTOMETRIC_CFA) { - if (sampleformat == SAMPLEFORMAT_IEEEFP) { - if (bitspersample == 16) { - sampleFormat = IIOSF_FLOAT16; - isHDR = true; + + if (photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_MINISBLACK) { + if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { + if (bitspersample == 8) { + sampleFormat = IIOSF_UNSIGNED_CHAR; + } else if (bitspersample <= 16) { + sampleFormat = IIOSF_UNSIGNED_SHORT; + } + } else if (sampleformat == SAMPLEFORMAT_IEEEFP) { + if (bitspersample==16) { + sampleFormat = IIOSF_FLOAT16; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); #endif - } - else if (bitspersample == 24) { - sampleFormat = IIOSF_FLOAT24; - isHDR = true; + } + else if (bitspersample == 24) { + sampleFormat = IIOSF_FLOAT24; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); #endif - } - else if (bitspersample == 32) { - sampleFormat = IIOSF_FLOAT32; - isHDR = true; + } + else if (bitspersample == 32) { + sampleFormat = IIOSF_FLOAT32; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); -#endif - } - } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { - if (bitspersample == 8) { // shouldn't occur... - sampleFormat = IIOSF_UNSIGNED_CHAR; - } else if (bitspersample <= 16) { - sampleFormat = IIOSF_UNSIGNED_SHORT; - } - } - } else if (photometric == 34892 || photometric == 32892 /* Linear RAW (see DNG spec ; 32892 seem to be a flaw from Sony's ARQ files) */) { - if (sampleformat == SAMPLEFORMAT_IEEEFP) { - sampleFormat = IIOSF_FLOAT32; - isHDR = true; -#if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); -#endif - } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { - if (bitspersample == 8) { // shouldn't occur... - sampleFormat = IIOSF_UNSIGNED_CHAR; - } else if (bitspersample <= 16) { - sampleFormat = IIOSF_UNSIGNED_SHORT; - if (mnote && (!make.compare (0, 4, "SONY")) && bitspersample >= 12 && samplesperpixel == 4) { - isPixelShift = true; -#if PRINT_HDR_PS_DETECTION - printf("PixelShift detected ! -> \"Make\" = SONY, bitsPerPixel > 8, samplesPerPixel == 4\n"); + printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); #endif } } - } - } else if (photometric == PHOTOMETRIC_LOGLUV) { - if (compression == COMPRESSION_SGILOG24) { - sampleFormat = IIOSF_LOGLUV24; - isHDR = true; + } else if (photometric == PHOTOMETRIC_CFA) { + if (sampleformat == SAMPLEFORMAT_IEEEFP) { + if (bitspersample == 16) { + sampleFormat = IIOSF_FLOAT16; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (16-bit)\n", sampleFormat); #endif - } else if (compression == COMPRESSION_SGILOG) { - sampleFormat = IIOSF_LOGLUV32; - isHDR = true; + } + else if (bitspersample == 24) { + sampleFormat = IIOSF_FLOAT24; + isHDR = true; #if PRINT_HDR_PS_DETECTION - printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); + printf("HDR detected ! -> sampleFormat = %d (24-bit)\n", sampleFormat); #endif + } + else if (bitspersample == 32) { + sampleFormat = IIOSF_FLOAT32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d (32-bit)\n", sampleFormat); +#endif + } + } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { + if (bitspersample == 8) { // shouldn't occur... + sampleFormat = IIOSF_UNSIGNED_CHAR; + } else if (bitspersample <= 16) { + sampleFormat = IIOSF_UNSIGNED_SHORT; + } + } + } else if (photometric == 34892 || photometric == 32892 /* Linear RAW (see DNG spec ; 32892 seem to be a flaw from Sony's ARQ files) */) { + if (sampleformat == SAMPLEFORMAT_IEEEFP) { + sampleFormat = IIOSF_FLOAT32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { + if (bitspersample == 8) { // shouldn't occur... + sampleFormat = IIOSF_UNSIGNED_CHAR; + } else if (bitspersample <= 16) { + sampleFormat = IIOSF_UNSIGNED_SHORT; + if (find_exif_tag("Exif.Photo.MakerNote") && (!make.compare (0, 4, "SONY")) && bitspersample >= 12 && samplesperpixel == 4) { + isPixelShift = true; +#if PRINT_HDR_PS_DETECTION + printf("PixelShift detected ! -> \"Make\" = SONY, bitsPerPixel > 8, samplesPerPixel == 4\n"); +#endif + } + } + } + } else if (photometric == PHOTOMETRIC_LOGLUV) { + if (compression == COMPRESSION_SGILOG24) { + sampleFormat = IIOSF_LOGLUV24; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } else if (compression == COMPRESSION_SGILOG) { + sampleFormat = IIOSF_LOGLUV32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } } - } -} - -FrameData::~FrameData () -{ - - if (iptc) { - iptc_data_free (iptc); - } -} - -procparams::IPTCPairs FrameData::getIPTCData () const -{ - return getIPTCData(iptc); -} - -procparams::IPTCPairs FrameData::getIPTCData (IptcData* iptc_) -{ - - procparams::IPTCPairs iptcc; - - if (!iptc_) { - return iptcc; - } - - unsigned char buffer[2100]; - - for (int i = 0; i < 16; i++) { - IptcDataSet* ds = iptc_data_get_next_dataset (iptc_, nullptr, IPTC_RECORD_APP_2, strTags[i].tag); - - if (ds) { - iptc_dataset_get_data (ds, buffer, 2100); - std::vector icValues; - icValues.push_back (to_utf8((char*)buffer)); - - iptcc[strTags[i].field] = icValues; - iptc_dataset_unref (ds); + } catch(Exiv2::AnyError &e) { + if (settings->verbose) { + std::cerr << "EXIV2 ERROR: " << e.what() << std::endl; } + ok_ = false; } - - IptcDataSet* ds = nullptr; - std::vector keywords; - - while ((ds = iptc_data_get_next_dataset (iptc_, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS))) { - iptc_dataset_get_data (ds, buffer, 2100); - keywords.push_back (to_utf8((char*)buffer)); - } - - iptcc["Keywords"] = keywords; - ds = nullptr; - std::vector suppCategories; - - while ((ds = iptc_data_get_next_dataset (iptc_, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY))) { - iptc_dataset_get_data (ds, buffer, 2100); - suppCategories.push_back (to_utf8((char*)buffer)); - iptc_dataset_unref (ds); - } - - iptcc["SupplementalCategories"] = suppCategories; - return iptcc; } -bool FrameData::getPixelShift () const +bool FramesData::getPixelShift() const { return isPixelShift; } -bool FrameData::getHDR () const + + +bool FramesData::getHDR() const { return isHDR; } -std::string FrameData::getImageType () const + + +std::string FramesData::getImageType() const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } -IIOSampleFormat FrameData::getSampleFormat () const + + +IIOSampleFormat FramesData::getSampleFormat() const { return sampleFormat; } -rtexif::TagDirectory* FrameData::getExifData () const + + +bool FramesData::hasExif() const { - return frameRootDir; + return ok_; } -bool FrameData::hasExif () const -{ - return frameRootDir && frameRootDir->getCount(); -} -bool FrameData::hasIPTC () const -{ - return iptc; -} -tm FrameData::getDateTime () const + + +tm FramesData::getDateTime() const { return time; } -time_t FrameData::getDateTimeAsTS () const + + +time_t FramesData::getDateTimeAsTS() const { return timeStamp; } -int FrameData::getISOSpeed () const + + +int FramesData::getISOSpeed() const { return iso_speed; } -double FrameData::getFNumber () const + + +double FramesData::getFNumber() const { return aperture; } -double FrameData::getFocalLen () const + + +double FramesData::getFocalLen() const { return focal_len; } -double FrameData::getFocalLen35mm () const + + +double FramesData::getFocalLen35mm() const { return focal_len35mm; } -float FrameData::getFocusDist () const + + +float FramesData::getFocusDist() const { return focus_dist; } -double FrameData::getShutterSpeed () const + + +double FramesData::getShutterSpeed() const { return shutter; } -double FrameData::getExpComp () const + + +double FramesData::getExpComp() const { return expcomp; } -std::string FrameData::getMake () const + + +std::string FramesData::getMake() const { return make; } -std::string FrameData::getModel () const + + +std::string FramesData::getModel() const { return model; } -std::string FrameData::getLens () const + + +std::string FramesData::getLens() const { return lens; } -std::string FrameData::getSerialNumber () const + + +std::string FramesData::getSerialNumber() const { return serial; } -std::string FrameData::getOrientation () const + + +std::string FramesData::getOrientation() const { return orientation; } - -void FramesData::setDCRawFrameCount (unsigned int frameCount) +void FramesData::setDCRawFrameCount(unsigned int frameCount) { dcrawFrameCount = frameCount; } -unsigned int FramesData::getRootCount () const +unsigned int FramesData::getFrameCount() const { - return roots.size(); + return dcrawFrameCount ? dcrawFrameCount : 1; } -unsigned int FramesData::getFrameCount () const + +Glib::ustring FramesData::getFileName() const { - return dcrawFrameCount ? dcrawFrameCount : frames.size(); + return fname_; } -bool FramesData::getPixelShift () const -{ - // So far only Pentax and Sony provide multi-frame Pixel Shift files. - // Only the first frame contains the Pixel Shift tag - // If more brand have to be supported, this rule may need - // to evolve - - return frames.empty() ? false : frames.at(0)->getPixelShift (); -} -bool FramesData::getHDR (unsigned int frame) const -{ - // So far only Pentax provides multi-frame HDR file. - // Only the first frame contains the HDR tag - // If more brand have to be supported, this rule may need - // to evolve - - return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getHDR (); -} - -std::string FramesData::getImageType (unsigned int frame) const -{ - return frames.empty() || frame >= frames.size() ? "STD" : frames.at(0)->getImageType(); -} - -IIOSampleFormat FramesData::getSampleFormat (unsigned int frame) const -{ - return frames.empty() || frame >= frames.size() ? IIOSF_UNKNOWN : frames.at(frame)->getSampleFormat (); -} - -rtexif::TagDirectory* FramesData::getFrameExifData (unsigned int frame) const -{ - return frames.empty() || frame >= frames.size() ? nullptr : frames.at(frame)->getExifData (); -} - -rtexif::TagDirectory* FramesData::getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const -{ - rtexif::TagDirectory *td = nullptr; - if (frames.empty()) { - return nullptr; - } - if (imgSource && rawParams) { - eSensorType sensorType = imgSource->getSensorType(); - unsigned int imgNum = 0; - if (sensorType == ST_BAYER) { - imgNum = rtengine::LIM(rawParams->bayersensor.imageNum, 0, frames.size() - 1); - /* - // might exist someday ? - } else if (sensorType == ST_FUJI_XTRANS) { - imgNum = rtengine::LIM(rawParams->xtranssensor.imageNum, 0, frames.size() - 1); - } else if (sensorType == ST_NONE && !imgSource->isRAW()) { - // standard image multiframe support should come here (when implemented in GUI) - */ - } - - td = getFrameExifData (imgNum); - rtexif::Tag* makeTag; - if (td && (makeTag = td->findTag("Make", true))) { - td = makeTag->getParent(); - } else { - td = getRootExifData(0); - } - } - return td; -} - -rtexif::TagDirectory* FramesData::getRootExifData (unsigned int root) const -{ - return roots.empty() || root >= roots.size() ? nullptr : roots.at(root); -} - -procparams::IPTCPairs FramesData::getIPTCData (unsigned int frame) const -{ - if (frame < frames.size() && frames.at(frame)->hasIPTC()) { - return frames.at(frame)->getIPTCData(); - } else { - if (iptc) { - return FrameData::getIPTCData(iptc); - } else { - procparams::IPTCPairs emptyPairs; - return emptyPairs; - } - } -} - -bool FramesData::hasExif(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.hasExif(); - } - ); -} - -bool FramesData::hasIPTC(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.hasIPTC(); - } - ); -} - -tm FramesData::getDateTime(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getDateTime(); - } - ); -} - -time_t FramesData::getDateTimeAsTS(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getDateTimeAsTS(); - } - ); -} - -int FramesData::getISOSpeed(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getISOSpeed(); - } - ); -} - -double FramesData::getFNumber(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getFNumber(); - } - ); -} - -double FramesData::getFocalLen(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getFocalLen(); - } - ); -} - -double FramesData::getFocalLen35mm(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getFocalLen35mm(); - } - ); -} - -float FramesData::getFocusDist(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getFocusDist(); - } - ); -} - -double FramesData::getShutterSpeed(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getShutterSpeed(); - } - ); -} - -double FramesData::getExpComp(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getExpComp(); - } - ); -} - -std::string FramesData::getMake(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getMake(); - } - ); -} - -std::string FramesData::getModel(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getModel(); - } - ); -} - -std::string FramesData::getLens(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getLens(); - } - ); -} - -std::string FramesData::getSerialNumber(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getSerialNumber(); - } - ); -} - -std::string FramesData::getOrientation(unsigned int frame) const -{ - return getFromFrame( - frames, - frame, - [](const FrameData& frame_data) - { - return frame_data.getOrientation(); - } - ); -} - - //------inherited functions--------------// -std::string FramesMetaData::apertureToString (double aperture) +std::string FramesMetaData::apertureToString(double aperture) { char buffer[256]; @@ -1181,7 +584,7 @@ std::string FramesMetaData::apertureToString (double aperture) return buffer; } -std::string FramesMetaData::shutterToString (double shutter) +std::string FramesMetaData::shutterToString(double shutter) { char buffer[256]; @@ -1195,7 +598,7 @@ std::string FramesMetaData::shutterToString (double shutter) return buffer; } -std::string FramesMetaData::expcompToString (double expcomp, bool maskZeroexpcomp) +std::string FramesMetaData::expcompToString(double expcomp, bool maskZeroexpcomp) { char buffer[256]; @@ -1213,9 +616,8 @@ std::string FramesMetaData::expcompToString (double expcomp, bool maskZeroexpcom } } -double FramesMetaData::shutterFromString (std::string s) +double FramesMetaData::shutterFromString(std::string s) { - size_t i = s.find_first_of ('/'); if (i == std::string::npos) { @@ -1225,158 +627,9 @@ double FramesMetaData::shutterFromString (std::string s) } } -double FramesMetaData::apertureFromString (std::string s) +double FramesMetaData::apertureFromString(std::string s) { - return atof (s.c_str()); + return atof(s.c_str()); } -extern "C" { - -#include -#include - - struct _IptcDataPrivate { - unsigned int ref_count; - - IptcLog *log; - IptcMem *mem; - }; - - IptcData * - iptc_data_new_from_jpeg_file (FILE *infile) - { - IptcData *d; - unsigned char * buf; - int buf_len = 256 * 256; - int len, offset; - unsigned int iptc_len; - - if (!infile) { - return nullptr; - } - - d = iptc_data_new (); - - if (!d) { - return nullptr; - } - - buf = (unsigned char*)iptc_mem_alloc (d->priv->mem, buf_len); - - if (!buf) { - iptc_data_unref (d); - return nullptr; - } - - len = iptc_jpeg_read_ps3 (infile, buf, buf_len); - - if (len <= 0) { - goto failure; - } - - offset = iptc_jpeg_ps3_find_iptc (buf, len, &iptc_len); - - if (offset <= 0) { - goto failure; - } - - iptc_data_load (d, buf + offset, iptc_len); - - iptc_mem_free (d->priv->mem, buf); - return d; - -failure: - iptc_mem_free (d->priv->mem, buf); - iptc_data_unref (d); - return nullptr; - } - -} - -FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) : - iptc(nullptr), dcrawFrameCount (0) -{ - if (rml && (rml->exifBase >= 0 || rml->ciffBase >= 0)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - rtexif::ExifManager exifManager (f, std::move(rml), firstFrameOnly); - if (exifManager.f && exifManager.rml) { - if (exifManager.rml->exifBase >= 0) { - exifManager.parseRaw (); - } else if (exifManager.rml->ciffBase >= 0) { - exifManager.parseCIFF (); - } - } - - // copying roots - roots = exifManager.roots; - - // creating FrameData - for (auto currFrame : exifManager.frames) { - frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); - } - for (auto currRoot : roots) { - rtexif::Tag* t = currRoot->getTag(0x83BB); - - if (t && !iptc) { - iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); - break; - } - } - - fclose (f); - } - } else if (hasJpegExtension(fname)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - rtexif::ExifManager exifManager (f, std::move(rml), true); - if (exifManager.f) { - exifManager.parseJPEG (); - roots = exifManager.roots; - for (auto currFrame : exifManager.frames) { - frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); - } - rewind (exifManager.f); // Not sure this is necessary - iptc = iptc_data_new_from_jpeg_file (exifManager.f); - } - fclose (f); - } - } else if (hasTiffExtension(fname)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - rtexif::ExifManager exifManager (f, std::move(rml), firstFrameOnly); - - exifManager.parseTIFF(); - roots = exifManager.roots; - - // creating FrameData - for (auto currFrame : exifManager.frames) { - frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); - } - for (auto currRoot : roots) { - rtexif::Tag* t = currRoot->getTag(0x83BB); - - if (t && !iptc) { - iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); - break; - } - } - fclose (f); - } - } -} - -FramesData::~FramesData () -{ - for (auto currRoot : roots) { - delete currRoot; - } - - if (iptc) { - iptc_data_free (iptc); - } -} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index c6889e653..6f2147277 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -24,20 +24,20 @@ #include "rawimage.h" #include #include -#include "../rtexif/rtexif.h" -#include +#include #include "rtengine.h" namespace rtengine { -class FrameData -{ +Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname); -protected: - rtexif::TagDirectory* frameRootDir; - IptcData* iptc; +class FramesData : public FramesMetaData { +private: + bool ok_; + Glib::ustring fname_; + unsigned int dcrawFrameCount; struct tm time; time_t timeStamp; int iso_speed; @@ -50,82 +50,34 @@ protected: std::string orientation; std::string lens; IIOSampleFormat sampleFormat; - - // each frame has the knowledge of "being an" - // or "being part of an" HDR or PS image bool isPixelShift; bool isHDR; - + public: + FramesData (const Glib::ustring& fname); - FrameData (rtexif::TagDirectory* frameRootDir, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir); - virtual ~FrameData (); - - bool getPixelShift () const; - bool getHDR () const; - std::string getImageType () const; - IIOSampleFormat getSampleFormat () const; - rtexif::TagDirectory* getExifData () const; - procparams::IPTCPairs getIPTCData () const; - static procparams::IPTCPairs getIPTCData (IptcData* iptc_); - bool hasExif () const; - bool hasIPTC () const; - tm getDateTime () const; - time_t getDateTimeAsTS () const; - int getISOSpeed () const; - double getFNumber () const; - double getFocalLen () const; - double getFocalLen35mm () const; - float getFocusDist () const; - double getShutterSpeed () const; - double getExpComp () const; - std::string getMake () const; - std::string getModel () const; - std::string getLens () const; - std::string getSerialNumber () const; - std::string getOrientation () const; -}; - -class FramesData : public FramesMetaData { -private: - // frame's root IFD, can be a file root IFD or a SUB-IFD - std::vector> frames; - // root IFD in the file - std::vector roots; - IptcData* iptc; - unsigned int dcrawFrameCount; - -public: - FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); - ~FramesData () override; - - void setDCRawFrameCount (unsigned int frameCount); - unsigned int getRootCount () const override; - unsigned int getFrameCount () const override; - bool getPixelShift () const override; - bool getHDR (unsigned int frame = 0) const override; - std::string getImageType (unsigned int frame) const override; - IIOSampleFormat getSampleFormat (unsigned int frame = 0) const override; - rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const override; - rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const override; - rtexif::TagDirectory* getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const override; - procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const override; - bool hasExif (unsigned int frame = 0) const override; - bool hasIPTC (unsigned int frame = 0) const override; - tm getDateTime (unsigned int frame = 0) const override; - time_t getDateTimeAsTS (unsigned int frame = 0) const override; - int getISOSpeed (unsigned int frame = 0) const override; - double getFNumber (unsigned int frame = 0) const override; - double getFocalLen (unsigned int frame = 0) const override; - double getFocalLen35mm (unsigned int frame = 0) const override; - float getFocusDist (unsigned int frame = 0) const override; - double getShutterSpeed (unsigned int frame = 0) const override; - double getExpComp (unsigned int frame = 0) const override; - std::string getMake (unsigned int frame = 0) const override; - std::string getModel (unsigned int frame = 0) const override; - std::string getLens (unsigned int frame = 0) const override; - std::string getSerialNumber (unsigned int frame = 0) const; - std::string getOrientation (unsigned int frame = 0) const override; + void setDCRawFrameCount(unsigned int frameCount); + unsigned int getFrameCount() const override; + bool getPixelShift() const override; + bool getHDR() const override; + std::string getImageType() const override; + IIOSampleFormat getSampleFormat() const override; + bool hasExif() const override; + tm getDateTime() const override; + time_t getDateTimeAsTS() const override; + int getISOSpeed() const override; + double getFNumber() const override; + double getFocalLen() const override; + double getFocalLen35mm() const override; + float getFocusDist() const override; + double getShutterSpeed() const override; + double getExpComp() const override; + std::string getMake() const override; + std::string getModel() const override; + std::string getLens() const override; + std::string getSerialNumber() const; + std::string getOrientation() const override; + Glib::ustring getFileName() const override; }; diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index f1fa8dbef..f7d95b2df 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -24,7 +24,6 @@ #include #include #include -#include #include "rt_math.h" #include "procparams.h" #include "../rtgui/options.h" @@ -37,9 +36,10 @@ #endif #include "imageio.h" -#include "iptcpairs.h" +//#include "iptcpairs.h" #include "iccjpeg.h" #include "color.h" +#include "imagedata.h" #include "jpeg.h" @@ -80,97 +80,6 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."}; -// For only copying the raw input data -void ImageIO::setMetadata (const rtexif::TagDirectory* eroot) -{ - if (exifRoot != nullptr) { - delete exifRoot; - exifRoot = nullptr; - } - - if (eroot) { - rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (nullptr); - - // make IPTC and XMP pass through - td->keepTag(0x83bb); // IPTC - td->keepTag(0x02bc); // XMP - - exifRoot = td; - } -} - -// For merging with RT specific data -void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc) -{ - - // store exif info - exifChange->clear(); - *exifChange = exif; - - if (exifRoot != nullptr) { - delete exifRoot; - exifRoot = nullptr; - } - - if (eroot) { - exifRoot = ((rtexif::TagDirectory*)eroot)->clone (nullptr); - } - - if (iptc != nullptr) { - iptc_data_free (iptc); - iptc = nullptr; - } - - // build iptc structures for libiptcdata - if (iptcc.empty()) { - return; - } - - iptc = iptc_data_new (); - - const unsigned char utf8Esc[] = {0x1B, '%', 'G'}; - IptcDataSet * ds = iptc_dataset_new (); - iptc_dataset_set_tag (ds, IPTC_RECORD_OBJECT_ENV, IPTC_TAG_CHARACTER_SET); - iptc_dataset_set_data (ds, utf8Esc, 3, IPTC_DONT_VALIDATE); - iptc_data_add_dataset (iptc, ds); - iptc_dataset_unref (ds); - - for (rtengine::procparams::IPTCPairs::const_iterator i = iptcc.begin(); i != iptcc.end(); ++i) { - if (i->first == "Keywords" && !(i->second.empty())) { - for (unsigned int j = 0; j < i->second.size(); j++) { - IptcDataSet * ds = iptc_dataset_new (); - iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(64), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); - iptc_data_add_dataset (iptc, ds); - iptc_dataset_unref (ds); - } - - continue; - } else if (i->first == "SupplementalCategories" && !(i->second.empty())) { - for (unsigned int j = 0; j < i->second.size(); j++) { - IptcDataSet * ds = iptc_dataset_new (); - iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(32), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); - iptc_data_add_dataset (iptc, ds); - iptc_dataset_unref (ds); - } - - continue; - } - - for (int j = 0; j < 16; j++) - if (i->first == strTags[j].field && !(i->second.empty())) { - IptcDataSet * ds = iptc_dataset_new (); - iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(0).c_str(), min(strTags[j].size, i->second.at(0).bytes()), IPTC_DONT_VALIDATE); - iptc_data_add_dataset (iptc, ds); - iptc_dataset_unref (ds); - } - } - - iptc_data_sort (iptc); -} - void ImageIO::setOutputProfile (const char* pdata, int plen) { @@ -194,9 +103,6 @@ ImageIO::ImageIO() : loadedProfileData(nullptr), loadedProfileDataJpg(false), loadedProfileLength(0), - exifChange(new procparams::ExifPairs), - iptc(nullptr), - exifRoot(nullptr), sampleFormat(IIOSF_UNKNOWN), sampleArrangement(IIOSA_UNKNOWN) { @@ -210,7 +116,7 @@ ImageIO::~ImageIO () } deleteLoadedProfileData(); - delete exifRoot; + // delete exifRoot; delete [] profileData; } @@ -919,76 +825,6 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s } -namespace { - -// Taken from Darktable -- src/imageio/format/png.c -// -/* Write EXIF data to PNG file. - * Code copied from DigiKam's libs/dimg/loaders/pngloader.cpp. - * The EXIF embedding is defined by ImageMagicK. - * It is documented in the ExifTool page: - * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html - * - * ..and in turn copied from ufraw. thanks to udi and colleagues - * for making useful code much more readable and discoverable ;) - */ - -void PNGwriteRawProfile(png_struct *ping, png_info *ping_info, const char *profile_type, guint8 *profile_data, png_uint_32 length) -{ - png_textp text; - long i; - guint8 *sp; - png_charp dp; - png_uint_32 allocated_length, description_length; - - const guint8 hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - text = static_cast(png_malloc(ping, sizeof(png_text))); - description_length = strlen(profile_type); - allocated_length = length * 2 + (length >> 5) + 20 + description_length; - - text[0].text = static_cast(png_malloc(ping, allocated_length)); - text[0].key = static_cast(png_malloc(ping, 80)); - text[0].key[0] = '\0'; - - g_strlcat(text[0].key, "Raw profile type ", 80); - g_strlcat(text[0].key, profile_type, 80); - - sp = profile_data; - dp = text[0].text; - *dp++ = '\n'; - - g_strlcpy(dp, profile_type, allocated_length); - - dp += description_length; - *dp++ = '\n'; - *dp = '\0'; - - g_snprintf(dp, allocated_length - strlen(text[0].text), "%8lu ", static_cast(length)); - - dp += 8; - - for(i = 0; i < long(length); i++) - { - if(i % 36 == 0) *dp++ = '\n'; - - *(dp++) = hex[((*sp >> 4) & 0x0f)]; - *(dp++) = hex[((*sp++) & 0x0f)]; - } - - *dp++ = '\n'; - *dp = '\0'; - text[0].text_length = (dp - text[0].text); - text[0].compression = -1; - - if(text[0].text_length <= allocated_length) png_set_text(ping, ping_info, text, 1); - - png_free(ping, text[0].text); - png_free(ping, text[0].key); - png_free(ping, text); -} - -} // namespace - int ImageIO::savePNG (const Glib::ustring &fname, int bps) const { if (getWidth() < 1 || getHeight() < 1) { @@ -1060,30 +896,6 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const png_set_iCCP(png, info, const_cast("icc"), 0, profdata, profileLength); } - { - // buffer for the exif and iptc - unsigned int bufferSize; - unsigned char* buffer = nullptr; // buffer will be allocated in createTIFFHeader - unsigned char* iptcdata = nullptr; - unsigned int iptclen = 0; - - if (iptc && iptc_data_save (iptc, &iptcdata, &iptclen) && iptcdata) { - iptc_data_free_buf (iptc, iptcdata); - iptcdata = nullptr; - } - - int size = rtexif::ExifManager::createPNGMarker(exifRoot, *exifChange, width, height, bps, (char*)iptcdata, iptclen, buffer, bufferSize); - - if (iptcdata) { - iptc_data_free_buf (iptc, iptcdata); - } - if (buffer && size) { - PNGwriteRawProfile(png, info, "exif", buffer, size); - delete[] buffer; - } - } - - int rowlen = width * 3 * bps / 8; unsigned char *row = new unsigned char [rowlen]; @@ -1117,6 +929,11 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const delete [] row; fclose (file); + if (!saveMetadata(fname)) { + g_remove(fname.c_str()); + return IMIO_CANNOTWRITEFILE; + } + if (pl) { pl->setProgressStr ("PROGRESSBAR_READY"); pl->setProgress (1.0); @@ -1216,49 +1033,6 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con jpeg_start_compress(&cinfo, TRUE); - // buffer for exif and iptc markers - unsigned char* buffer = new unsigned char[165535]; //FIXME: no buffer size check so it can be overflowed in createJPEGMarker() for large tags, and then software will crash - unsigned int size; - - // assemble and write exif marker - if (exifRoot) { - int size = rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer); - - if (size > 0 && size < 65530) { - jpeg_write_marker(&cinfo, JPEG_APP0 + 1, buffer, size); - } - } - - // assemble and write iptc marker - if (iptc) { - unsigned char* iptcdata; - bool error = false; - - if (iptc_data_save (iptc, &iptcdata, &size)) { - if (iptcdata) { - iptc_data_free_buf (iptc, iptcdata); - } - - error = true; - } - - int bytes = 0; - - if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, size, buffer, 65532)) < 0) { - error = true; - } - - if (iptcdata) { - iptc_data_free_buf (iptc, iptcdata); - } - - if (!error) { - jpeg_write_marker(&cinfo, JPEG_APP0 + 13, buffer, bytes); - } - } - - delete [] buffer; - // write icc profile to the output if (profileData) { write_icc_profile (&cinfo, (JOCTET*)profileData, profileLength); @@ -1310,6 +1084,11 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con fclose (file); + if (!saveMetadata(fname)) { + g_remove(fname.c_str()); + return IMIO_CANNOTWRITEFILE; + } + if (pl) { pl->setProgressStr ("PROGRESSBAR_READY"); pl->setProgress (1.0); @@ -1336,7 +1115,7 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u unsigned char* linebuffer = new unsigned char[lineWidth]; // little hack to get libTiff to use proper byte order (see TIFFClienOpen()): - const char *mode = !exifRoot ? "w" : (exifRoot->getOrder() == rtexif::INTEL ? "wl" : "wb"); + const char *mode = "w"; #ifdef WIN32 FILE *file = g_fopen_withBinaryAndLock (fname); int fileno = _fileno(file); @@ -1344,7 +1123,7 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode); #else TIFF* out = TIFFOpen(fname.c_str(), mode); - int fileno = TIFFFileno (out); + // int fileno = TIFFFileno (out); #endif if (!out) { @@ -1357,113 +1136,7 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u pl->setProgress (0.0); } - bool applyExifPatch = false; - - if (exifRoot) { - rtexif::TagDirectory* cl = (const_cast (exifRoot))->clone (nullptr); - - // ------------------ remove some unknown top level tags which produce warnings when opening a tiff (might be useless) ----------------- - - rtexif::Tag *removeTag = cl->getTag (0x9003); - - if (removeTag) { - removeTag->setKeep (false); - } - - removeTag = cl->getTag (0x9211); - - if (removeTag) { - removeTag->setKeep (false); - } - - // ------------------ Apply list of change ----------------- - - for (auto currExifChange : *exifChange) { - cl->applyChange (currExifChange.first, currExifChange.second); - } - - rtexif::Tag *tag = cl->getTag (TIFFTAG_EXIFIFD); - - if (tag && tag->isDirectory()) { - rtexif::TagDirectory *exif = tag->getDirectory(); - - if (exif) { - int exif_size = exif->calculateSize(); - unsigned char *buffer = new unsigned char[exif_size + 8]; - // TIFFOpen writes out the header and sets file pointer at position 8 - - exif->write (8, buffer); - - write (fileno, buffer + 8, exif_size); - - delete [] buffer; - // let libtiff know that scanlines or any other following stuff should go - // at a different offset: - TIFFSetWriteOffset (out, exif_size + 8); - TIFFSetField (out, TIFFTAG_EXIFIFD, 8); - applyExifPatch = true; - } - } - - //TODO Even though we are saving EXIF IFD - MakerNote still comes out screwed. - - if ((tag = cl->getTag (TIFFTAG_MODEL)) != nullptr) { - TIFFSetField (out, TIFFTAG_MODEL, tag->getValue()); - } - - if ((tag = cl->getTag (TIFFTAG_MAKE)) != nullptr) { - TIFFSetField (out, TIFFTAG_MAKE, tag->getValue()); - } - - if ((tag = cl->getTag (TIFFTAG_DATETIME)) != nullptr) { - TIFFSetField (out, TIFFTAG_DATETIME, tag->getValue()); - } - - if ((tag = cl->getTag (TIFFTAG_ARTIST)) != nullptr) { - TIFFSetField (out, TIFFTAG_ARTIST, tag->getValue()); - } - - if ((tag = cl->getTag (TIFFTAG_COPYRIGHT)) != nullptr) { - TIFFSetField (out, TIFFTAG_COPYRIGHT, tag->getValue()); - } - - delete cl; - } - - unsigned char* iptcdata = nullptr; - unsigned int iptclen = 0; - - if (iptc && iptc_data_save (iptc, &iptcdata, &iptclen)) { - if (iptcdata) { - iptc_data_free_buf (iptc, iptcdata); - iptcdata = nullptr; - } - } - -#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::MOTOROLA; -#else - bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::INTEL; -#endif - if (iptcdata) { - rtexif::Tag iptcTag(nullptr, rtexif::lookupAttrib (rtexif::ifdAttribs, "IPTCData")); - iptcTag.initLongArray((char*)iptcdata, iptclen); - if (needsReverse) { - unsigned char *ptr = iptcTag.getValue(); - for (int a = 0; a < iptcTag.getCount(); ++a) { - unsigned char cc; - cc = ptr[3]; - ptr[3] = ptr[0]; - ptr[0] = cc; - cc = ptr[2]; - ptr[2] = ptr[1]; - ptr[1] = cc; - ptr += 4; - } - } - TIFFSetField (out, TIFFTAG_RICHTIFFIPTC, iptcTag.getCount(), (long*)iptcTag.getValue()); - iptc_data_free_buf (iptc, iptcdata); - } + bool needsReverse = false; TIFFSetField (out, TIFFTAG_SOFTWARE, "RawTherapee " RTVERSION); TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width); @@ -1523,38 +1196,6 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u writeOk = false; } - /************************************************************************************************************ - * - * Hombre: This is a dirty hack to update the Exif tag data type to 0x0004 so that Windows can understand it. - * libtiff will set this data type to 0x000d and doesn't provide any mechanism to update it before - * dumping to the file. - * - */ - if (applyExifPatch) { - unsigned char b[10]; - uint16 tagCount = 0; - lseek(fileno, 4, SEEK_SET); - read(fileno, b, 4); - uint32 ifd0Offset = rtexif::sget4(b, exifRoot->getOrder()); - lseek(fileno, ifd0Offset, SEEK_SET); - read(fileno, b, 2); - tagCount = rtexif::sget2(b, exifRoot->getOrder()); - for (size_t i = 0; i < tagCount ; ++i) { - uint16 tagID = 0; - read(fileno, b, 2); - tagID = rtexif::sget2(b, exifRoot->getOrder()); - if (tagID == 0x8769) { - rtexif::sset2(4, b, exifRoot->getOrder()); - write(fileno, b, 2); - break; - } else { - read(fileno, b, 10); - } - } - } - /************************************************************************************************************/ - - TIFFClose (out); #ifdef WIN32 fclose (file); @@ -1562,6 +1203,10 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u delete [] linebuffer; + if (!saveMetadata(fname)) { + writeOk = false; + } + if (pl) { pl->setProgressStr ("PROGRESSBAR_READY"); pl->setProgress (1.0); @@ -1692,3 +1337,42 @@ void ImageIO::deleteLoadedProfileData( ) loadedProfileData = nullptr; } + + +bool ImageIO::saveMetadata(const Glib::ustring &fname) const +{ + if (metadataInfo.filename().empty()) { + return true; + } + + try { + auto src = open_exiv2(metadataInfo.filename()); + auto dst = open_exiv2(fname); + src->readMetadata(); + dst->setMetadata(*src); + dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; + for (auto &p : metadataInfo.exif()) { + try { + dst->exifData()[p.first] = p.second; + } catch (Exiv2::AnyError &exc) {} + } + for (auto &p : metadataInfo.iptc()) { + try { + auto &v = p.second; + if (v.size() >= 1) { + dst->iptcData()[p.first] = v[0]; + for (size_t j = 1; j < v.size(); ++j) { + Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); + d.setValue(v[j]); + dst->iptcData().add(d); + } + } + } catch (Exiv2::AnyError &exc) {} + } + dst->writeMetadata(); + return true; + } catch (Exiv2::AnyError &exc) { + std::cout << "EXIF ERROR: " << exc.what() << std::endl; + return false; + } +} diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 05a11655a..0bdb7d43a 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -31,13 +31,12 @@ #include #include -#include #include "rtengine.h" #include "imageformat.h" -#include "../rtexif/rtexif.h" #include "imagedimensions.h" #include "iimage.h" #include "colortemp.h" +#include "procparams.h" namespace rtengine { @@ -45,6 +44,24 @@ namespace rtengine class ProgressListener; class Imagefloat; +class MetadataInfo { +public: + explicit MetadataInfo(const Glib::ustring &src=Glib::ustring()): + src_(src) {} + + const Glib::ustring &filename() const { return src_; } + + const rtengine::procparams::ExifPairs &exif() const { return exif_; } + const rtengine::procparams::IPTCPairs &iptc() const { return iptc_; } + void setExif(const rtengine::procparams::ExifPairs &exif) { exif_ = exif; } + void setIptc(const rtengine::procparams::IPTCPairs &iptc) { iptc_ = iptc; } + +private: + Glib::ustring src_; + rtengine::procparams::ExifPairs exif_; + rtengine::procparams::IPTCPairs iptc_; +}; + class ImageIO : virtual public ImageDatas { @@ -56,12 +73,10 @@ protected: char* loadedProfileData; bool loadedProfileDataJpg; int loadedProfileLength; - const std::unique_ptr exifChange; - IptcData* iptc; - const rtexif::TagDirectory* exifRoot; MyMutex imutex; IIOSampleFormat sampleFormat; IIOSampleArrangement sampleArrangement; + MetadataInfo metadataInfo; private: void deleteLoadedProfileData( ); @@ -103,10 +118,11 @@ public: cmsHPROFILE getEmbeddedProfile () const; void getEmbeddedProfileData (int& length, unsigned char*& pdata) const; - void setMetadata (const rtexif::TagDirectory* eroot); - void setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc); + void setMetadata(const MetadataInfo &info) { metadataInfo = info; } void setOutputProfile (const char* pdata, int plen); + bool saveMetadata(const Glib::ustring &fname) const; + MyMutex& mutex (); }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ec047f853..079c5cb48 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -876,20 +876,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) customColCurve1, customColCurve2, customColCurve3, 1); const FramesMetaData* metaData = imgsrc->getMetaData(); - int imgNum = 0; - - if (imgsrc->isRAW()) { - if (imgsrc->getSensorType() == ST_BAYER) { - imgNum = rtengine::LIM(params->raw.bayersensor.imageNum, 0, metaData->getFrameCount() - 1); - } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { - //imgNum = rtengine::LIM(params->raw.xtranssensor.imageNum, 0, metaData->getFrameCount() - 1); - } - } - - float fnum = metaData->getFNumber(imgNum); // F number - float fiso = metaData->getISOSpeed(imgNum) ; // ISO - float fspeed = metaData->getShutterSpeed(imgNum) ; // Speed - double fcomp = metaData->getExpComp(imgNum); // Compensation +/- + float fnum = metaData->getFNumber(); // F number + float fiso = metaData->getISOSpeed() ; // ISO + float fspeed = metaData->getShutterSpeed() ; // Speed + double fcomp = metaData->getExpComp(); // Compensation +/- double adap; if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong @@ -1413,7 +1403,8 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a im = tempImage; } - im->setMetadata(imgsrc->getMetaData()->getRootExifData()); + // im->setMetadata(imgsrc->getMetaData()->getRootExifData()); + im->setMetadata(MetadataInfo(imgsrc->getFileName())); im->saveTIFF(fname, 16, false, true); delete im; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index d215833d3..8dd57e74d 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5656,18 +5656,17 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_size) { if (fname != "") { - rtengine::RawMetaDataLocation ri; int w_raw = -1, h_raw = thumb_size; int w_thumb = -1, h_thumb = thumb_size; eSensorType sensorType = rtengine::ST_NONE; - Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, w_thumb, h_thumb, 1, FALSE); + Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, w_thumb, h_thumb, 1, FALSE); if (!thumb) { return 0.0; } - Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, w_raw, h_raw, 1, 1.0, FALSE); + Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, sensorType, w_raw, h_raw, 1, 1.0, FALSE); if (!raw) { delete thumb; diff --git a/rtengine/iptcpairs.h b/rtengine/iptcpairs.h deleted file mode 100644 index e0b34180f..000000000 --- a/rtengine/iptcpairs.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _IPTCPAIRS_ -#define _IPTCPAIRS_ - - -struct IptcPair { - IptcTag tag; - size_t size; - Glib::ustring field; -}; - -const IptcPair strTags[] = { - {IPTC_TAG_CAPTION, 2000, "Caption"}, - {IPTC_TAG_WRITER_EDITOR, 32, "CaptionWriter"}, - {IPTC_TAG_HEADLINE, 256, "Headline"}, - {IPTC_TAG_SPECIAL_INSTRUCTIONS, 256, "Instructions"}, - {IPTC_TAG_CATEGORY, 3, "Category"}, - {IPTC_TAG_BYLINE, 32, "Creator"}, - {IPTC_TAG_BYLINE_TITLE, 32, "CreatorJobTitle"}, - {IPTC_TAG_CREDIT, 32, "Credit"}, - {IPTC_TAG_SOURCE, 32, "Source"}, - {IPTC_TAG_COPYRIGHT_NOTICE, 128, "Copyright"}, - {IPTC_TAG_CITY, 32, "City"}, - {IPTC_TAG_STATE, 32, "Province"}, - {IPTC_TAG_COUNTRY_NAME, 64, "Country"}, - {IPTC_TAG_OBJECT_NAME, 64, "Title"}, - {IPTC_TAG_ORIG_TRANS_REF, 32, "TransReference"}, - {IPTC_TAG_DATE_CREATED, 8, "DateCreated"} -}; - -#endif - diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index e62a1adea..944e2e0ce 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -60,9 +60,8 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext data = tpp->getImage8Data(); } } else { - rtengine::RawMetaDataLocation ri; eSensorType sensorType = rtengine::ST_NONE; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, width, height, 1, true, true); + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, width, height, 1, true, true); if (tpp) { data = tpp->getImage8Data(); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 6d914bb27..f9daead22 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -295,7 +295,36 @@ bool saveToKeyfile( return false; } -} + +const std::map exif_keys = { + {"Copyright", "Exif.Image.Copyright"}, + {"Artist", "Exif.Image.Artist"}, + {"ImageDescription", "Exif.Image.ImageDescription"}, + {"Exif.UserComment", "Exif.Photo.UserComment"} +}; + +const std::map iptc_keys = { + {"Title", "Iptc.Application2.ObjectName"}, + {"Category", "Iptc.Application2.Category"}, + {"SupplementalCategories", "Iptc.Application2.SuppCategory"}, + {"Keywords", "Iptc.Application2.Keywords"}, + {"Instructions", "Iptc.Application2.SpecialInstructions"}, + {"DateCreated", "Iptc.Application2.DateCreated"}, + {"Creator", "Iptc.Application2.Byline"}, + {"CreatorJobTitle", "Iptc.Application2.BylineTitle"}, + {"City", "Iptc.Application2.City"}, + {"Province", "Iptc.Application2.ProvinceState"}, + {"Country", "Iptc.Application2.CountryName"}, + {"TransReference", "Iptc.Application2.TransmissionReference"}, + {"Headline", "Iptc.Application2.Headline"}, + {"Credit", "Iptc.Application2.Credit"}, + {"Source", "Iptc.Application2.Source"}, + {"Copyright", "Iptc.Application2.Copyright"}, + {"Caption", "Iptc.Application2.Caption"}, + {"CaptionWriter", "Iptc.Application2.Writer"} +}; + +} // namespace namespace rtengine { @@ -3568,16 +3597,30 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // EXIF change list if (!pedited || pedited->exif) { + std::map m; + for (auto &p : exif_keys) { + m[p.second] = p.first; + } for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { - keyFile.set_string("Exif", i->first, i->second); + auto it = m.find(i->first); + if (it != m.end()) { + keyFile.set_string("Exif", it->second, i->second); + } } } // IPTC change list if (!pedited || pedited->iptc) { + std::map m; + for (auto &p : iptc_keys) { + m[p.second] = p.first; + } for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); ++i) { - Glib::ArrayHandle values = i->second; - keyFile.set_string_list("IPTC", i->first, values); + auto it = m.find(i->first); + if (it != m.end()) { + Glib::ArrayHandle values = i->second; + keyFile.set_string_list("IPTC", it->second, values); + } } } @@ -5120,10 +5163,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("Exif")) { for (const auto& key : keyFile.get_keys("Exif")) { - exif[key] = keyFile.get_string("Exif", key); + auto it = exif_keys.find(key); + if (it != exif_keys.end()) { + exif[it->second] = keyFile.get_string("Exif", key); - if (pedited) { - pedited->exif = true; + if (pedited) { + pedited->exif = true; + } } } } @@ -5143,7 +5189,12 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("IPTC")) { for (const auto& key : keyFile.get_keys("IPTC")) { // does this key already exist? - const IPTCPairs::iterator element = iptc.find(key); + auto it = iptc_keys.find(key); + if (it == iptc_keys.end()) { + continue; + } + auto kk = it->second; + const IPTCPairs::iterator element = iptc.find(kk); if (element != iptc.end()) { // it already exist so we cleanup the values @@ -5152,7 +5203,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) // TODO: look out if merging Keywords and SupplementalCategories from the procparams chain would be interesting for (const auto& currLoadedTagValue : keyFile.get_string_list("IPTC", key)) { - iptc[key].push_back(currLoadedTagValue); + iptc[kk].push_back(currLoadedTagValue); } if (pedited) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0982fda48..951b02b1a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1075,90 +1075,8 @@ struct MetaDataParams { }; -/** - * Minimal wrapper allowing forward declaration for representing a key/value for the exif metadata information - */ -class ExifPairs final -{ -public: - using const_iterator = std::map::const_iterator; - - const_iterator begin() const - { - return pairs.begin(); - } - - const_iterator end() const - { - return pairs.end(); - } - - void clear() - { - pairs.clear(); - } - - Glib::ustring& operator[](const Glib::ustring& key) - { - return pairs[key]; - } - - bool operator ==(const ExifPairs& other) const - { - return pairs == other.pairs; - } - -private: - std::map pairs; -}; - -/** - * The IPTC key/value pairs - */ -class IPTCPairs final -{ -public: - using iterator = std::map>::iterator; - using const_iterator = std::map>::const_iterator; - - iterator find(const Glib::ustring& key) - { - return pairs.find(key); - } - - const_iterator begin() const - { - return pairs.begin(); - } - - const_iterator end() const - { - return pairs.end(); - } - - bool empty() const - { - return pairs.empty(); - } - - void clear() - { - pairs.clear(); - } - - std::vector& operator[](const Glib::ustring& key) - { - return pairs[key]; - } - - bool operator ==(const IPTCPairs& other) const - { - return pairs == other.pairs; - } - -private: - std::map> pairs; -}; +typedef std::map ExifPairs; +typedef std::map> IPTCPairs; struct WaveletParams { std::vector ccwcurve; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 0f0d31c40..5efb3249c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1693,8 +1693,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) // Load complete Exif information - std::unique_ptr rml(new RawMetaDataLocation (ri->get_exifBase(), ri->get_ciffBase(), ri->get_ciffLen())); - idata = new FramesData (fname, std::move(rml)); + idata = new FramesData (fname); idata->setDCRawFrameCount (numFrames); green(W, H); diff --git a/rtengine/rawmetadatalocation.h b/rtengine/rawmetadatalocation.h deleted file mode 100644 index de6c6a0d7..000000000 --- a/rtengine/rawmetadatalocation.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _RAWMETADATALOCATION_ -#define _RAWMETADATALOCATION_ - -namespace rtengine -{ - -class RawMetaDataLocation { - -public: - int exifBase; - int ciffBase; - int ciffLength; - - RawMetaDataLocation () : exifBase(-1), ciffBase(-1), ciffLength(-1) {} - explicit RawMetaDataLocation (int exifBase) : exifBase(exifBase), ciffBase(-1), ciffLength(-1) {} - RawMetaDataLocation (int ciffBase, int ciffLength) : exifBase(-1), ciffBase(ciffBase), ciffLength(ciffLength) {} - RawMetaDataLocation (int exifBase, int ciffBase, int ciffLength) : exifBase(exifBase), ciffBase(ciffBase), ciffLength(ciffLength) {} -}; - -} - -#endif - diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6264d43ae..b6b7402f9 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -26,8 +26,6 @@ #include #include #include -#include "../rtexif/rtexif.h" -#include "rawmetadatalocation.h" #include "iimage.h" #include "utils.h" #include "../rtgui/threadutils.h" @@ -49,14 +47,15 @@ enum RenderingIntent : int; namespace procparams { -class ProcParams; -class IPTCPairs; +typedef std::map ExifPairs; +typedef std::map> IPTCPairs; struct RAWParams; struct ColorManagementParams; struct CropParams; enum class ToneCurveMode : int; +class ProcParams; } @@ -73,76 +72,54 @@ class FramesMetaData { public: - /** @return Returns the number of root Metadata */ - virtual unsigned int getRootCount () const = 0; /** @return Returns the number of frame contained in the file based on Metadata */ - virtual unsigned int getFrameCount () const = 0; + virtual unsigned int getFrameCount() const = 0; /** Checks the availability of exif metadata tags. * @return Returns true if image contains exif metadata tags */ - virtual bool hasExif (unsigned int frame = 0) const = 0; - /** Returns the directory of exif metadata tags. - * @param root root number in the metadata tree - * @return The directory of exif metadata tags */ - virtual rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const = 0; - /** Returns the directory of exif metadata tags. - * @param frame frame number in the metadata tree - * @return The directory of exif metadata tags */ - virtual rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const = 0; - /** Returns the directory of exif metadata tags containing at least the 'Make' tag for the requested frame. - * If no usable metadata exist in the frame, send back the best TagDirectory describing the frame content. - * @param imgSource rawimage that we want the metadata from - * @param rawParams RawParams to select the frame number - * @return The directory of exif metadata tags containing at least the 'Make' tag */ - virtual rtexif::TagDirectory* getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const = 0; - /** Checks the availability of IPTC tags. - * @return Returns true if image contains IPTC tags */ - virtual bool hasIPTC (unsigned int frame = 0) const = 0; - /** Returns the directory of IPTC tags. - * @return The directory of IPTC tags */ - virtual procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const = 0; + virtual bool hasExif() const = 0; /** @return a struct containing the date and time of the image */ - virtual tm getDateTime (unsigned int frame = 0) const = 0; + virtual tm getDateTime() const = 0; /** @return a timestamp containing the date and time of the image */ - virtual time_t getDateTimeAsTS(unsigned int frame = 0) const = 0; + virtual time_t getDateTimeAsTS() const = 0; /** @return the ISO of the image */ - virtual int getISOSpeed (unsigned int frame = 0) const = 0; + virtual int getISOSpeed() const = 0; /** @return the F number of the image */ - virtual double getFNumber (unsigned int frame = 0) const = 0; + virtual double getFNumber() const = 0; /** @return the focal length used at the exposure */ - virtual double getFocalLen (unsigned int frame = 0) const = 0; + virtual double getFocalLen() const = 0; /** @return the focal length in 35mm used at the exposure */ - virtual double getFocalLen35mm (unsigned int frame = 0) const = 0; + virtual double getFocalLen35mm() const = 0; /** @return the focus distance in meters, 0=unknown, 10000=infinity */ - virtual float getFocusDist (unsigned int frame = 0) const = 0; + virtual float getFocusDist() const = 0; /** @return the shutter speed */ - virtual double getShutterSpeed (unsigned int frame = 0) const = 0; + virtual double getShutterSpeed() const = 0; /** @return the exposure compensation */ - virtual double getExpComp (unsigned int frame = 0) const = 0; + virtual double getExpComp() const = 0; /** @return the maker of the camera */ - virtual std::string getMake (unsigned int frame = 0) const = 0; + virtual std::string getMake() const = 0; /** @return the model of the camera */ - virtual std::string getModel (unsigned int frame = 0) const = 0; + virtual std::string getModel() const = 0; - std::string getCamera (unsigned int frame = 0) const + std::string getCamera() const { - return getMake(frame) + " " + getModel(frame); + return getMake() + " " + getModel(); } /** @return the lens on the camera */ - virtual std::string getLens (unsigned int frame = 0) const = 0; + virtual std::string getLens() const = 0; /** @return the orientation of the image */ - virtual std::string getOrientation (unsigned int frame = 0) const = 0; + virtual std::string getOrientation() const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ 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 (unsigned int frame = 0) const = 0; + virtual bool getHDR() 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 (unsigned int frame) const = 0; + virtual std::string getImageType() const = 0; /** @return the sample format based on MetaData */ - virtual IIOSampleFormat getSampleFormat (unsigned int frame = 0) const = 0; + virtual IIOSampleFormat getSampleFormat() const = 0; /** Functions to convert between floating point and string representation of shutter and aperture */ static std::string apertureToString (double aperture); @@ -163,7 +140,9 @@ public: * Use it only for raw files. In caseof jpgs and tiffs pass a NULL pointer. * @param firstFrameOnly must be true to get the MetaData of the first frame only, e.g. for a PixelShift file. * @return The metadata */ - static FramesMetaData* fromFile (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly = false); + static FramesMetaData* fromFile (const Glib::ustring& fname); + + virtual Glib::ustring getFileName() const = 0; }; /** This listener interface is used to indicate the progress of time consuming operations */ diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1ee09dcf3..a3c9ec6ba 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -312,7 +312,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, namespace { -Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml, eSensorType &sensorType, int &w, int &h) +Image8 *load_inspector_mode(const Glib::ustring &fname, eSensorType &sensorType, int &w, int &h) { BENCHFUN @@ -368,7 +368,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml } // namespace -Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode, bool forHistogramMatching) +Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode, bool forHistogramMatching) { Thumbnail* tpp = new Thumbnail (); tpp->isRaw = 1; @@ -378,7 +378,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL tpp->colorMatrix[2][2] = 1.0; if (inspectorMode && !forHistogramMatching && settings->thumbnail_inspector_mode == Settings::ThumbnailInspectorMode::RAW) { - Image8 *img = load_inspector_mode(fname, rml, sensorType, w, h); + Image8 *img = load_inspector_mode(fname, sensorType, w, h); if (!img) { delete tpp; return nullptr; @@ -403,10 +403,6 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL sensorType = ri->getSensorType(); - rml.exifBase = ri->get_exifBase(); - rml.ciffBase = ri->get_ciffBase(); - rml.ciffLength = ri->get_ciffLen(); - Image8* img = new Image8 (); // No sample format detection occurred earlier, so we set them here, // as they are mandatory for the setScanline method @@ -447,7 +443,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL delete img; delete ri; - img = load_inspector_mode(fname, rml, sensorType, w, h); + img = load_inspector_mode(fname, sensorType, w, h); if (!img) { delete tpp; return nullptr; @@ -513,28 +509,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL #define FISBLUE(filter,row,col) \ ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter) -RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname) -{ - RawMetaDataLocation rml; - rml.exifBase = -1; - rml.ciffBase = -1; - rml.ciffLength = -1; - - RawImage ri (fname); - unsigned int imageNum = 0; - - int r = ri.loadRaw (false, imageNum); - - if ( !r ) { - rml.exifBase = ri.get_exifBase(); - rml.ciffBase = ri.get_ciffBase(); - rml.ciffLength = ri.get_ciffLen(); - } - - return rml; -} - -Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching) +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching) { RawImage *ri = new RawImage (fname); unsigned int tempImageNum = 0; @@ -572,10 +547,6 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati ri->pre_interpolate(); - rml.exifBase = ri->get_exifBase(); - rml.ciffBase = ri->get_ciffBase(); - rml.ciffLength = ri->get_ciffLen(); - tpp->camwbRed = tpp->redMultiplier / pre_mul[0]; //ri->get_pre_mul(0); tpp->camwbGreen = tpp->greenMultiplier / pre_mul[1]; //ri->get_pre_mul(1); tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2]; //ri->get_pre_mul(2); @@ -1084,19 +1055,11 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int // Full thumbnail processing, second stage if complete profile exists IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool forHistogramMatching) { - unsigned int imgNum = 0; - if (isRaw) { - if (sensorType == ST_BAYER) { - imgNum = rtengine::LIM(params.raw.bayersensor.imageNum, 0, metadata->getFrameCount() - 1); - } else if (sensorType == ST_FUJI_XTRANS) { - //imgNum = rtengine::LIM(params.raw.xtranssensor.imageNum, 0, metadata->getFrameCount() - 1) - } - } - std::string camName = metadata->getCamera(imgNum); - float shutter = metadata->getShutterSpeed(imgNum); - float fnumber = metadata->getFNumber(imgNum); - float iso = metadata->getISOSpeed(imgNum); - float fcomp = metadata->getExpComp(imgNum); + std::string camName = metadata->getCamera(); + float shutter = metadata->getShutterSpeed(); + float fnumber = metadata->getFNumber(); + float iso = metadata->getISOSpeed(); + float fcomp = metadata->getExpComp(); // check if the WB's equalizer value has changed if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4) || wbTempBias < (params.wb.tempBias - 5e-4) || wbTempBias > (params.wb.tempBias + 5e-4)) { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index df33b892d..a2839e83d 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -19,7 +19,6 @@ #ifndef _THUMBPROCESSINGPARAMETERS_ #define _THUMBPROCESSINGPARAMETERS_ -#include "rawmetadatalocation.h" #include #include #include "image8.h" @@ -82,10 +81,9 @@ public: int getImageWidth (const procparams::ProcParams& pparams, int rheight, float &ratio); void getDimensions (int& w, int& h, double& scaleFac); - static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false); - static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false); + static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false); + static Thumbnail* loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false); static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); - static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname); void getCamWB (double& temp, double& green); void getAutoWB (double& temp, double& green, double equal, double tempBias); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index ff2b234a3..64edc5c17 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1151,16 +1151,10 @@ private: if (params.colorappearance.enabled) { double adap; - int imgNum = 0; - if (imgsrc->getSensorType() == ST_BAYER) { - imgNum = params.raw.bayersensor.imageNum; - } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { - //imgNum = params.raw.xtranssensor.imageNum; - } - float fnum = imgsrc->getMetaData()->getFNumber (imgNum); // F number - float fiso = imgsrc->getMetaData()->getISOSpeed (imgNum) ; // ISO - float fspeed = imgsrc->getMetaData()->getShutterSpeed (imgNum) ; //speed - float fcomp = imgsrc->getMetaData()->getExpComp (imgNum); //compensation + - + float fnum = imgsrc->getMetaData()->getFNumber (); // F number + float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO + float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; //speed + float fcomp = imgsrc->getMetaData()->getExpComp (); //compensation + - if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { adap = 2000.; @@ -1295,15 +1289,20 @@ private: readyImg = tempImage; } + MetadataInfo info(imgsrc->getFileName()); switch (params.metadata.mode) { case MetaDataParams::TUNNEL: // Sending back the whole first root, which won't necessarily be the selected frame number // and may contain subframe depending on initial raw's hierarchy - readyImg->setMetadata (ii->getMetaData()->getRootExifData ()); + // readyImg->setMetadata (ii->getMetaData()->getRootExifData ()); + readyImg->setMetadata(info); break; case MetaDataParams::EDIT: + info.setExif(params.exif); + info.setIptc(params.iptc); + readyImg->setMetadata(info); // ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy - readyImg->setMetadata (ii->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); + // readyImg->setMetadata (ii->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); break; default: // case MetaDataParams::STRIP // nothing to do diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt deleted file mode 100644 index 9747b03fb..000000000 --- a/rtexif/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_library(rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc panasonicattribs.cc) -add_dependencies(rtexif UpdateInfo) - -if(WIN32) - include_directories(${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS}) - link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS}) -else() - set_target_properties(rtexif PROPERTIES COMPILE_FLAGS " -fPIC") - include_directories(${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS}) - link_directories(${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS}) -endif() - -include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") - -if(BUILD_SHARED_LIBS) - install(TARGETS rtexif DESTINATION ${LIBDIR}) -endif() diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc deleted file mode 100644 index 2dcbdd96f..000000000 --- a/rtexif/canonattribs.cc +++ /dev/null @@ -1,2078 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _CANONATTRIBS_ -#define _CANONATTRIBS_ - -#include -#include - -#include "rtexif.h" - -using namespace std; - -namespace rtexif -{ - -class CAOnOffInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - int n = t->toInt(); - - if ( n == 0 ) { - return "OFF"; - } else if ( n == 1) { - return "ON"; - } else { - return "undef"; - } - } -}; -CAOnOffInterpreter caOnOffInterpreter; - -class CAIntSerNumInterpreter : public Interpreter -{ -public: - CAIntSerNumInterpreter () {} - std::string toString (const Tag* t) const override - { - return ""; - } -}; - -CAIntSerNumInterpreter caIntSerNumInterpreter; - -class CAApertureInterpreter : public Interpreter -{ -public: - CAApertureInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = pow (2.0, t->toDouble() / 64.0); - - if ( v < 0. || v > 1000.) { - return "undef"; - } - - sprintf (buffer, "%.1f", v ); - return buffer; - } -}; -CAApertureInterpreter caApertureInterpreter; - -class CAMacroModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAMacroModeInterpreter() - { - choices[1] = "Macro"; - choices[2] = "Normal"; - } -}; -CAMacroModeInterpreter caMacroModeInterpreter; - -class CASelfTimerInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - int sec = t->toInt (0, SHORT); - - if ( !sec ) { - return "OFF"; - } - - char buffer[32]; - sprintf (buffer, "%.1fs %s", sec / 10., (sec & 0x4000) ? ",Custom" : ""); - return buffer; - } -}; -CASelfTimerInterpreter caSelfTimerInterpreter; - -class CAQualityInterpreter : public ChoiceInterpreter<> -{ -public: - CAQualityInterpreter() - { - choices[1] = "Economy"; - choices[2] = "Normal"; - choices[3] = "Fine"; - choices[4] = "RAW"; - choices[5] = "Superfine"; - } -}; -CAQualityInterpreter caQualityInterpreter; - -class CAFlashModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAFlashModeInterpreter() - { - choices[0] = "Off"; - choices[1] = "Auto"; - choices[2] = "On"; - choices[3] = "Red-eye reduction"; - choices[4] = "Slow-sync"; - choices[5] = "Red-eye reduction (Auto)"; - choices[6] = "Red-eye reduction (On)"; - choices[16] = "External flash"; - } -}; -CAFlashModeInterpreter caFlashModeInterpreter; - -class CAContinuousDriveInterpreter : public ChoiceInterpreter<> -{ -public: - CAContinuousDriveInterpreter() - { - choices[0] = "Single"; - choices[1] = "Continuous"; - choices[2] = "Movie"; - choices[3] = "Continuous, Speed Priority"; - choices[4] = "Continuous, Low"; - choices[5] = "Continuous, High"; - choices[6] = "Silent Single"; - choices[9] = "Single, Silent"; - choices[10] = "Continuous, Silent"; - } -}; -CAContinuousDriveInterpreter caContinuousDriveInterpreter; - -class CAFocusModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAFocusModeInterpreter() - { - choices[0] = "One-shot AF"; - choices[1] = "AI Servo AF"; - choices[2] = "AI Focus AF"; - choices[3] = "Manual Focus (3)"; - choices[4] = "Single"; - choices[5] = "Continuous"; - choices[6] = "Manual Focus (6)"; - choices[16] = "Pan Focus"; - choices[256] = "AF + MF"; - choices[512] = "Movie Snap Focus"; - choices[519] = "Movie Servo AF"; - } -}; -CAFocusModeInterpreter caFocusModeInterpreter; - -class CARecordModeInterpreter : public ChoiceInterpreter<> -{ -public: - CARecordModeInterpreter() - { - choices[1] = "JPEG"; - choices[2] = "CRW+THM"; - choices[3] = "AVI+THM"; - choices[4] = "TIF"; - choices[5] = "TIF+JPEG"; - choices[6] = "CR2"; - choices[7] = "CR2+JPEG"; - choices[9] = "MOV"; - choices[10] = "MP4"; - } -}; -CARecordModeInterpreter caRecordModeInterpreter; - -class CAImageSizeInterpreter : public ChoiceInterpreter<> -{ -public: - CAImageSizeInterpreter () - { - choices[0] = "Large"; - choices[1] = "Medium"; - choices[2] = "Small"; - choices[5] = "Medium 1"; - choices[6] = "Medium 2"; - choices[7] = "Medium 3"; - choices[8] = "Postcard"; - choices[9] = "Widescreen"; - choices[10] = "Medium Widescreen"; - choices[14] = "Small 1"; - choices[15] = "Small 2"; - choices[16] = "Small 3"; - choices[128] = "640x480 Movie"; - choices[129] = "Medium Movie"; - choices[130] = "Small Movie"; - choices[137] = "1280x720 Movie"; - choices[142] = "1920x1080 Movie"; - } -}; -CAImageSizeInterpreter caImageSizeInterpreter; - -class CAEasyModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAEasyModeInterpreter () - { - choices[0] = "Full auto"; - choices[1] = "Manual"; - choices[2] = "Landscape"; - choices[3] = "Fast shutter"; - choices[4] = "Slow shutter"; - choices[5] = "Night"; - choices[6] = "Gray Scale"; - choices[7] = "Sepia"; - choices[8] = "Portrait"; - choices[9] = "Sports"; - choices[10] = "Macro"; - choices[11] = "Black & White"; - choices[12] = "Pan focus"; - choices[13] = "Vivid"; - choices[14] = "Neutral"; - choices[15] = "Flash Off"; - choices[16] = "Long Shutter"; - choices[17] = "Super Macro"; - choices[18] = "Foliage"; - choices[19] = "Indoor"; - choices[20] = "Fireworks"; - choices[21] = "Beach"; - choices[22] = "Underwater"; - choices[23] = "Snow"; - choices[24] = "Kids & Pets"; - choices[25] = "Night Snapshot"; - choices[26] = "Digital Macro"; - choices[27] = "My Colors"; - choices[28] = "Movie Snap"; - choices[29] = "Super Macro 2"; - choices[30] = "Color Accent"; - choices[31] = "Color Swap"; - choices[32] = "Aquarium"; - choices[33] = "ISO 3200"; - choices[34] = "ISO 6400"; - choices[35] = "Creative Light Effect"; - choices[36] = "Easy"; - choices[37] = "Quick Shot"; - choices[38] = "Creative Auto"; - choices[39] = "Zoom Blur"; - choices[40] = "Low Light"; - choices[41] = "Nostalgic"; - choices[42] = "Super Vivid"; - choices[43] = "Poster Effect"; - choices[44] = "Face Self-timer"; - choices[45] = "Smile"; - choices[46] = "Wink Self-timer"; - choices[47] = "Fisheye Effect"; - choices[48] = "Miniature Effect"; - choices[49] = "High-speed Burst"; - choices[50] = "Best Image Selection"; - choices[51] = "High Dynamic Range"; - choices[52] = "Handheld Night Scene"; - choices[53] = "Movie Digest"; - choices[54] = "Live View Control"; - choices[55] = "Discreet"; - choices[56] = "Blur Reduction"; - choices[57] = "Monochrome"; - choices[58] = "Toy Camera Effect"; - choices[59] = "Scene Intelligent Auto"; - choices[60] = "High-speed Burst HQ"; - choices[61] = "Smooth Skin"; - choices[62] = "Soft Focus"; - choices[257] = "Spotlight"; - choices[258] = "Night 2"; - choices[259] = "Night+"; - choices[260] = "Super Night"; - choices[261] = "Sunset"; - choices[263] = "Night Scene"; - choices[264] = "Surface"; - choices[265] = "Low Light 2"; - } -}; -CAEasyModeInterpreter caEasyModeInterpreter; - -class CADigitalZoomInterpreter : public ChoiceInterpreter<> -{ -public: - CADigitalZoomInterpreter() - { - choices[0] = "None"; - choices[1] = "2x"; - choices[2] = "4x"; - choices[3] = "Other"; - } -}; -CADigitalZoomInterpreter caDigitalZoomInterpreter; - -class CAMeteringModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAMeteringModeInterpreter() - { - choices[0] = "Default"; - choices[1] = "Spot"; - choices[2] = "Average"; - choices[3] = "Evaluative"; - choices[4] = "Partial"; - choices[5] = "Center-weighted average"; - } -}; -CAMeteringModeInterpreter caMeteringModeInterpreter; - -class CAFocusRangeInterpreter : public ChoiceInterpreter<> -{ -public: - CAFocusRangeInterpreter() - { - choices[0] = "Manual"; - choices[1] = "Auto"; - choices[2] = "Not Known"; - choices[3] = "Macro"; - choices[4] = "Very Close"; - choices[5] = "Close"; - choices[6] = "Middle Range"; - choices[7] = "Far Range"; - choices[8] = "Pan Focus"; - choices[9] = "Super Macro"; - choices[10] = "Infinity"; - } -}; -CAFocusRangeInterpreter caFocusRangeInterpreter; - -class CAAFPointInterpreter : public ChoiceInterpreter<> -{ -public: - CAAFPointInterpreter() - { - choices[0x2005] = "Manual AF point selection "; - choices[0x3000] = "None (MF)"; - choices[0x3001] = "Auto AF point selection "; - choices[0x3002] = "Right "; - choices[0x3003] = "Center "; - choices[0x3004] = "Left "; - choices[0x4001] = "Auto AF point selection "; - choices[0x4006] = "Face Detect"; - } -}; -CAAFPointInterpreter caAFPointInterpreter; - -class CAExposureModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAExposureModeInterpreter() - { - choices[0] = "Easy"; - choices[1] = "Program AE"; - choices[2] = "Shutter speed priority AE"; - choices[3] = "Aperture-priority AE"; - choices[4] = "Manual"; - choices[5] = "Depth-of-field AE"; - choices[6] = "M-Dep"; - choices[7] = "Bulb"; - } -}; -CAExposureModeInterpreter caExposureModeInterpreter; - -class CAFlashBitsInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - std::ostringstream s; - unsigned bits = t->toInt (0, SHORT); - - if ( bits & 0x0001 ) { - s << "Manual "; - } - - if ( bits & 0x0002 ) { - s << "TTL "; - } - - if ( bits & 0x0004 ) { - s << "A-TTL "; - } - - if ( bits & 0x0008 ) { - s << "E-TTL "; - } - - if ( bits & 0x0010 ) { - s << "FP sync enabled "; - } - - if ( bits & 0x0080 ) { - s << "2nd curtain "; - } - - if ( bits & 0x0800 ) { - s << "FP sync used "; - } - - if ( bits & 0x2000 ) { - s << "Built-in "; - } - - if ( bits & 0x4000 ) { - s << "External "; - } - - return s.str(); - } -}; -CAFlashBitsInterpreter caFlashBitsInterpreter; - -class CAFocusContinuousInterpreter : public ChoiceInterpreter<> -{ -public: - CAFocusContinuousInterpreter() - { - choices[0] = "Single"; - choices[1] = "Continuous"; - choices[8] = "Manual"; - } -}; -CAFocusContinuousInterpreter caFocusContinuousInterpreter; - -class CAAESettingsInterpreter : public ChoiceInterpreter<> -{ -public: - CAAESettingsInterpreter() - { - choices[0] = "Normal AE"; - choices[1] = "Exposure Compensation"; - choices[2] = "AE Lock"; - choices[3] = "AE Lock + Exposure Comp."; - choices[4] = "No AE"; - } -}; -CAAESettingsInterpreter caAESettingsInterpreter; - -class CAStabilizationInterpreter : public ChoiceInterpreter<> -{ -public: - CAStabilizationInterpreter() - { - choices[0] = "Off"; - choices[1] = "On"; - choices[2] = "Shoot Only"; - choices[3] = "Panning"; - choices[4] = "Dynamic"; - choices[256] = "Off (2)"; - choices[257] = "On (2)"; - choices[258] = "Shoot Only (2)"; - choices[259] = "Panning (2)"; - choices[260] = "Dynamic (2)"; - } -}; -CAStabilizationInterpreter caStabilizationInterpreter; - -class CASpotMeteringInterpreter : public ChoiceInterpreter<> -{ -public: - CASpotMeteringInterpreter() - { - choices[0] = "Center"; - choices[1] = "AF Point"; - } -}; -CASpotMeteringInterpreter caSpotMeteringInterpreter; - -class CAPhotoEffectInterpreter : public ChoiceInterpreter<> -{ -public: - CAPhotoEffectInterpreter() - { - choices[0] = "Off"; - choices[1] = "Vivid"; - choices[2] = "Neutral"; - choices[3] = "Smooth"; - choices[4] = "Sepia"; - choices[5] = "B&W"; - choices[6] = "Custom"; - choices[100] = "My Color Data"; - } -}; -CAPhotoEffectInterpreter caPhotoEffectInterpreter; - -class CAManualFlashInterpreter : public ChoiceInterpreter<> -{ -public: - CAManualFlashInterpreter() - { - choices[0] = "N/A"; - choices[0x500] = "Full"; - choices[0x502] = "Medium"; - choices[0x504] = "Low"; - choices[0x7fff] = "N/A"; - } -}; -CAManualFlashInterpreter caManualFlashInterpreter; - -class CARAWQualityInterpreter : public ChoiceInterpreter<> -{ -public: - CARAWQualityInterpreter() - { - choices[0] = "N/A"; - choices[1] = "sRAW1 (mRAW)"; - choices[2] = "sRAW2 (sRAW)"; - } -}; -CARAWQualityInterpreter caRAWQualityInterpreter; - -class CAFocalInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - Tag *unitTag = t->getParent()->getRoot()->findTag ("FocalUnits"); - double v = unitTag ? unitTag->toDouble() : 1.; - v = (v > 0. ? t->toDouble() / v : t->toDouble()); - - if ( v < 0. || v > 1000000.) { - return "undef"; - } - - char buffer[32]; - sprintf (buffer, "%.1f", v ); - return buffer; - } -}; -CAFocalInterpreter caFocalInterpreter; - -class CALensInterpreter : public IntLensInterpreter< int > -{ -public: - CALensInterpreter () - { - choices = { - {1, "Canon EF 50mm f/1.8"}, - {2, "Canon EF 28mm f/2.8"}, - {3, "Canon EF 135mm f/2.8 Soft"}, - {4, "Canon EF 35-105mm f/3.5-4.5 or Sigma Lens"}, - {4, "Sigma UC Zoom 35-135mm f/4-5.6"}, - {5, "Canon EF 35-70mm f/3.5-4.5"}, - {6, "Canon EF 28-70mm f/3.5-4.5 or Sigma or Tokina Lens"}, - {6, "Sigma 18-50mm f/3.5-5.6 DC"}, - {6, "Sigma 18-125mm f/3.5-5.6 DC IF ASP"}, - {6, "Tokina AF 193-2 19-35mm f/3.5-4.5"}, - {6, "Sigma 28-80mm f/3.5-5.6 II Macro"}, - {6, "Sigma 28-300mm f/3.5-6.3 DG Macro"}, - {7, "Canon EF 100-300mm f/5.6L"}, - {8, "Canon EF 100-300mm f/5.6 or Sigma or Tokina Lens"}, - {8, "Sigma 70-300mm f/4-5.6 [APO] DG Macro"}, - {8, "Tokina AT-X 242 AF 24-200mm f/3.5-5.6"}, - {9, "Canon EF 70-210mm f/4"}, - {9, "Sigma 55-200mm f/4-5.6 DC"}, - {10, "Canon EF 50mm f/2.5 Macro or Sigma Lens"}, - {10, "Sigma 50mm f/2.8 EX"}, - {10, "Sigma 28mm f/1.8"}, - {10, "Sigma 105mm f/2.8 Macro EX"}, - {10, "Sigma 70mm f/2.8 EX DG Macro EF"}, - {11, "Canon EF 35mm f/2"}, - {13, "Canon EF 15mm f/2.8 Fisheye"}, - {14, "Canon EF 50-200mm f/3.5-4.5L"}, - {15, "Canon EF 50-200mm f/3.5-4.5"}, - {16, "Canon EF 35-135mm f/3.5-4.5"}, - {17, "Canon EF 35-70mm f/3.5-4.5A"}, - {18, "Canon EF 28-70mm f/3.5-4.5"}, - {20, "Canon EF 100-200mm f/4.5A"}, - {21, "Canon EF 80-200mm f/2.8L"}, - {22, "Canon EF 20-35mm f/2.8L or Tokina Lens"}, - {22, "Tokina AT-X 280 AF Pro 28-80mm f/2.8 Aspherical"}, - {23, "Canon EF 35-105mm f/3.5-4.5"}, - {24, "Canon EF 35-80mm f/4-5.6 Power Zoom"}, - {25, "Canon EF 35-80mm f/4-5.6 Power Zoom"}, - {26, "Canon EF 100mm f/2.8 Macro or Other Lens"}, - {26, "Cosina 100mm f/3.5 Macro AF"}, - {26, "Tamron SP AF 90mm f/2.8 Di Macro"}, - {26, "Tamron SP AF 180mm f/3.5 Di Macro"}, - {26, "Carl Zeiss Planar T* 50mm f/1.4"}, - {27, "Canon EF 35-80mm f/4-5.6"}, - {28, "Canon EF 80-200mm f/4.5-5.6 or Tamron Lens"}, - {28, "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF"}, - {28, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro"}, - {28, "Tamron AF 70-300mm f/4-5.6 Di LD 1:2 Macro"}, - {28, "Tamron AF Aspherical 28-200mm f/3.8-5.6"}, - {29, "Canon EF 50mm f/1.8 II"}, - {30, "Canon EF 35-105mm f/4.5-5.6"}, - {31, "Canon EF 75-300mm f/4-5.6 or Tamron Lens"}, - {31, "Tamron SP AF 300mm f/2.8 LD IF"}, - {32, "Canon EF 24mm f/2.8 or Sigma Lens"}, - {32, "Sigma 15mm f/2.8 EX Fisheye"}, - {33, "Voigtlander or Carl Zeiss Lens"}, - {33, "Voigtlander Ultron 40mm f/2 SLII Aspherical"}, - {33, "Voigtlander Color Skopar 20mm f/3.5 SLII Aspherical"}, - {33, "Voigtlander APO-Lanthar 90mm f/3.5 SLII Close Focus"}, - {33, "Carl Zeiss Distagon T* 15mm f/2.8 ZE"}, - {33, "Carl Zeiss Distagon T* 18mm f/3.5 ZE"}, - {33, "Carl Zeiss Distagon T* 21mm f/2.8 ZE"}, - {33, "Carl Zeiss Distagon T* 25mm f/2 ZE"}, - {33, "Carl Zeiss Distagon T* 28mm f/2 ZE"}, - {33, "Carl Zeiss Distagon T* 35mm f/2 ZE"}, - {33, "Carl Zeiss Distagon T* 35mm f/1.4 ZE"}, - {33, "Carl Zeiss Planar T* 50mm f/1.4 ZE"}, - {33, "Carl Zeiss Makro-Planar T* 50mm f/2 ZE"}, - {33, "Carl Zeiss Makro-Planar T* 100mm f/2 ZE"}, - {33, "Carl Zeiss Apo-Sonnar T* 135mm f/2 ZE"}, - {35, "Canon EF 35-80mm f/4-5.6"}, - {36, "Canon EF 38-76mm f/4.5-5.6"}, - {37, "Canon EF 35-80mm f/4-5.6 or Tamron Lens"}, - {37, "Tamron 70-200mm f/2.8 Di LD IF Macro"}, - {37, "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20"}, - {37, "Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]"}, - {37, "Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical [IF] Macro"}, - {38, "Canon EF 80-200mm f/4.5-5.6"}, - {39, "Canon EF 75-300mm f/4-5.6"}, - {40, "Canon EF 28-80mm f/3.5-5.6"}, - {41, "Canon EF 28-90mm f/4-5.6"}, - {42, "Canon EF 28-200mm f/3.5-5.6 or Tamron Lens"}, - {42, "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20"}, - {43, "Canon EF 28-105mm f/4-5.6"}, - {44, "Canon EF 90-300mm f/4.5-5.6"}, - {45, "Canon EF-S 18-55mm f/3.5-5.6 [II]"}, - {46, "Canon EF 28-90mm f/4-5.6"}, - {47, "Zeiss Milvus 35mm f/2 or 50mm f/2"}, - {47, "Zeiss Milvus 50mm f/2 Makro"}, - {48, "Canon EF-S 18-55mm f/3.5-5.6 IS"}, - {49, "Canon EF-S 55-250mm f/4-5.6 IS"}, - {50, "Canon EF-S 18-200mm f/3.5-5.6 IS"}, - {51, "Canon EF-S 18-135mm f/3.5-5.6 IS"}, - {52, "Canon EF-S 18-55mm f/3.5-5.6 IS II"}, - {53, "Canon EF-S 18-55mm f/3.5-5.6 III"}, - {54, "Canon EF-S 55-250mm f/4-5.6 IS II"}, - {60, "Irix 11mm f/4"}, - {80, "Canon TS-E 50mm f/2.8L Macro"}, - {81, "Canon TS-E 90mm f/2.8L Macro"}, - {82, "Canon TS-E 135mm f/4L Macro"}, - {94, "Canon TS-E 17mm f/4L"}, - {95, "Canon TS-E 24mm f/3.5L II"}, - {103, "Samyang AF 14mm f/2.8 EF or Rokinon Lens"}, - {103, "Rokinon SP 14mm f/2.4"}, - {103, "Rokinon AF 14mm f/2.8 EF"}, - {124, "Canon MP-E 65mm f/2.8 1-5x Macro Photo"}, - {125, "Canon TS-E 24mm f/3.5L"}, - {126, "Canon TS-E 45mm f/2.8"}, - {127, "Canon TS-E 90mm f/2.8"}, - {129, "Canon EF 300mm f/2.8L USM"}, - {130, "Canon EF 50mm f/1.0L USM"}, - {131, "Canon EF 28-80mm f/2.8-4L USM or Sigma Lens"}, - {131, "Sigma 8mm f/3.5 EX DG Circular Fisheye"}, - {131, "Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM"}, - {131, "Sigma 17-70mm f/2.8-4.5 DC Macro"}, - {131, "Sigma APO 50-150mm f/2.8 [II] EX DC HSM"}, - {131, "Sigma APO 120-300mm f/2.8 EX DG HSM"}, - {131, "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye"}, - {131, "Sigma 70-200mm f/2.8 APO EX HSM"}, - {132, "Canon EF 1200mm f/5.6L USM"}, - {134, "Canon EF 600mm f/4L IS USM"}, - {135, "Canon EF 200mm f/1.8L USM"}, - {136, "Canon EF 300mm f/2.8L USM"}, - {137, "Canon EF 85mm f/1.2L USM or Sigma or Tamron Lens"}, - {137, "Sigma 18-50mm f/2.8-4.5 DC OS HSM"}, - {137, "Sigma 50-200mm f/4-5.6 DC OS HSM"}, - {137, "Sigma 18-250mm f/3.5-6.3 DC OS HSM"}, - {137, "Sigma 24-70mm f/2.8 IF EX DG HSM"}, - {137, "Sigma 18-125mm f/3.8-5.6 DC OS HSM"}, - {137, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C"}, - {137, "Sigma 17-50mm f/2.8 OS HSM"}, - {137, "Sigma 18-200mm f/3.5-6.3 DC OS HSM [II]"}, - {137, "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD"}, - {137, "Sigma 8-16mm f/4.5-5.6 DC HSM"}, - {137, "Tamron SP 17-50mm f/2.8 XR Di II VC"}, - {137, "Tamron SP 60mm f/2 Macro Di II"}, - {137, "Sigma 10-20mm f/3.5 EX DC HSM"}, - {137, "Tamron SP 24-70mm f/2.8 Di VC USD"}, - {137, "Sigma 18-35mm f/1.8 DC HSM"}, - {137, "Sigma 12-24mm f/4.5-5.6 DG HSM II"}, - {138, "Canon EF 28-80mm f/2.8-4L"}, - {139, "Canon EF 400mm f/2.8L USM"}, - {140, "Canon EF 500mm f/4.5L USM"}, - {141, "Canon EF 500mm f/4.5L USM"}, - {142, "Canon EF 300mm f/2.8L IS USM"}, - {143, "Canon EF 500mm f/4L IS USM or Sigma Lens"}, - {143, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM"}, - {144, "Canon EF 35-135mm f/4-5.6 USM"}, - {145, "Canon EF 100-300mm f/4.5-5.6 USM"}, - {146, "Canon EF 70-210mm f/3.5-4.5 USM"}, - {147, "Canon EF 35-135mm f/4-5.6 USM"}, - {148, "Canon EF 28-80mm f/3.5-5.6 USM"}, - {149, "Canon EF 100mm f/2 USM"}, - {150, "Canon EF 14mm f/2.8L USM or Sigma Lens"}, - {150, "Sigma 20mm EX f/1.8"}, - {150, "Sigma 30mm f/1.4 DC HSM"}, - {150, "Sigma 24mm f/1.8 DG Macro EX"}, - {150, "Sigma 28mm f/1.8 DG Macro EX"}, - {151, "Canon EF 200mm f/2.8L USM"}, - {152, "Canon EF 300mm f/4L IS USM or Sigma Lens"}, - {152, "Sigma 12-24mm f/4.5-5.6 EX DG ASPHERICAL HSM"}, - {152, "Sigma 14mm f/2.8 EX Aspherical HSM"}, - {152, "Sigma 10-20mm f/4-5.6"}, - {152, "Sigma 100-300mm f/4"}, - {153, "Canon EF 35-350mm f/3.5-5.6L USM or Sigma or Tamron Lens"}, - {153, "Sigma 50-500mm f/4-6.3 APO HSM EX"}, - {153, "Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical [IF] Macro"}, - {153, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro Model A14"}, - {153, "Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro"}, - {154, "Canon EF 20mm f/2.8 USM or Zeiss Lens"}, - {154, "Zeiss Milvus 21mm f/2.8"}, - {155, "Canon EF 85mm f/1.8 USM"}, - {156, "Canon EF 28-105mm f/3.5-4.5 USM or Tamron Lens"}, - {156, "Tamron SP 70-300mm f/4-5.6 Di VC USD"}, - {156, "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF"}, - {160, "Canon EF 20-35mm f/3.5-4.5 USM or Tamron or Tokina Lens"}, - {160, "Tamron AF 19-35mm f/3.5-4.5"}, - {160, "Tokina AT-X 124 AF Pro DX 12-24mm f/4"}, - {160, "Tokina AT-X 107 AF DX 10-17mm f/3.5-4.5 Fisheye"}, - {160, "Tokina AT-X 116 AF Pro DX 11-16mm f/2.8"}, - {160, "Tokina AT-X 11-20 F2.8 PRO DX Aspherical 11-20mm f/2.8"}, - {161, "Canon EF 28-70mm f/2.8L USM or Other Lens"}, - {161, "Sigma 24-70mm f/2.8 EX"}, - {161, "Sigma 28-70mm f/2.8 EX"}, - {161, "Sigma 24-60mm f/2.8 EX DG"}, - {161, "Tamron AF 17-50mm f/2.8 Di-II LD Aspherical"}, - {161, "Tamron 90mm f/2.8"}, - {161, "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF"}, - {161, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro"}, - {161, "Tokina AT-X 24-70mm f/2.8 PRO FX (IF)"}, - {162, "Canon EF 200mm f/2.8L USM"}, - {163, "Canon EF 300mm f/4L"}, - {164, "Canon EF 400mm f/5.6L"}, - {165, "Canon EF 70-200mm f/2.8L USM"}, - {166, "Canon EF 70-200mm f/2.8L USM + 1.4x"}, - {167, "Canon EF 70-200mm f/2.8L USM + 2x"}, - {168, "Canon EF 28mm f/1.8 USM or Sigma Lens"}, - {168, "Sigma 50-100mm f/1.8 DC HSM | A"}, - {169, "Canon EF 17-35mm f/2.8L USM or Sigma Lens"}, - {169, "Sigma 18-200mm f/3.5-6.3 DC OS"}, - {169, "Sigma 15-30mm f/3.5-4.5 EX DG Aspherical"}, - {169, "Sigma 18-50mm f/2.8 Macro"}, - {169, "Sigma 50mm f/1.4 EX DG HSM"}, - {169, "Sigma 85mm f/1.4 EX DG HSM"}, - {169, "Sigma 30mm f/1.4 EX DC HSM"}, - {169, "Sigma 35mm f/1.4 DG HSM"}, - {169, "Sigma 35mm f/1.5 FF High-Speed Prime | 017"}, - {170, "Canon EF 200mm f/2.8L II USM"}, - {171, "Canon EF 300mm f/4L USM"}, - {172, "Canon EF 400mm f/5.6L USM or Sigma Lens"}, - {172, "Sigma 150-600mm f/5-6.3 DG OS HSM | S"}, - {173, "Canon EF 180mm Macro f/3.5L USM or Sigma Lens"}, - {173, "Sigma 180mm EX HSM Macro f/3.5"}, - {173, "Sigma APO Macro 150mm f/2.8 EX DG HSM"}, - {174, "Canon EF 135mm f/2L USM or Other Lens"}, - {174, "Sigma 70-200mm f/2.8 EX DG APO OS HSM"}, - {174, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM"}, - {174, "Sigma 150-500mm f/5-6.3 APO DG OS HSM"}, - {174, "Zeiss Milvus 100mm f/2 Makro"}, - {175, "Canon EF 400mm f/2.8L USM"}, - {176, "Canon EF 24-85mm f/3.5-4.5 USM"}, - {177, "Canon EF 300mm f/4L IS USM"}, - {178, "Canon EF 28-135mm f/3.5-5.6 IS"}, - {179, "Canon EF 24mm f/1.4L USM"}, - {180, "Canon EF 35mm f/1.4L USM or Other Lens"}, - {180, "Sigma 50mm f/1.4 DG HSM | A"}, - {180, "Sigma 24mm f/1.4 DG HSM | A"}, - {180, "Zeiss Milvus 50mm f/1.4"}, - {180, "Zeiss Milvus 85mm f/1.4"}, - {180, "Zeiss Otus 28mm f/1.4 ZE"}, - {180, "Sigma 24mm f/1.5 FF High-Speed Prime | 017"}, - {180, "Sigma 50mm f/1.5 FF High-Speed Prime | 017"}, - {180, "Sigma 85mm f/1.5 FF High-Speed Prime | 017"}, - {181, "Canon EF 100-400mm f/4.5-5.6L IS USM + 1.4x or Sigma Lens"}, - {181, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + 1.4x"}, - {182, "Canon EF 100-400mm f/4.5-5.6L IS USM + 2x or Sigma Lens"}, - {182, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + 2x"}, - {183, "Canon EF 100-400mm f/4.5-5.6L IS USM or Sigma Lens"}, - {183, "Sigma 150mm f/2.8 EX DG OS HSM APO Macro"}, - {183, "Sigma 105mm f/2.8 EX DG OS HSM Macro"}, - {183, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro"}, - {183, "Sigma 150-600mm f/5-6.3 DG OS HSM | C"}, - {183, "Sigma 150-600mm f/5-6.3 DG OS HSM | S"}, - {183, "Sigma 100-400mm f/5-6.3 DG OS HSM"}, - {183, "Sigma 180mm f/3.5 APO Macro EX DG IF HSM"}, - {184, "Canon EF 400mm f/2.8L USM + 2x"}, - {185, "Canon EF 600mm f/4L IS USM"}, - {186, "Canon EF 70-200mm f/4L USM"}, - {187, "Canon EF 70-200mm f/4L USM + 1.4x"}, - {188, "Canon EF 70-200mm f/4L USM + 2x"}, - {189, "Canon EF 70-200mm f/4L USM + 2.8x"}, - {190, "Canon EF 100mm f/2.8 Macro USM"}, - {191, "Canon EF 400mm f/4 DO IS or Sigma Lens"}, - {191, "Sigma 500mm f/4 DG OS HSM"}, - {193, "Canon EF 35-80mm f/4-5.6 USM"}, - {194, "Canon EF 80-200mm f/4.5-5.6 USM"}, - {195, "Canon EF 35-105mm f/4.5-5.6 USM"}, - {196, "Canon EF 75-300mm f/4-5.6 USM"}, - {197, "Canon EF 75-300mm f/4-5.6 IS USM or Sigma Lens"}, - {197, "Sigma 18-300mm f/3.5-6.3 DC Macro OS HS"}, - {198, "Canon EF 50mm f/1.4 USM or Zeiss Lens"}, - {198, "Zeiss Otus 55mm f/1.4 ZE"}, - {198, "Zeiss Otus 85mm f/1.4 ZE"}, - {198, "Zeiss Milvus 25mm f/1.4"}, - {199, "Canon EF 28-80mm f/3.5-5.6 USM"}, - {200, "Canon EF 75-300mm f/4-5.6 USM"}, - {201, "Canon EF 28-80mm f/3.5-5.6 USM"}, - {202, "Canon EF 28-80mm f/3.5-5.6 USM IV"}, - {208, "Canon EF 22-55mm f/4-5.6 USM"}, - {209, "Canon EF 55-200mm f/4.5-5.6"}, - {210, "Canon EF 28-90mm f/4-5.6 USM"}, - {211, "Canon EF 28-200mm f/3.5-5.6 USM"}, - {212, "Canon EF 28-105mm f/4-5.6 USM"}, - {213, "Canon EF 90-300mm f/4.5-5.6 USM or Tamron Lens"}, - {213, "Tamron SP 150-600mm f/5-6.3 Di VC USD"}, - {213, "Tamron 16-300mm f/3.5-6.3 Di II VC PZD Macro"}, - {213, "Tamron SP 35mm f/1.8 Di VC USD"}, - {213, "Tamron SP 45mm f/1.8 Di VC USD"}, - {214, "Canon EF-S 18-55mm f/3.5-5.6 USM"}, - {215, "Canon EF 55-200mm f/4.5-5.6 II USM"}, - {217, "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD"}, - {224, "Canon EF 70-200mm f/2.8L IS USM"}, - {225, "Canon EF 70-200mm f/2.8L IS USM + 1.4x"}, - {226, "Canon EF 70-200mm f/2.8L IS USM + 2x"}, - {227, "Canon EF 70-200mm f/2.8L IS USM + 2.8x"}, - {228, "Canon EF 28-105mm f/3.5-4.5 USM"}, - {229, "Canon EF 16-35mm f/2.8L USM"}, - {230, "Canon EF 24-70mm f/2.8L USM"}, - {231, "Canon EF 17-40mm f/4L USM"}, - {232, "Canon EF 70-300mm f/4.5-5.6 DO IS USM"}, - {233, "Canon EF 28-300mm f/3.5-5.6L IS USM"}, - {234, "Canon EF-S 17-85mm f/4-5.6 IS USM or Tokina Lens"}, - {234, "Tokina AT-X 12-28 PRO DX 12-28mm f/4"}, - {235, "Canon EF-S 10-22mm f/3.5-4.5 USM"}, - {236, "Canon EF-S 60mm f/2.8 Macro USM"}, - {237, "Canon EF 24-105mm f/4L IS USM"}, - {238, "Canon EF 70-300mm f/4-5.6 IS USM"}, - {239, "Canon EF 85mm f/1.2L II USM or Rokinon Lens"}, - {239, "Rokinon SP 85mm f/1.2"}, - {240, "Canon EF-S 17-55mm f/2.8 IS USM or Sigma Lens"}, - {240, "Sigma 17-50mm f/2.8 EX DC OS HSM"}, - {241, "Canon EF 50mm f/1.2L USM"}, - {242, "Canon EF 70-200mm f/4L IS USM"}, - {243, "Canon EF 70-200mm f/4L IS USM + 1.4x"}, - {244, "Canon EF 70-200mm f/4L IS USM + 2x"}, - {245, "Canon EF 70-200mm f/4L IS USM + 2.8x"}, - {246, "Canon EF 16-35mm f/2.8L II USM"}, - {247, "Canon EF 14mm f/2.8L II USM"}, - {248, "Canon EF 200mm f/2L IS USM or Sigma Lens"}, - {248, "Sigma 24-35mm f/2 DG HSM | A"}, - {248, "Sigma 135mm f/2 FF High-Speed Prime | 017"}, - {248, "Sigma 24-35mm f/2.2 FF Zoom | 017"}, - {249, "Canon EF 800mm f/5.6L IS USM"}, - {250, "Canon EF 24mm f/1.4L II USM or Sigma Lens"}, - {250, "Sigma 20mm f/1.4 DG HSM | A"}, - {250, "Sigma 20mm f/1.5 FF High-Speed Prime | 017"}, - {251, "Canon EF 70-200mm f/2.8L IS II USM"}, - {252, "Canon EF 70-200mm f/2.8L IS II USM + 1.4x"}, - {253, "Canon EF 70-200mm f/2.8L IS II USM + 2x"}, - {254, "Canon EF 100mm f/2.8L Macro IS USM"}, - {255, "Sigma 24-105mm f/4 DG OS HSM | A or Other Sigma Lens"}, - {255, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro"}, - {368, "Sigma 14-24mm f/2.8 DG HSM | A or other Sigma Lens"}, - {368, "Sigma 20mm f/1.4 DG HSM | A"}, - {368, "Sigma 50mm f/1.4 DG HSM | A"}, - {368, "Sigma 40mm f/1.4 DG HSM | A"}, - {368, "Sigma 60-600mm f/4.5-6.3 DG OS HSM | S"}, - {488, "Canon EF-S 15-85mm f/3.5-5.6 IS USM"}, - {489, "Canon EF 70-300mm f/4-5.6L IS USM"}, - {490, "Canon EF 8-15mm f/4L Fisheye USM"}, - {491, "Canon EF 300mm f/2.8L IS II USM or Tamron Lens"}, - {491, "Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)"}, - {491, "Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)"}, - {491, "Tamron 100-400mm f/4.5-6.3 Di VC USD (A035)"}, - {491, "Tamron 70-210mm f/4 Di VC USD (A034)"}, - {491, "Tamron 70-210mm f/4 Di VC USD (A034) + 1.4x"}, - {491, "Tamron SP 24-70mm f/2.8 Di VC USD G2 (A032)"}, - {492, "Canon EF 400mm f/2.8L IS II USM"}, - {493, "Canon EF 500mm f/4L IS II USM or EF 24-105mm f4L IS USM"}, - {493, "Canon EF 24-105mm f/4L IS USM"}, - {494, "Canon EF 600mm f/4L IS II USM"}, - {495, "Canon EF 24-70mm f/2.8L II USM or Sigma Lens"}, - {495, "Sigma 24-70mm F2.8 DG OS HSM | A"}, - {496, "Canon EF 200-400mm f/4L IS USM"}, - {499, "Canon EF 200-400mm f/4L IS USM + 1.4x"}, - {502, "Canon EF 28mm f/2.8 IS USM or Tamron Lens"}, - {502, "Tamron 35mm f/1.8 Di VC USD (F012)"}, - {503, "Canon EF 24mm f/2.8 IS USM"}, - {504, "Canon EF 24-70mm f/4L IS USM"}, - {505, "Canon EF 35mm f/2 IS USM"}, - {506, "Canon EF 400mm f/4 DO IS II USM"}, - {507, "Canon EF 16-35mm f/4L IS USM"}, - {508, "Canon EF 11-24mm f/4L USM or Tamron Lens"}, - {508, "Tamron 10-24mm f/3.5-4.5 Di II VC HLD"}, - {747, "Canon EF 100-400mm f/4.5-5.6L IS II USM or Tamron Lens"}, - {747, "Tamron SP 150-600mm f/5-6.3 Di VC USD G2"}, - {748, "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x or Tamron Lens"}, - {748, "Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 1.4x"}, - {748, "Tamron 70-210mm f/4 Di VC USD (A034) + 2x"}, - {749, "Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 2x"}, - {750, "Canon EF 35mm f/1.4L II USM"}, - {751, "Canon EF 16-35mm f/2.8L III USM"}, - {752, "Canon EF 24-105mm f/4L IS II USM"}, - {753, "Canon EF 85mm f/1.4L IS USM"}, - {754, "Canon EF 70-200mm f/4L IS II USM"}, - {757, "Canon EF 400mm f/2.8L IS III USM"}, - {758, "Canon EF 600mm f/4L IS III USM"}, - {1136, "Sigma 24-70mm f/2.8 DG OS HSM | Art 017"}, - {4142, "Canon EF-S 18-135mm f/3.5-5.6 IS STM"}, - {4143, "Canon EF-M 18-55mm f/3.5-5.6 IS STM or Tamron Lens"}, - {4143, "Tamron 18-200mm f/3.5-6.3 Di III VC"}, - {4144, "Canon EF 40mm f/2.8 STM"}, - {4145, "Canon EF-M 22mm f/2 STM"}, - {4146, "Canon EF-S 18-55mm f/3.5-5.6 IS STM"}, - {4147, "Canon EF-M 11-22mm f/4-5.6 IS STM"}, - {4148, "Canon EF-S 55-250mm f/4-5.6 IS STM"}, - {4149, "Canon EF-M 55-200mm f/4.5-6.3 IS STM"}, - {4150, "Canon EF-S 10-18mm f/4.5-5.6 IS STM"}, - {4152, "Canon EF 24-105mm f/3.5-5.6 IS STM"}, - {4153, "Canon EF-M 15-45mm f/3.5-6.3 IS STM"}, - {4154, "Canon EF-S 24mm f/2.8 STM"}, - {4155, "Canon EF-M 28mm f/3.5 Macro IS STM"}, - {4156, "Canon EF 50mm f/1.8 STM"}, - {4157, "Canon EF-M 18-150mm 1:3.5-6.3 IS STM"}, - {4158, "Canon EF-S 18-55mm f/4-5.6 IS STM"}, - {4159, "Canon EF-M 32mm f/1.4 STM"}, - {4160, "Canon EF-S 35mm f/2.8 Macro IS STM"}, - {36910, "Canon EF 70-300mm f/4-5.6 IS II USM"}, - {36912, "Canon EF-S 18-135mm f/3.5-5.6 IS USM"}, - {61182, "Canon RF 35mm F1.8 Macro IS STM or other Canon RF Lens"}, - {61182, "Canon RF 50mm F1.2 L USM"}, - {61182, "Canon RF 24-105mm F4 L IS USM"}, - {61182, "Canon RF 28-70mm F2 L USM"}, - {61491, "Canon CN-E 14mm T3.1 L F"}, - {61492, "Canon CN-E 24mm T1.5 L F"}, - {61494, "Canon CN-E 85mm T1.3 L F"}, - {61495, "Canon CN-E 135mm T2.2 L F"}, - {61496, "Canon CN-E 35mm T1.5 L F"}, - {65535, "n/a"} - }; - } - - std::string toString (const Tag* t) const override - { - int lensID = t->toInt(); - - it_t r; - size_t nFound = choices.count ( lensID ); - - if (1 == nFound) { - r = choices.find ( lensID ); - return r->second; - } - - Tag *apertureTag = t->getParent()->getRoot()->findTag ("MaxAperture"); - Tag *focalLengthTag = t->getParent()->getRoot()->findTag ("FocalLength"); - Tag *focalLengthMaxTag = t->getParent()->getRoot()->findTag ("LongFocal"); - Tag *focalLengthMinTag = t->getParent()->getRoot()->findTag ("ShortFocal"); - Tag *unitTag = t->getParent()->getRoot()->findTag ("FocalUnits"); - double maxApertureAtFocal = 0.; - double focalLength = 0.; - double focalLengthMin = 0.; - double focalLengthMax = 0.; - - if ( apertureTag ) { - maxApertureAtFocal = pow (2.0, apertureTag->toDouble() / 64.0); - } - - if ( unitTag ) { - double unit = unitTag->toDouble(); - - if ( unit == 0. ) { - unit = 1; - } - - if ( focalLengthTag ) { - focalLength = focalLengthTag->toDouble(); - } - - if ( focalLengthMinTag ) { - focalLengthMin = focalLengthMinTag->toDouble() / unit; - } - - if ( focalLengthMaxTag ) { - focalLengthMax = focalLengthMaxTag->toDouble() / unit; - } - } - - std::ostringstream s; - s << "Unknown "; - - if (focalLengthMin > 0.) { - s << focalLengthMin; - } - - if (focalLengthMax > 0. && focalLengthMax != focalLengthMin) { - s << "-" << focalLengthMax; - } - - if (focalLengthMin > 0.) { - s << "mm"; - } - - s << " (" << lensID << ")"; - - if (0 == nFound) { - return s.str(); - } - - double deltaMin = 1000.; - - std::string bestMatch (s.str()); - std::ostringstream candidates; - - for (r = choices.lower_bound (lensID); r != choices.upper_bound (lensID); r++) { - double a1, a2, f1, f2, dif; - - if ( !extractLensInfo ( r->second, f1, f2, a1, a2) ) { - continue; - } - - if ( f1 == 0. || a1 == 0.) { - continue; - } - - if ( focalLength < f1 - .5 || focalLength > f2 + 0.5 ) { - continue; - } - - if ( focalLengthMin > 0. && fabs (f1 - focalLengthMin) > 0.5 ) { - continue; - } - - if ( focalLengthMax > 0. && fabs (f2 - focalLengthMax) > 0.5 ) { - continue; - } - - if ( maxApertureAtFocal > 0.1) { - double lensAperture; - - if ( maxApertureAtFocal < a1 - 0.15 || maxApertureAtFocal > a2 + 0.15) { - continue; - } - - if ( a1 == a2 || f1 == f2) { - lensAperture = a1; - } else { - lensAperture = exp ( log (a1) + (log (a2) - log (a1)) / (log (f2) - log (f1)) * (log (focalLength) - log (f1)) ); - } - - dif = abs (lensAperture - maxApertureAtFocal); - } else { - dif = 0; - } - - if ( dif < deltaMin ) { - deltaMin = dif; - bestMatch = r->second; - } - - if ( dif < 0.15) { - if ( candidates.tellp() ) { - candidates << "\n or " << r->second; - } else { - candidates << r->second; - } - } - - } - - if ( !candidates.tellp() ) { - return bestMatch; - } else { - return candidates.str(); - } - } -}; -CALensInterpreter caLensInterpreter; - -class CAFocalTypeInterpreter : public ChoiceInterpreter<> -{ -public: - CAFocalTypeInterpreter() - { - choices[0] = "Fixed"; - choices[1] = "Fixed"; - choices[2] = "Zoom"; - } -}; -CAFocalTypeInterpreter caFocalTypeInterpreter; - -class CAFocalPlaneInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - int val = t->toInt(); - - if ( val < 40 ) { - return "undef"; - } - - char buffer[32]; - sprintf (buffer, "%.2fmm", val * 25.4 / 1000); - return buffer; - } -}; -CAFocalPlaneInterpreter caFocalPlaneInterpreter; - -class CAExposureTimeInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - char buffer[32]; - double d = pow (2, - t->toInt() / 32.0); - sprintf (buffer, "%.3f", d); - return buffer; - } -}; -CAExposureTimeInterpreter caExposureTimeInterpreter; - -class CAEVInterpreter : public Interpreter -{ - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%.1f", t->toDouble() / 32.0 ); - return buffer; - } -}; -CAEVInterpreter caEVInterpreter; - -class CABaseISOInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - char buffer[32]; - int a = t->toInt(); - sprintf (buffer, "%d", a); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = Interpreter::toInt (t, ofs); - - if (a > 1) { - double i = pow (2., double (a) / 32. - 4.) * 50.; - return i; - } else { - return 0.; - } - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - int a = Interpreter::toInt (t, ofs, astype); - - if (a > 1) { - int i = int (double (powf (2.f, float (a) / 32.f - 4.f)) * 50.f + 0.5f); - return i; - } else { - return 0; - } - } -}; -CABaseISOInterpreter caBaseISOInterpreter; - -class CAToneCurveInterpreter : public ChoiceInterpreter<> -{ -public: - CAToneCurveInterpreter() - { - choices[0] = "Standard"; - choices[1] = "Manual"; - choices[2] = "Custom"; - } -}; -CAToneCurveInterpreter caToneCurveInterpreter; - -class CASharpnessFrequencyInterpreter : public ChoiceInterpreter<> -{ -public: - CASharpnessFrequencyInterpreter() - { - choices[0] = "N/A"; - choices[1] = "Lowest"; - choices[2] = "Low"; - choices[3] = "Standard"; - choices[4] = "High"; - choices[5] = "Highest"; - } -}; -CASharpnessFrequencyInterpreter caSharpnessFrequencyInterpreter; - -class CAWhiteBalanceInterpreter : public ChoiceInterpreter<> -{ -public: - CAWhiteBalanceInterpreter() - { - choices[0] = "Auto"; - choices[1] = "Daylight"; - choices[2] = "Cloudy"; - choices[3] = "Tungsten"; - choices[4] = "Fluorescent"; - choices[5] = "Flash"; - choices[6] = "Custom"; - choices[7] = "Black & White"; - choices[8] = "Shade"; - choices[9] = "Manual Temperature (Kelvin)"; - choices[10] = "PC Set1"; - choices[11] = "PC Set2"; - choices[12] = "PC Set3"; - choices[14] = "Daylight Fluorescent"; - choices[15] = "Custom 1"; - choices[16] = "Custom 2"; - choices[17] = "Underwater"; - choices[18] = "Custom 3"; - choices[19] = "Custom 4"; - choices[20] = "PC Set4"; - choices[21] = "PC Set5"; - choices[23] = "Auto (ambience priority)"; - } -}; -CAWhiteBalanceInterpreter caWhiteBalanceInterpreter; - -class CAPictureStyleInterpreter : public ChoiceInterpreter<> -{ -public: - CAPictureStyleInterpreter() - { - choices[0] = "None"; - choices[1] = "Standard"; - choices[2] = "Portrait"; - choices[3] = "High Saturation"; - choices[4] = "Adobe RGB"; - choices[5] = "Low Saturation"; - choices[6] = "CM Set 1"; - choices[7] = "CM Set 2"; - choices[0x21] = "User Def. 1"; - choices[0x22] = "User Def. 2"; - choices[0x23] = "User Def. 3"; - choices[0x41] = "PC 1"; - choices[0x42] = "PC 2"; - choices[0x43] = "PC 3"; - choices[0x81] = "Standard"; - choices[0x82] = "Portrait"; - choices[0x83] = "Landscape"; - choices[0x84] = "Neutral"; - choices[0x85] = "Faithful"; - choices[0x86] = "Monochrome"; - choices[0x87] = "Auto"; - choices[0x88] = "Fine Detail"; - } -}; -CAPictureStyleInterpreter caPictureStyleInterpreter; - -class CASlowShutterInterpreter : public ChoiceInterpreter<> -{ -public: - CASlowShutterInterpreter() - { - choices[0] = "Off"; - choices[1] = "Night Scene"; - choices[2] = "On"; - choices[3] = "None"; - } -}; -CASlowShutterInterpreter caSlowShutterInterpreter; - -class CAFlashGuideNumberInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - int n = t->toInt(); - - if ( n == -1) { - return "undef"; - } - - char buffer[32]; - sprintf (buffer, "%.0f", n / 32. ); - return buffer; - } -}; -CAFlashGuideNumberInterpreter caFlashGuideNumberInterpreter; - -class CAAFPointsInFocusInterpreter : public ChoiceInterpreter<> -{ -public: - CAAFPointsInFocusInterpreter() - { - choices[0x3000] = "None (MF)"; - choices[0x3001] = "Right"; - choices[0x3002] = "Center"; - choices[0x3003] = "Center+Right"; - choices[0x3004] = "Left"; - choices[0x3005] = "Left+Right"; - choices[0x3006] = "Left+Center"; - choices[0x3007] = "All"; - } -}; -CAAFPointsInFocusInterpreter caAFPointsInFocusInterpreter; - -class CAAutoExposureBracketingInterpreter : public ChoiceInterpreter -{ -public: - CAAutoExposureBracketingInterpreter() - { - choices[-1] = "On "; - choices[0] = "Off "; - choices[1] = "On (shot 1)"; - choices[2] = "On (shot 2)"; - choices[3] = "On (shot 3)"; - } -}; -CAAutoExposureBracketingInterpreter caAutoExposureBracketingInterpreter; - -class CAControModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAControModeInterpreter() - { - choices[0] = "n/a"; - choices[1] = "Camera Local Control"; - choices[3] = "Computer Remote Control"; - } -}; -CAControModeInterpreter caControModeInterpreter; - -class CAFocusDistanceInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%.2f", t->toDouble() / 100 ); - return buffer; - } -}; -CAFocusDistanceInterpreter caFocusDistanceInterpreter; - -class CAMeasuredEVInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%.1f", t->toDouble() / 8 - 6 ); - return buffer; - } -}; -CAMeasuredEVInterpreter caMeasuredEVInterpreter; - -class CACameraTypeInterpreter : public ChoiceInterpreter<> -{ -public: - CACameraTypeInterpreter() - { - choices[248] = "EOS High-end"; - choices[250] = "Compact"; - choices[252] = "EOS Mid-range"; - choices[255] = "DV Camera"; - } -}; -CACameraTypeInterpreter caCameraTypeInterpreter; - -class CAAutoRotateInterpreter : public ChoiceInterpreter -{ -public: - CAAutoRotateInterpreter() - { - choices[-1] = "Rotated by Software"; - choices[0] = "None"; - choices[1] = "Rotate 90 CW"; - choices[2] = "Rotate 180"; - choices[3] = "Rotate 270 CW"; - } -}; -CAAutoRotateInterpreter caAutoRotateInterpreter; - -class CABracketModeInterpreter : public ChoiceInterpreter<> -{ -public: - CABracketModeInterpreter() - { - choices[0] = "Off"; - choices[1] = "AEB"; - choices[2] = "FEB"; - choices[3] = "ISO"; - choices[4] = "WB"; - } -}; -CABracketModeInterpreter caBracketModeInterpreter; - -class CARAWJpegQualityInterpreter : public ChoiceInterpreter<> -{ -public: - CARAWJpegQualityInterpreter() - { - choices[1] = "Economy"; - choices[2] = "Normal"; - choices[3] = "Fine"; - choices[4] = "RAW"; - choices[5] = "Superfine"; - choices[130] = "Normal Movie"; - choices[131] = "Movie (2)"; - } -}; -CARAWJpegQualityInterpreter caRAWJpegQualityInterpreter; - -class CAJpegSizeInterpreter : public ChoiceInterpreter<> -{ -public: - CAJpegSizeInterpreter() - { - choices[0] = "Large"; - choices[1] = "Medium"; - choices[2] = "Small"; - choices[5] = "Medium 1"; - choices[6] = "Medium 2"; - choices[7] = "Medium 3"; - choices[8] = "Postcard"; - choices[9] = "Widescreen"; - choices[10] = "Medium Widescreen"; - choices[14] = "Small 1"; - choices[15] = "Small 2"; - choices[16] = "Small 3"; - choices[128] = "640x480 Movie"; - choices[129] = "Medium Movie"; - choices[130] = "Small Movie"; - choices[137] = "1280x720 Movie"; - choices[142] = "1920x1080 Movie"; - } -}; -CAJpegSizeInterpreter caJpegSizeInterpreter; - -class CAWBBracketModeInterpreter : public ChoiceInterpreter<> -{ -public: - CAWBBracketModeInterpreter() - { - choices[0] = "Off"; - choices[1] = "On (shift AB)"; - choices[2] = "On (shift GM)"; - } -}; -CAWBBracketModeInterpreter caWBBracketModeInterpreter; - -class CAFilterEffectInterpreter : public ChoiceInterpreter<> -{ -public: - CAFilterEffectInterpreter() - { - choices[0] = "None"; - choices[1] = "Yellow"; - choices[2] = "Orange"; - choices[3] = "Red"; - choices[4] = "Green"; - } -}; -CAFilterEffectInterpreter caFilterEffectInterpreter; - -class CAToningEffectInterpreter : public ChoiceInterpreter<> -{ -public: - CAToningEffectInterpreter() - { - choices[0] = "None"; - choices[1] = "Sepia"; - choices[2] = "Blue"; - choices[3] = "Purple"; - choices[4] = "Green"; - } -}; -CAToningEffectInterpreter caToningEffectInterpreter; - -class CAFileNumberInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - unsigned long val = t->toInt (0, LONG); - char buffer[32]; - sprintf (buffer, "%ld", ((val & 0xffc0) >> 6) * 10000 + ((val >> 16) & 0xff) + ((val & 0x3f) << 8) ); - return buffer; - } -}; -CAFileNumberInterpreter caFileNumberInterpreter; - -// CanonModelID -class CAModelIDInterpreter : public ChoiceInterpreter<> -{ -public: - CAModelIDInterpreter () - { - choices[1042] = "EOS M50 / Kiss M"; - choices[2049] = "PowerShot SX740 HS"; - choices[2053] = "PowerShot SX70 HS"; - choices[16842752] = "PowerShot A30"; - choices[17039360] = "PowerShot S300 / Digital IXUS 300 / IXY Digital 300"; - choices[17170432] = "PowerShot A20"; - choices[17301504] = "PowerShot A10"; - choices[17367040] = "PowerShot S110 / Digital IXUS v / IXY Digital 200"; - choices[17825792] = "PowerShot G2"; - choices[17891328] = "PowerShot S40"; - choices[17956864] = "PowerShot S30"; - choices[18022400] = "PowerShot A40"; - choices[18087936] = "EOS D30"; - choices[18153472] = "PowerShot A100"; - choices[18219008] = "PowerShot S200 / Digital IXUS v2 / IXY Digital 200a"; - choices[18284544] = "PowerShot A200"; - choices[18350080] = "PowerShot S330 / Digital IXUS 330 / IXY Digital 300a"; - choices[18415616] = "PowerShot G3"; - choices[18939904] = "PowerShot S45"; - choices[19070976] = "PowerShot SD100 / Digital IXUS II / IXY Digital 30"; - choices[19136512] = "PowerShot S230 / Digital IXUS v3 / IXY Digital 320"; - choices[19202048] = "PowerShot A70"; - choices[19267584] = "PowerShot A60"; - choices[19333120] = "PowerShot S400 / Digital IXUS 400 / IXY Digital 400"; - choices[19464192] = "PowerShot G5"; - choices[19922944] = "PowerShot A300"; - choices[19988480] = "PowerShot S50"; - choices[20185088] = "PowerShot A80"; - choices[20250624] = "PowerShot SD10 / Digital IXUS i / IXY Digital L"; - choices[20316160] = "PowerShot S1 IS"; - choices[20381696] = "PowerShot Pro1"; - choices[20447232] = "PowerShot S70"; - choices[20512768] = "PowerShot S60"; - choices[20971520] = "PowerShot G6"; - choices[21037056] = "PowerShot S500 / Digital IXUS 500 / IXY Digital 500"; - choices[21102592] = "PowerShot A75"; - choices[21233664] = "PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a"; - choices[21299200] = "PowerShot A400"; - choices[21430272] = "PowerShot A310"; - choices[21561344] = "PowerShot A85"; - choices[22151168] = "PowerShot S410 / Digital IXUS 430 / IXY Digital 450"; - choices[22216704] = "PowerShot A95"; - choices[22282240] = "PowerShot SD300 / Digital IXUS 40 / IXY Digital 50"; - choices[22347776] = "PowerShot SD200 / Digital IXUS 30 / IXY Digital 40"; - choices[22413312] = "PowerShot A520"; - choices[22478848] = "PowerShot A510"; - choices[22609920] = "PowerShot SD20 / Digital IXUS i5 / IXY Digital L2"; - choices[23330816] = "PowerShot S2 IS"; - choices[23396352] = "PowerShot SD430 / Digital IXUS Wireless / IXY Digital Wireless"; - choices[23461888] = "PowerShot SD500 / Digital IXUS 700 / IXY Digital 600"; - choices[23494656] = "EOS D60"; - choices[24117248] = "PowerShot SD30 / Digital IXUS i Zoom / IXY Digital L3"; - choices[24379392] = "PowerShot A430"; - choices[24444928] = "PowerShot A410"; - choices[24510464] = "PowerShot S80"; - choices[24641536] = "PowerShot A620"; - choices[24707072] = "PowerShot A610"; - choices[25165824] = "PowerShot SD630 / Digital IXUS 65 / IXY Digital 80"; - choices[25231360] = "PowerShot SD450 / Digital IXUS 55 / IXY Digital 60"; - choices[25296896] = "PowerShot TX1"; - choices[25624576] = "PowerShot SD400 / Digital IXUS 50 / IXY Digital 55"; - choices[25690112] = "PowerShot A420"; - choices[25755648] = "PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000"; - choices[26214400] = "PowerShot SD550 / Digital IXUS 750 / IXY Digital 700"; - choices[26345472] = "PowerShot A700"; - choices[26476544] = "PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS"; - choices[26542080] = "PowerShot S3 IS"; - choices[26607616] = "PowerShot A540"; - choices[26673152] = "PowerShot SD600 / Digital IXUS 60 / IXY Digital 70"; - choices[26738688] = "PowerShot G7"; - choices[26804224] = "PowerShot A530"; - choices[33554432] = "PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS"; - choices[33619968] = "PowerShot SD40 / Digital IXUS i7 / IXY Digital L4"; - choices[33685504] = "PowerShot A710 IS"; - choices[33751040] = "PowerShot A640"; - choices[33816576] = "PowerShot A630"; - choices[34144256] = "PowerShot S5 IS"; - choices[34603008] = "PowerShot A460"; - choices[34734080] = "PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS"; - choices[34799616] = "PowerShot A570 IS"; - choices[34865152] = "PowerShot A560"; - choices[34930688] = "PowerShot SD750 / Digital IXUS 75 / IXY Digital 90"; - choices[34996224] = "PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10"; - choices[35127296] = "PowerShot A550"; - choices[35192832] = "PowerShot A450"; - choices[35848192] = "PowerShot G9"; - choices[35913728] = "PowerShot A650 IS"; - choices[36044800] = "PowerShot A720 IS"; - choices[36241408] = "PowerShot SX100 IS"; - choices[36700160] = "PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS"; - choices[36765696] = "PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS"; - choices[36831232] = "PowerShot SD890 IS / Digital IXUS 970 IS / IXY Digital 820 IS"; - choices[37093376] = "PowerShot SD790 IS / Digital IXUS 90 IS / IXY Digital 95 IS"; - choices[37158912] = "PowerShot SD770 IS / Digital IXUS 85 IS / IXY Digital 25 IS"; - choices[37224448] = "PowerShot A590 IS"; - choices[37289984] = "PowerShot A580"; - choices[37879808] = "PowerShot A470"; - choices[37945344] = "PowerShot SD1100 IS / Digital IXUS 80 IS / IXY Digital 20 IS"; - choices[38141952] = "PowerShot SX1 IS"; - choices[38207488] = "PowerShot SX10 IS"; - choices[38273024] = "PowerShot A1000 IS"; - choices[38338560] = "PowerShot G10"; - choices[38862848] = "PowerShot A2000 IS"; - choices[38928384] = "PowerShot SX110 IS"; - choices[38993920] = "PowerShot SD990 IS / Digital IXUS 980 IS / IXY Digital 3000 IS"; - choices[39059456] = "PowerShot SD880 IS / Digital IXUS 870 IS / IXY Digital 920 IS"; - choices[39124992] = "PowerShot E1"; - choices[39190528] = "PowerShot D10"; - choices[39256064] = "PowerShot SD960 IS / Digital IXUS 110 IS / IXY Digital 510 IS"; - choices[39321600] = "PowerShot A2100 IS"; - choices[39387136] = "PowerShot A480"; - choices[39845888] = "PowerShot SX200 IS"; - choices[39911424] = "PowerShot SD970 IS / Digital IXUS 990 IS / IXY Digital 830 IS"; - choices[39976960] = "PowerShot SD780 IS / Digital IXUS 100 IS / IXY Digital 210 IS"; - choices[40042496] = "PowerShot A1100 IS"; - choices[40108032] = "PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS"; - choices[40894464] = "PowerShot G11"; - choices[40960000] = "PowerShot SX120 IS"; - choices[41025536] = "PowerShot S90"; - choices[41222144] = "PowerShot SX20 IS"; - choices[41287680] = "PowerShot SD980 IS / Digital IXUS 200 IS / IXY Digital 930 IS"; - choices[41353216] = "PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS"; - choices[41943040] = "PowerShot A495"; - choices[42008576] = "PowerShot A490"; - choices[42074112] = "PowerShot A3100/A3150 IS"; - choices[42139648] = "PowerShot A3000 IS"; - choices[42205184] = "PowerShot SD1400 IS / IXUS 130 / IXY 400F"; - choices[42270720] = "PowerShot SD1300 IS / IXUS 105 / IXY 200F"; - choices[42336256] = "PowerShot SD3500 IS / IXUS 210 / IXY 10S"; - choices[42401792] = "PowerShot SX210 IS"; - choices[42467328] = "PowerShot SD4000 IS / IXUS 300 HS / IXY 30S"; - choices[42532864] = "PowerShot SD4500 IS / IXUS 1000 HS / IXY 50S"; - choices[43122688] = "PowerShot G12"; - choices[43188224] = "PowerShot SX30 IS"; - choices[43253760] = "PowerShot SX130 IS"; - choices[43319296] = "PowerShot S95"; - choices[43515904] = "PowerShot A3300 IS"; - choices[43581440] = "PowerShot A3200 IS"; - choices[50331648] = "PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31S"; - choices[50397184] = "PowerShot Pro90 IS"; - choices[50397185] = "PowerShot A800"; - choices[50462720] = "PowerShot ELPH 100 HS / IXUS 115 HS / IXY 210F"; - choices[50528256] = "PowerShot SX230 HS"; - choices[50593792] = "PowerShot ELPH 300 HS / IXUS 220 HS / IXY 410F"; - choices[50659328] = "PowerShot A2200"; - choices[50724864] = "PowerShot A1200"; - choices[50790400] = "PowerShot SX220 HS"; - choices[50855936] = "PowerShot G1 X"; - choices[50921472] = "PowerShot SX150 IS"; - choices[51380224] = "PowerShot ELPH 510 HS / IXUS 1100 HS / IXY 51S"; - choices[51445760] = "PowerShot S100 (new)"; - choices[51511296] = "PowerShot ELPH 310 HS / IXUS 230 HS / IXY 600F"; - choices[51576832] = "PowerShot SX40 HS"; - choices[51642368] = "IXY 32S"; - choices[51773440] = "PowerShot A1300"; - choices[51838976] = "PowerShot A810"; - choices[51904512] = "PowerShot ELPH 320 HS / IXUS 240 HS / IXY 420F"; - choices[51970048] = "PowerShot ELPH 110 HS / IXUS 125 HS / IXY 220F"; - choices[52428800] = "PowerShot D20"; - choices[52494336] = "PowerShot A4000 IS"; - choices[52559872] = "PowerShot SX260 HS"; - choices[52625408] = "PowerShot SX240 HS"; - choices[52690944] = "PowerShot ELPH 530 HS / IXUS 510 HS / IXY 1"; - choices[52756480] = "PowerShot ELPH 520 HS / IXUS 500 HS / IXY 3"; - choices[52822016] = "PowerShot A3400 IS"; - choices[52887552] = "PowerShot A2400 IS"; - choices[52953088] = "PowerShot A2300"; - choices[53673984] = "PowerShot G15"; - choices[53739520] = "PowerShot SX50 HS"; - choices[53805056] = "PowerShot SX160 IS"; - choices[53870592] = "PowerShot S110 (new)"; - choices[53936128] = "PowerShot SX500 IS"; - choices[54001664] = "PowerShot N"; - choices[54067200] = "IXUS 245 HS / IXY 430F"; - choices[54525952] = "PowerShot SX280 HS"; - choices[54591488] = "PowerShot SX270 HS"; - choices[54657024] = "PowerShot A3500 IS"; - choices[54722560] = "PowerShot A2600"; - choices[54788096] = "PowerShot SX275 HS"; - choices[54853632] = "PowerShot A1400"; - choices[54919168] = "PowerShot ELPH 130 IS / IXUS 140 / IXY 110F"; - choices[54984704] = "PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F"; - choices[55115776] = "PowerShot ELPH 330 HS / IXUS 255 HS / IXY 610F"; - choices[55640064] = "PowerShot A2500"; - choices[55836672] = "PowerShot G16"; - choices[55902208] = "PowerShot S120"; - choices[55967744] = "PowerShot SX170 IS"; - choices[56098816] = "PowerShot SX510 HS"; - choices[56164352] = "PowerShot S200 (new)"; - choices[56623104] = "IXY 620F"; - choices[56688640] = "PowerShot N100"; - choices[56885248] = "PowerShot G1 X Mark II"; - choices[56950784] = "PowerShot D30"; - choices[57016320] = "PowerShot SX700 HS"; - choices[57081856] = "PowerShot SX600 HS"; - choices[57147392] = "PowerShot ELPH 140 IS / IXUS 150 / IXY 130"; - choices[57212928] = "PowerShot ELPH 135 / IXUS 145 / IXY 120"; - choices[57671680] = "PowerShot ELPH 340 HS / IXUS 265 HS / IXY 630"; - choices[57737216] = "PowerShot ELPH 150 IS / IXUS 155 / IXY 140"; - choices[57933824] = "EOS M3"; - choices[57999360] = "PowerShot SX60 HS"; - choices[58064896] = "PowerShot SX520 HS"; - choices[58130432] = "PowerShot SX400 IS"; - choices[58195968] = "PowerShot G7 X"; - choices[58261504] = "PowerShot N2"; - choices[58720256] = "PowerShot SX530 HS"; - choices[58851328] = "PowerShot SX710 HS"; - choices[58916864] = "PowerShot SX610 HS"; - choices[58982400] = "EOS M10"; - choices[59047936] = "PowerShot G3 X"; - choices[59113472] = "PowerShot ELPH 165 HS / IXUS 165 / IXY 160"; - choices[59179008] = "PowerShot ELPH 160 / IXUS 160"; - choices[59244544] = "PowerShot ELPH 350 HS / IXUS 275 HS / IXY 640"; - choices[59310080] = "PowerShot ELPH 170 IS / IXUS 170"; - choices[59834368] = "PowerShot SX410 IS"; - choices[59965440] = "PowerShot G9 X"; - choices[60030976] = "EOS M5"; - choices[60096512] = "PowerShot G5 X"; - choices[60227584] = "PowerShot G7 X Mark II"; - choices[60293120] = "EOS M100"; - choices[60358656] = "PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650"; - choices[67174400] = "PowerShot SX540 HS"; - choices[67239936] = "PowerShot SX420 IS"; - choices[67305472] = "PowerShot ELPH 190 IS / IXUS 180 / IXY 190"; - choices[67371008] = "PowerShot G1"; - choices[67371009] = "IXY 180"; - choices[67436544] = "PowerShot SX720 HS"; - choices[67502080] = "PowerShot SX620 HS"; - choices[67567616] = "EOS M6"; - choices[68157440] = "PowerShot G9 X Mark II"; - choices[68485120] = "PowerShot ELPH 185 / IXUS 185 / IXY 200"; - choices[68550656] = "PowerShot SX430 IS"; - choices[68616192] = "PowerShot SX730 HS"; - choices[68681728] = "PowerShot G1 X Mark III"; - choices[100925440] = "PowerShot S100 / Digital IXUS / IXY Digital"; - choices[1074255475] = "DC19/DC21/DC22"; - choices[1074255476] = "XH A1"; - choices[1074255477] = "HV10"; - choices[1074255478] = "MD130/MD140/MD150/MD160/ZR850"; - choices[1074255735] = "DC50"; - choices[1074255736] = "HV20"; - choices[1074255737] = "DC211"; - choices[1074255738] = "HG10"; - choices[1074255739] = "HR10"; - choices[1074255741] = "MD255/ZR950"; - choices[1074255900] = "HF11"; - choices[1074255992] = "HV30"; - choices[1074255996] = "XH A1S"; - choices[1074255998] = "DC301/DC310/DC311/DC320/DC330"; - choices[1074255999] = "FS100"; - choices[1074256000] = "HF10"; - choices[1074256002] = "HG20/HG21"; - choices[1074256165] = "HF21"; - choices[1074256166] = "HF S11"; - choices[1074256248] = "HV40"; - choices[1074256263] = "DC410/DC411/DC420"; - choices[1074256264] = "FS19/FS20/FS21/FS22/FS200"; - choices[1074256265] = "HF20/HF200"; - choices[1074256266] = "HF S10/S100"; - choices[1074256526] = "HF R10/R16/R17/R18/R100/R106"; - choices[1074256527] = "HF M30/M31/M36/M300/M306"; - choices[1074256528] = "HF S20/S21/S200"; - choices[1074256530] = "FS31/FS36/FS37/FS300/FS305/FS306/FS307"; - choices[1074257056] = "EOS C300"; - choices[1074257321] = "HF G25"; - choices[1074257844] = "XC10"; - choices[1074258371] = "EOS C200"; - choices[2147483649] = "EOS-1D"; - choices[2147484007] = "EOS-1DS"; - choices[2147484008] = "EOS 10D"; - choices[2147484009] = "EOS-1D Mark III"; - choices[2147484016] = "EOS Digital Rebel / 300D / Kiss Digital"; - choices[2147484020] = "EOS-1D Mark II"; - choices[2147484021] = "EOS 20D"; - choices[2147484022] = "EOS Digital Rebel XSi / 450D / Kiss X2"; - choices[2147484040] = "EOS-1Ds Mark II"; - choices[2147484041] = "EOS Digital Rebel XT / 350D / Kiss Digital N"; - choices[2147484048] = "EOS 40D"; - choices[2147484179] = "EOS 5D"; - choices[2147484181] = "EOS-1Ds Mark III"; - choices[2147484184] = "EOS 5D Mark II"; - choices[2147484185] = "WFT-E1"; - choices[2147484210] = "EOS-1D Mark II N"; - choices[2147484212] = "EOS 30D"; - choices[2147484214] = "EOS Digital Rebel XTi / 400D / Kiss Digital X"; - choices[2147484225] = "WFT-E2"; - choices[2147484230] = "WFT-E3"; - choices[2147484240] = "EOS 7D"; - choices[2147484242] = "EOS Rebel T1i / 500D / Kiss X3"; - choices[2147484244] = "EOS Rebel XS / 1000D / Kiss F"; - choices[2147484257] = "EOS 50D"; - choices[2147484265] = "EOS-1D X"; - choices[2147484272] = "EOS Rebel T2i / 550D / Kiss X4"; - choices[2147484273] = "WFT-E4"; - choices[2147484275] = "WFT-E5"; - choices[2147484289] = "EOS-1D Mark IV"; - choices[2147484293] = "EOS 5D Mark III"; - choices[2147484294] = "EOS Rebel T3i / 600D / Kiss X5"; - choices[2147484295] = "EOS 60D"; - choices[2147484296] = "EOS Rebel T3 / 1100D / Kiss X50"; - choices[2147484297] = "EOS 7D Mark II"; - choices[2147484311] = "WFT-E2 II"; - choices[2147484312] = "WFT-E4 II"; - choices[2147484417] = "EOS Rebel T4i / 650D / Kiss X6i"; - choices[2147484418] = "EOS 6D"; - choices[2147484452] = "EOS-1D C"; - choices[2147484453] = "EOS 70D"; - choices[2147484454] = "EOS Rebel T5i / 700D / Kiss X7i"; - choices[2147484455] = "EOS Rebel T5 / 1200D / Kiss X70 / Hi"; - choices[2147484456] = "EOS-1D X MARK II"; - choices[2147484465] = "EOS M"; - choices[2147484486] = "EOS Rebel SL1 / 100D / Kiss X7"; - choices[2147484487] = "EOS Rebel T6s / 760D / 8000D"; - choices[2147484489] = "EOS 5D Mark IV"; - choices[2147484496] = "EOS 80D"; - choices[2147484501] = "EOS M2"; - choices[2147484546] = "EOS 5DS"; - choices[2147484563] = "EOS Rebel T6i / 750D / Kiss X8i"; - choices[2147484673] = "EOS 5DS R"; - choices[2147484676] = "EOS Rebel T6 / 1300D / Kiss X80"; - choices[2147484677] = "EOS Rebel T7i / 800D / Kiss X9i"; - choices[2147484678] = "EOS 6D Mark II"; - choices[2147484680] = "EOS 77D / 9000D"; - choices[2147484695] = "EOS Rebel SL2 / 200D / Kiss X9"; - choices[2147484706] = "EOS Rebel T100 / 4000D / 3000D"; - choices[2147484708] = "EOR R"; - choices[2147484722] = "EOS Rebel T7 / 2000D / 1500D / Kiss X90"; - } -}; -CAModelIDInterpreter caModelIDInterpreter; - -class CAPanoramaDirectionInterpreter : public ChoiceInterpreter<> -{ -public: - CAPanoramaDirectionInterpreter() - { - choices[0] = "Left to Right"; - choices[1] = "Right to Left"; - choices[2] = "Bottom to Top"; - choices[3] = "Top to Bottom"; - choices[4] = "2x2 Matrix (Clockwise)"; - } -}; -CAPanoramaDirectionInterpreter caPanoramaDirectionInterpreter; - -class CAAspectRatioInterpreter : public ChoiceInterpreter<> -{ -public: - CAAspectRatioInterpreter() - { - choices[0] = "3:2"; - choices[1] = "1:1"; - choices[2] = "4:3"; - choices[7] = "16:9"; - choices[8] = "4:5"; - } - -}; -CAAspectRatioInterpreter caAspectRatioInterpreter; - -const TagAttrib canonCameraSettingsAttribs[] = { - {0, AC_WRITE, 0, nullptr, 1, AUTO, "MacroMode", &caMacroModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "SelfTimer", &caSelfTimerInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "Quality", &caQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "CanonFlashMode", &caFlashModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "ContinuousDrive", &caContinuousDriveInterpreter}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "FocusMode", &caFocusModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "RecordMode", &caRecordModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "CanonImageSize", &caImageSizeInterpreter}, - {0, AC_WRITE, 0, nullptr, 11, AUTO, "EasyMode", &caEasyModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 12, AUTO, "DigitalZoom", &caDigitalZoomInterpreter}, - {0, AC_WRITE, 0, nullptr, 13, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 14, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "CameraISO", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "MeteringMode", &caMeteringModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "FocusRange", &caFocusRangeInterpreter}, - {0, AC_WRITE, 0, nullptr, 19, AUTO, "AFPoint", &caAFPointInterpreter}, - {0, AC_WRITE, 0, nullptr, 20, AUTO, "CanonExposureMode", &caExposureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 22, AUTO, "LensID", &caLensInterpreter}, - {0, AC_WRITE, 0, nullptr, 23, AUTO, "LongFocal", &caFocalInterpreter}, - {0, AC_WRITE, 0, nullptr, 24, AUTO, "ShortFocal", &caFocalInterpreter}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "FocalUnits", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 26, AUTO, "MaxAperture", &caApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 27, AUTO, "MinAperture", &caApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 28, AUTO, "FlashActivity", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 29, AUTO, "FlashBits", &caFlashBitsInterpreter}, - {0, AC_WRITE, 0, nullptr, 32, AUTO, "FocusContinuous", &caFocusContinuousInterpreter}, - {0, AC_WRITE, 0, nullptr, 33, AUTO, "AESetting", &caAESettingsInterpreter}, - {0, AC_WRITE, 0, nullptr, 34, AUTO, "ImageStabilization", &caStabilizationInterpreter}, - {0, AC_WRITE, 0, nullptr, 35, AUTO, "DisplayAperture", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 36, AUTO, "ZoomSourceWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 37, AUTO, "ZoomTargetWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 39, AUTO, "SpotMeteringMode", &caSpotMeteringInterpreter}, - {0, AC_WRITE, 0, nullptr, 40, AUTO, "PhotoEffect", &caPhotoEffectInterpreter}, - {0, AC_WRITE, 0, nullptr, 41, AUTO, "ManualFlashOutput", &caManualFlashInterpreter}, - {0, AC_WRITE, 0, nullptr, 42, AUTO, "ColorTone", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 46, AUTO, "SRAWQuality", &caRAWQualityInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib canonFocalLengthAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "FocalType", &caFocalTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "FocalLength", &caFocalInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "FocalPlaneXSize", &caFocalPlaneInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "FocalPlaneYSize", &caFocalPlaneInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib canonShotInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 1, AUTO, "AutoISO", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "BaseISO", &caBaseISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "MeasuredEV", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "TargetAperture", &caApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "TargetExposureTime", &caExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "ExposureCompensation", &caEVInterpreter}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "WhiteBalance", &caWhiteBalanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 8, AUTO, "SlowShutter", &caSlowShutterInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "SequenceNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "OpticalZoomCode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 13, AUTO, "FlashGuideNumber", &caFlashGuideNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 14, AUTO, "AFPointsInFocus", &caAFPointsInFocusInterpreter}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "AutoExposureBracketing", &caAutoExposureBracketingInterpreter}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "AEBBracketValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "ControlMode", &caControModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 21, AUTO, "FNumber", &caApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 22, AUTO, "ExposureTime", &caExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 23, AUTO, "MeasuredEV2", &caMeasuredEVInterpreter}, - {0, AC_WRITE, 0, nullptr, 24, AUTO, "BulbDuration", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 26, AUTO, "CameraType", &caCameraTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 27, AUTO, "AutoRotate", &caAutoRotateInterpreter}, - {0, AC_WRITE, 0, nullptr, 28, AUTO, "NDFilter", &caOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 29, AUTO, "Self-timer2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 33, AUTO, "FlashOutput", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonFileInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 1, AUTO, "FileNumber", &caFileNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "BracketMode", &caBracketModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "BracketValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "BracketShotNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "RawJpgQuality", &caRAWJpegQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "RawJpgSize", &caJpegSizeInterpreter}, - {0, AC_WRITE, 0, nullptr, 8, AUTO, "NoiseReduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "WBBracketMode", &caWBBracketModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 12, AUTO, "WBBracketValueAB", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 13, AUTO, "WBBracketValueGM", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 14, AUTO, "FilterEffect", &caFilterEffectInterpreter}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "ToningEffect", &caToningEffectInterpreter}, - {0, AC_WRITE, 0, nullptr, 19, AUTO, "LiveViewShooting", &caOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 20, AUTO, "FocusDistanceUpper", &caFocusDistanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 21, AUTO, "FocusDistanceLower", &caFocusDistanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "FlashExposureLock", &caOnOffInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonProcessingInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ToneCurve", &caToneCurveInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "SharpnessFrequency", &caSharpnessFrequencyInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "SensorRedLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "SensorBlueLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "WhiteBalanceRed", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "WhiteBalanceBlue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 8, AUTO, "WhiteBalance", &caWhiteBalanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "PictureStyle", &caPictureStyleInterpreter}, - {0, AC_WRITE, 0, nullptr, 11, AUTO, "DigitalGain", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 12, AUTO, "WBShiftAB", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 13, AUTO, "WBShiftGM", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonPanoramaInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 2, AUTO, "PanoramaFrameNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "PanoramaDirection", &caPanoramaDirectionInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonCropInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "CropLeftMargin", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "CropRightMargin", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "CropTopMargin", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "CropBottomMargin", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonAspectInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "AspectRatio", &caAspectRatioInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "CroppedImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "CroppedImageHeight", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}, -}; - -const TagAttrib canonMicroAdjustAttrib[] = { - {0, AC_WRITE, 0, nullptr, 1, AUTO, "AFMicroAdjActive", &caOnOffInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 2, AUTO, "", nullptr}, -}; - -const TagAttrib canonAttribs[] = { - {0, AC_WRITE, 0, canonCameraSettingsAttribs, 0x0001, AUTO, "CanonCameraSettings", &stdInterpreter}, - {0, AC_WRITE, 0, canonFocalLengthAttribs, 0x0002, AUTO, "CanonFocalLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "CanonFlashInfo", &stdInterpreter}, - {0, AC_WRITE, 0, canonShotInfoAttribs, 0x0004, AUTO, "CanonShotInfo", &stdInterpreter}, - {0, AC_WRITE, 0, canonPanoramaInfoAttribs, 0x0005, AUTO, "CanonPanorama", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "CanonImageType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "CanonFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0008, AUTO, "FileNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0009, AUTO, "OwnerName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000a, AUTO, "ColorInfoD30", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000c, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000d, AUTO, "CanonCameraInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000e, AUTO, "CanonFileLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "CustomFunctions", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0010, AUTO, "CanonModelID", &caModelIDInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "CanonAFInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0015, AUTO, "SerialNumberFormat", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001c, AUTO, "DateStampMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001d, AUTO, "MyColors", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001e, AUTO, "FirmwareRevision", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x0024, AUTO, "FaceDetect1", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x0025, AUTO, "FaceDetect2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "CanonAFInfo2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0083, AUTO, "OriginalDecisionData", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0090, AUTO, "CustomFunctions1D", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0091, AUTO, "PersonalFunctions", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0092, AUTO, "PersonalFunctionValues", &stdInterpreter}, - {0, AC_WRITE, 0, canonFileInfoAttribs, 0x0093, AUTO, "CanonFileInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0094, AUTO, "AFPointsInFocus1D", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0095, AUTO, "LensType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0096, AUTO, "InternalSerialNumber", &caIntSerNumInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0097, AUTO, "DustRemovalData", &stdInterpreter}, - {0, AC_WRITE, 0, canonCropInfoAttribs, 0x0098, AUTO, "CropInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0099, AUTO, "CustomFunctions2", &stdInterpreter}, - {0, AC_WRITE, 0, canonAspectInfoAttribs, 0x009a, AUTO, "AspectInfo", &stdInterpreter}, - {0, AC_WRITE, 0, canonProcessingInfoAttribs, 0x00a0, AUTO, "ProcessingInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a1, AUTO, "ToneCurveTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a2, AUTO, "SharpnessTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a3, AUTO, "SharpnessFreqTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a4, AUTO, "WhiteBalanceTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a9, AUTO, "ColorBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00aa, AUTO, "MeasuredColor", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00ae, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x00b0, AUTO, "CanonFlags", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b1, AUTO, "ModifiedInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b2, AUTO, "ToneCurveMatching", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b3, AUTO, "WhiteBalanceMatching", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b4, AUTO, "ColorSpace", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x00b6, AUTO, "PreviewImageInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00d0, AUTO, "VRDOffset", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00e0, AUTO, "SensorInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x4001, AUTO, "ColorBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x4002, AUTO, "UnknownBlock1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x4003, AUTO, "ColorInfo", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x4005, AUTO, "UnknownBlock2", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x4008, AUTO, "BlackLevel", &stdInterpreter}, - {1, AC_WRITE, 0, canonMicroAdjustAttrib, 0x4013, AUTO, "AFMicroAdj", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; -} -#endif - diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc deleted file mode 100644 index 2e17a68f9..000000000 --- a/rtexif/fujiattribs.cc +++ /dev/null @@ -1,316 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _FUJIATTRIBS_ -#define _FUJIATTRIBS_ - -#include "rtexif.h" - -namespace rtexif -{ - -class FAOnOffInterpreter : public ChoiceInterpreter<> -{ -public: - FAOnOffInterpreter () - { - choices[0] = "Off"; - choices[1] = "On"; - } -}; -FAOnOffInterpreter faOnOffInterpreter; - -class FASharpnessInterpreter : public ChoiceInterpreter<> -{ -public: - FASharpnessInterpreter () - { - choices[1] = "Soft"; - choices[2] = "Soft2"; - choices[3] = "Normal"; - choices[4] = "Hard"; - choices[5] = "Hard2"; - choices[0x82] = "Medium Soft"; - choices[0x84] = "Medium Hard"; - choices[0x8000] = "Film Simulation"; - choices[0xffff] = "n/a"; - } -}; -FASharpnessInterpreter faSharpnessInterpreter; - -class FAWhiteBalanceInterpreter : public ChoiceInterpreter<> -{ -public: - FAWhiteBalanceInterpreter () - { - choices[0] = "Auto"; - choices[0x100] = "Daylight"; - choices[0x200] = "Cloudy"; - choices[0x300] = "Daylight Fluorescent"; - choices[0x301] = "Day White Fluorescent"; - choices[0x302] = "White Fluorescent"; - choices[0x303] = "Warm White Fluorescent"; - choices[0x304] = "Living Room Warm White Fluorescent"; - choices[0x400] = "Incandescent"; - choices[0x500] = "Flash"; - choices[0x600] = "Underwater"; - choices[0xf00] = "Custom"; - choices[0xf01] = "Custom2"; - choices[0xf02] = "Custom3"; - choices[0xf03] = "Custom4"; - choices[0xf04] = "Custom5"; - choices[0xff0] = "Kelvin"; - } -}; -FAWhiteBalanceInterpreter faWhiteBalanceInterpreter; - -class FASaturationInterpreter : public ChoiceInterpreter<> -{ -public: - FASaturationInterpreter () - { - choices[0] = "Normal"; - choices[128] = "Medium High"; - choices[256] = "High"; - choices[384] = "Medium Low"; - choices[512] = "Low"; - choices[768] = "None (B&W)"; - choices[769] = "B&W Red Filter"; - choices[770] = "B&W Yellow Filter"; - choices[771] = "B&W Green Filter"; - choices[784] = "B&W Sepia"; - choices[1024] = "Low 2"; - choices[1280] = "Acros"; - choices[1281] = "Acros Red Filter"; - choices[1282] = "Acros Yellow Filter"; - choices[1283] = "Acros Green Filter"; - choices[32768] = "Film Simulation"; - } -}; -FASaturationInterpreter faSaturationInterpreter; - -class FAContrastInterpreter : public ChoiceInterpreter<> -{ -public: - FAContrastInterpreter () - { - choices[0] = "Normal"; - choices[0x80] = "Medium High"; - choices[0x100] = "High"; - choices[0x180] = "Medium Low"; - choices[0x200] = "Low"; - choices[0x8000] = "Film Simulation"; - } -}; -FAContrastInterpreter faContrastInterpreter; - -class FAContrast2Interpreter : public ChoiceInterpreter<> -{ -public: - FAContrast2Interpreter () - { - choices[0] = "Normal"; - choices[0x100] = "High"; - choices[0x300] = "Low"; - } -}; -FAContrast2Interpreter faContrast2Interpreter; - -class FANoiseReductionInterpreter : public ChoiceInterpreter<> -{ -public: - FANoiseReductionInterpreter () - { - choices[0x40] = "Low"; - choices[0x80] = "Normal"; - choices[0x100] = "n/a"; - } -}; -FANoiseReductionInterpreter faNoiseReductionInterpreter; - -class FAFlashInterpreter : public ChoiceInterpreter<> -{ -public: - // FujiFlashMode - FAFlashInterpreter () - { - choices[0] = "Auto"; - choices[1] = "On"; - choices[2] = "Off"; - choices[3] = "Red-eye reduction"; - choices[4] = "External"; - } -}; -FAFlashInterpreter faFlashInterpreter; - -class FAFocusModeInterpreter : public ChoiceInterpreter<> -{ -public: - FAFocusModeInterpreter () - { - choices[0] = "Auto"; - choices[1] = "Manual"; - } -}; -FAFocusModeInterpreter faFocusModeInterpreter; - -class FAColorModeInterpreter : public ChoiceInterpreter<> -{ -public: - FAColorModeInterpreter () - { - choices[0] = "Standard"; - choices[0x10] = "Chrome"; - choices[0x30] = "B & W"; - } -}; -FAColorModeInterpreter faColorModeInterpreter; - -class FADynamicRangeInterpreter : public ChoiceInterpreter<> -{ -public: - FADynamicRangeInterpreter () - { - choices[1] = "Standard"; - choices[3] = "Wide"; - } -}; -FADynamicRangeInterpreter faDynamicRangeInterpreter; - -class FAFilmModeInterpreter : public ChoiceInterpreter<> -{ -public: - FAFilmModeInterpreter () - { - choices[0x0] = "F0/Standard (Provia)"; - choices[0x100] = "F1/Studio Portrait"; - choices[0x110] = "F1a/Studio Portrait Enhanced Saturation"; - choices[0x120] = "F1b/Studio Portrait Smooth Skin Tone (Astia)"; - choices[0x130] = "F1c/Studio Portrait Increased Sharpness"; - choices[0x200] = "F2/Fujichrome (Velvia)"; - choices[0x300] = "F3/Studio Portrait Ex"; - choices[0x400] = "F4/Velvia"; - choices[0x500] = "Pro Neg. Std"; - choices[0x501] = "Pro Neg. Hi"; - choices[0x600] = "Classic Chrome"; - } -}; -FAFilmModeInterpreter faFilmModeInterpreter; - -class FADRSettingInterpreter : public ChoiceInterpreter<> -{ -public: - // DynamicRangeSetting - FADRSettingInterpreter () - { - choices[0x0] = "Auto (100-400%)"; - choices[0x1] = "Manual"; - choices[0x100] = "Standard (100%)"; - choices[0x200] = "Wide1 (230%)"; - choices[0x201] = "Wide2 (400%)"; - choices[0x8000] = "Film Simulation"; - } -}; -FADRSettingInterpreter faDRSettingInterpreter; - -class FAPictureModeInterpreter : public ChoiceInterpreter<> -{ -public: - FAPictureModeInterpreter () - { - choices[0x0] = "Auto"; - choices[0x1] = "Portrait"; - choices[0x2] = "Landscape"; - choices[0x3] = "Macro"; - choices[0x4] = "Sports"; - choices[0x5] = "Night Scene"; - choices[0x6] = "Program AE"; - choices[0x7] = "Natural Light"; - choices[0x8] = "Anti-blur"; - choices[0x9] = "Beach & Snow"; - choices[0xa] = "Sunset"; - choices[0xb] = "Museum"; - choices[0xc] = "Party"; - choices[0xd] = "Flower"; - choices[0xe] = "Text"; - choices[0xf] = "Natural Light & Flash"; - choices[0x10] = "Beach"; - choices[0x11] = "Snow"; - choices[0x12] = "Fireworks"; - choices[0x13] = "Underwater"; - choices[0x14] = "Portrait with Skin Correction"; - choices[0x16] = "Panorama"; - choices[0x17] = "Night (tripod)"; - choices[0x18] = "Pro Low-light"; - choices[0x19] = "Pro Focus"; - choices[0x1a] = "Portrait 2"; - choices[0x1b] = "Dog Face Detection"; - choices[0x1c] = "Cat Face Detection"; - choices[0x40] = "Advanced Filter"; - choices[0x100] = "Aperture-priority AE"; - choices[0x200] = "Shutter speed priority AE"; - choices[0x300] = "Manual"; - } -}; -FAPictureModeInterpreter faPictureModeInterpreter; - - - -const TagAttrib fujiAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "Version", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0010, AUTO, "InternalSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1000, AUTO, "Quality", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1001, AUTO, "Sharpness", &faSharpnessInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1002, AUTO, "WhiteBalance", &faWhiteBalanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1003, AUTO, "Saturation", &faSaturationInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1004, AUTO, "Contrast", &faContrastInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1005, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1006, AUTO, "Contrast2", &faContrast2Interpreter}, - {0, AC_WRITE, 0, nullptr, 0x100a, AUTO, "WhiteBalanceFineTune", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100b, AUTO, "NoiseReduction", &faNoiseReductionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1010, AUTO, "FujiFlashMode", &faFlashInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1011, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1020, AUTO, "Macro", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1021, AUTO, "FocusMode", &faFocusModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1023, AUTO, "FocusPixel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1030, AUTO, "SlowSync", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1031, AUTO, "PictureMode", &faPictureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1100, AUTO, "AutoBracketing", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1101, AUTO, "SequenceNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1210, AUTO, "ColorMode", &faColorModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1300, AUTO, "BlurWarning", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1301, AUTO, "FocusWarning", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1302, AUTO, "ExposureWarning", &faOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1400, AUTO, "DynamicRange", &faDynamicRangeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1401, AUTO, "FilmMode", &faFilmModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1402, AUTO, "DynamicRangeSetting", &faDRSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1403, AUTO, "DevelopmentDynamicRange", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1404, AUTO, "MinFocalLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1405, AUTO, "MaxFocalLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1406, AUTO, "MaxApertureAtMinFocal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1407, AUTO, "MaxApertureAtMaxFocal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x140b, AUTO, "AutoDynamicRange", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x4100, AUTO, "FacesDetected", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8000, AUTO, "FileSource", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8002, AUTO, "OrderNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8003, AUTO, "FrameNumber", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; -} -#endif - diff --git a/rtexif/kodakattribs.cc b/rtexif/kodakattribs.cc deleted file mode 100644 index a9c168a70..000000000 --- a/rtexif/kodakattribs.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of RawTherapee. - */ -#ifndef _KODAKATTRIBS_ -#define _KODAKATTRIBS_ - -#include -#include "rtexif.h" - -namespace rtexif -{ - - -void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif_) -{ - // parse TextualInfo and copy values into corresponding standard Exif - if (textualInfo->getType() != ASCII) { - return; - } - - TagDirectory *exif = exif_->getDirectory(); - char *value = (char *)textualInfo->getValue(); - - char *p = value; - char *pc, *plf; - - while ((pc = strchr (p, ':')) != nullptr && (plf = strchr (pc, '\n')) != nullptr) { - while (*p == ' ') { - p++; - } - - size_t len = pc - p; - - while (len > 1 && p[len - 1] == ' ') { - len--; - } - - std::string key = std::string (p, len); - ++pc; - - while (*pc == ' ') { - pc++; - } - - len = plf - pc; - - while (len > 1 && pc[len - 1] == ' ') { - len--; - } - - std::string val = std::string (pc, len); - p = ++plf; - - // we pick out a few select tags here - Tag *t; - - if (key == "Lens") { - // Proback645 may have "Lens" but not "Focal Length" - float flen = atof (val.c_str()); - - if (flen != 0.0) { - t = new Tag (exif, lookupAttrib (exifAttribs, "FocalLength")); - t->initRational (flen * 32, 32); - exif->replaceTag (t); - } - } else if (key == "Focal Length") { - float flen = atof (val.c_str()); - - if (flen != 0.0) { - t = new Tag (exif, lookupAttrib (exifAttribs, "FocalLength")); - t->initRational (flen * 32, 32); - exif->replaceTag (t); - } - } else if (key == "Aperture") { - float aperture = atof (&val.c_str()[1]); - - if (aperture != 0.0) { - t = new Tag (exif, lookupAttrib (exifAttribs, "FNumber")); - t->initRational ((int) (aperture * 10), 10); - exif->replaceTag (t); - } - } else if (key == "Exposure Bias" || key == "Compensation") { - float bias = 0.0; - - if (val != "Off") { - bias = atof (val.c_str()); - } - - t = new Tag (exif, lookupAttrib (exifAttribs, "ExposureBiasValue")); - t->initRational ((int) (bias * 1000), 1000); - exif->replaceTag (t); - } else if (key == "ISO Speed") { - t = new Tag (exif, lookupAttrib (exifAttribs, "ISOSpeedRatings")); - t->initInt (atoi (val.c_str()), SHORT); - exif->replaceTag (t); - } else if (key == "Shutter") { - const char *p1 = strchr (val.c_str(), '/'); - int a, b; - - if (p1 == nullptr) { - a = atoi (val.c_str()); - b = 1; - } else { - a = atoi (val.c_str()); - b = atoi (&p1[1]); - } - t = new Tag (exif, lookupAttrib (exifAttribs, "ExposureTime")); - t->initRational (a, b); - exif->replaceTag (t); - - const float ssv = -log2 ((float)a / std::max((float)b, 0.0001f)); // convert to APEX value, avoid division by zero - t = new Tag (exif, lookupAttrib (exifAttribs, "ShutterSpeedValue")); - t->initRational (1000000 * ssv, 1000000); - exif->replaceTag (t); - } else if (key == "Flash Fired") { - t = new Tag (exif, lookupAttrib (exifAttribs, "Flash")); - - if (val == "No") { - t->initInt (0, SHORT); - } else { - // not sure if "Flash Fired" is only yes/no, only seen "No" in test pictures - t->initInt (1, SHORT); - } - - exif->replaceTag (t); - } else if (key == "White balance") { // yes should be small 'b' int 'balance'. - t = new Tag (exif, lookupAttrib (exifAttribs, "Flash")); - t->initInt ((val == "Auto") ? 0 : 1, SHORT); - exif->replaceTag (t); - } - } -} - -// table not complete, not all proprietary Kodak tags are known -const TagAttrib kodakIfdAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "UnknownEV?", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "ExposureValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03e9, AUTO, "OriginalFileName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03eb, AUTO, "SensorLeftBorder", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03ec, AUTO, "SensorTopBorder", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03ed, AUTO, "SensorImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03ee, AUTO, "SensorImageHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03f1, AUTO, "TextualInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03fc, AUTO, "WhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03fd, AUTO, "Processing", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0401, AUTO, "Time", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0414, AUTO, "NCDFileInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0846, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0852, AUTO, "WB_RGBMul0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0853, AUTO, "WB_RGBMul1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0854, AUTO, "WB_RGBMul2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0855, AUTO, "WB_RGBMul3", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x085c, AUTO, "WB_RGBCoeffs0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x085d, AUTO, "WB_RGBCoeffs1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x085e, AUTO, "WB_RGBCoeffs2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x085f, AUTO, "WB_RGBCoeffs3", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0ce5, AUTO, "FirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1391, AUTO, "ToneCurveFileName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1784, AUTO, "ISO", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - -} -#endif - diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc deleted file mode 100644 index b2066150d..000000000 --- a/rtexif/nikonattribs.cc +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _NIKONATTRIBS_ -#define _NIKONATTRIBS_ - -#include -#include -#include -#include -#include "rtexif.h" - -using namespace std; - -namespace rtexif -{ - -class NAISOInterpreter : public Interpreter -{ -public: - NAISOInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%d", t->toInt (2)); - return buffer; - } -}; -NAISOInterpreter naISOInterpreter; - -class NAISOInfoISOInterpreter : public Interpreter -{ -public: - NAISOInfoISOInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - int a = t->toInt(); - sprintf (buffer, "%d", a); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->getValue()[ofs]; - - if (a > 1) { - double i = pow (2., double (a) / 12. - 5.) * 100.; - return i; - } else { - return 0.; - } - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - int a = t->getValue()[ofs]; - - if (a > 1) { - int i = int (double (powf (2.f, float (a) / 12.f - 5.f)) * 100.f + 0.5f); - return i; - } else { - return 0; - } - } -}; -NAISOInfoISOInterpreter naISOInfoISOInterpreter; - -class NAISOExpansionInterpreter : public Interpreter -{ -public: - NAISOExpansionInterpreter () {} - std::string toString (const Tag* t) const override - { - int a = t->toInt(); - - // unclear if this interpretation is correct! - switch (a) { - case 0x0: - return "Off"; - - case 0x101: - return "Hi 0.3"; - - case 0x102: - return "Hi 0.5"; - - case 0x103: - return "Hi 0.7"; - - case 0x104: - return "Hi 1.0"; - - case 0x105: - return "Hi 1.3"; - - case 0x106: - return "Hi 1.5"; - - case 0x107: - return "Hi 1.7"; - - case 0x108: - return "Hi 2.0"; - - case 0x201: - return "Lo 0.3"; - - case 0x202: - return "Lo 0.5"; - - case 0x203: - return "Lo 0.7"; - - case 0x204: - return "Lo 1.0"; - - default: { - char buffer[32]; - sprintf (buffer, "0x%04X", a); - return buffer; - } - } - } -}; -NAISOExpansionInterpreter naISOExpansionInterpreter; - -class NALensTypeInterpreter : public Interpreter -{ -public: - NALensTypeInterpreter () {} - std::string toString (const Tag* t) const override - { - int a = t->toInt(); - std::ostringstream str; - str << "MF = " << ((a & 1) ? "Yes" : "No") << std::endl; - str << "D = " << ((a & 2) ? "Yes" : "No") << std::endl; - str << "G = " << ((a & 4) ? "Yes" : "No") << std::endl; - str << "VR = " << ((a & 8) ? "Yes" : "No"); - return str.str(); - } -}; -NALensTypeInterpreter naLensTypeInterpreter; - -class NAFlashModeInterpreter : public ChoiceInterpreter<> -{ -public: - NAFlashModeInterpreter () - { - choices[0x0] = "Did Not Fire"; - choices[0x1] = "Fired, Manual"; - choices[0x3] = "Not Ready"; - choices[0x7] = "Fired, External"; - choices[0x8] = "Fired, Commander Mode"; - choices[0x9] = "Fired, TTL Mode"; - } -}; -NAFlashModeInterpreter naFlashModeInterpreter; - -class NAHiISONRInterpreter : public ChoiceInterpreter<> -{ -public: - // HighISONoiseReduction - NAHiISONRInterpreter () - { - choices[0x0] = "Off"; - choices[0x1] = "Minimal"; - choices[0x2] = "Low"; - choices[0x3] = "Medium Low"; - choices[0x4] = "Normal"; - choices[0x5] = "Medium High"; - choices[0x6] = "High"; - } -}; -NAHiISONRInterpreter naHiISONRInterpreter; - -class NAShootingModeInterpreter : public Interpreter -{ -public: - NAShootingModeInterpreter () {} - std::string toString (const Tag* t) const override - { - int a = t->toInt(); - std::ostringstream str; - str << "Continuous = " << ((a & 1) ? "Yes" : "No") << std::endl; - str << "Delay = " << ((a & 2) ? "Yes" : "No") << std::endl; - str << "PC Control = " << ((a & 4) ? "Yes" : "No") << std::endl; - str << "White-Balance Bracketing = " << ((a & 8) ? "Yes" : "No") << std::endl; - str << "Exposure Bracketing = " << ((a & 16) ? "Yes" : "No") << std::endl; - str << "Auto ISO = " << ((a & 32) ? "Yes" : "No") << std::endl; - str << "IR Control = " << ((a & 64) ? "Yes" : "No"); - return str.str(); - } -}; -NAShootingModeInterpreter naShootingModeInterpreter; - -class NAAFInfoInterpreter : public Interpreter -{ - std::map amchoices; - std::map afpchoices; -public: - // AFAreaMode - NAAFInfoInterpreter () - { - amchoices[0x0] = "Single Area"; - amchoices[0x1] = "Dynamic Area"; - amchoices[0x2] = "Dynamic Area (closest subject)"; - amchoices[0x3] = "Group Dynamic"; - amchoices[0x4] = "Single Area (wide)"; - amchoices[0x5] = "Dynamic Area (wide)"; - // AFPoint - afpchoices[0x0] = "Center"; - afpchoices[0x1] = "Top"; - afpchoices[0x2] = "Bottom"; - afpchoices[0x3] = "Mid-left"; - afpchoices[0x4] = "Mid-right"; - afpchoices[0x5] = "Upper-left"; - afpchoices[0x6] = "Upper-right"; - afpchoices[0x7] = "Lower-left"; - afpchoices[0x8] = "Lower-right"; - afpchoices[0x9] = "Far Left"; - afpchoices[0xa] = "Far Right"; - } - std::string toString (const Tag* t) const override - { - const auto get_from_choices = - [](const std::map& choices, int index) -> std::string - { - const std::map::const_iterator choice = choices.find(index); - - if (choice != choices.end()) { - return choice->second; - } - - return {}; - }; - - int am = t->toInt (0, BYTE); - int afp = t->toInt (1, BYTE); - int aff = t->toInt (2, SHORT); - std::ostringstream str; - str << "AFAreaMode = " << get_from_choices(amchoices, am) << std::endl; - str << "AFAreaMode = " << get_from_choices(afpchoices, afp) << std::endl; - - std::ostringstream af; - - if (aff & 1) - if (af.str() == "") { - af << "Center"; - } else { - af << ", Center"; - } else if (aff & 2) - if (af.str() == "") { - af << "Top"; - } else { - af << ", Top"; - } else if (aff & 4) - if (af.str() == "") { - af << "Bottom"; - } else { - af << ", Bottom"; - } else if (aff & 8) - if (af.str() == "") { - af << "Left"; - } else { - af << ", Left"; - } else if (aff & 16) - if (af.str() == "") { - af << "Right"; - } else { - af << ", Right"; - } else if (aff & 32) - if (af.str() == "") { - af << "Upper-left"; - } else { - af << ", Upper-left"; - } else if (aff & 64) - if (af.str() == "") { - af << "Upper-right"; - } else { - af << ", Upper-right"; - } else if (aff & 128) - if (af.str() == "") { - af << " Lower-left"; - } else { - af << ", Lower-left"; - } else if (aff & 256) - if (af.str() == "") { - af << "Lower-right"; - } else { - af << ", Lower-right"; - } else if (aff & 512) - if (af.str() == "") { - af << "Far Left"; - } else { - af << ", Far Left"; - } else if (aff & 1024) { - if (af.str() == "") { - af << "Far Right"; - } else { - af << ", Far Right"; - } - } - - str << "AFPointsInFocus = " << af.str(); - return str.str(); - } -}; -NAAFInfoInterpreter naAFInfoInterpreter; - -class NALensDataInterpreter : public Interpreter -{ - static const std::map lenses; - -public: - std::string toString (const Tag* t) const override - { - - static const unsigned char xlat[2][256] = { - { - 0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f, 0xc7, 0x7f, 0x3d, 0x3d, - 0x53, 0x59, 0xe3, 0xc7, 0xe9, 0x2f, 0x95, 0xa7, 0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, - 0xdf, 0x07, 0xef, 0x71, 0x89, 0x3d, 0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f, - 0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b, 0x47, 0x7f, 0x95, 0x35, 0xa7, 0x47, 0x4f, - 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61, 0xf1, 0x3d, 0xb3, 0x2b, 0x0d, 0x43, 0x89, 0xc1, - 0x9d, 0x9d, 0x89, 0x65, 0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95, 0x17, - 0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7, 0x53, 0xb5, 0x29, 0x89, - 0xe5, 0x2b, 0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5, 0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, - 0xb3, 0x43, 0x53, 0x65, 0x1d, 0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b, - 0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43, 0x2b, 0x07, 0x1d, 0x95, 0x59, 0x59, 0x47, 0xfb, - 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17, 0x7f, 0xef, 0x7f, 0x95, 0x95, 0x71, 0xd3, 0xa3, - 0x0b, 0x71, 0xa3, 0xad, 0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad, 0xe9, 0x2f, - 0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47, 0x3b, 0x9d, 0xef, 0x35, - 0xa3, 0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53, 0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, - 0x2f, 0x11, 0xdf, 0x17, 0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5, - 0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07, 0x6b, 0x25, 0x49, 0x95, 0x25, 0x49, 0x6d, 0x71, 0xc7 - }, - { - 0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17, 0x46, 0x7c, 0x29, 0x4c, - 0x4d, 0x03, 0xe9, 0x25, 0x68, 0x11, 0x86, 0xb3, 0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, - 0x2a, 0xbe, 0x1e, 0x46, 0x14, 0x68, 0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad, - 0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95, 0x9c, 0x66, 0xdc, 0xe7, 0x5d, 0x6c, 0x05, - 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f, 0x82, 0x4c, 0xc0, 0x68, 0x47, 0xa1, 0xbd, 0xee, - 0x39, 0x50, 0x56, 0x4a, 0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42, 0x9d, - 0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34, 0xe5, 0x2c, 0xdc, 0x9b, - 0x3f, 0xca, 0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5, 0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, - 0x3e, 0xd0, 0x5b, 0xa8, 0x87, 0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc, - 0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45, 0xf1, 0xf0, 0xa3, 0x94, 0x3a, 0x12, 0x77, 0x33, - 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65, 0x57, 0x16, 0x94, 0x6b, 0xfb, 0x59, 0xd0, 0xc8, - 0x22, 0x36, 0xdb, 0xd2, 0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26, 0xbb, 0xd6, - 0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e, 0xe0, 0x2f, 0xdc, 0x7c, - 0xbe, 0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8, 0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, - 0x3b, 0x2d, 0xeb, 0x25, 0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb, - 0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65, 0x7e, 0xb0, 0xdf, 0xaf, 0x4e, 0xb3, 0x61, 0x7f, 0x2f - } - }; - - int ver = (t->toInt (0, BYTE) - '0') * 1000 + (t->toInt (1, BYTE) - '0') * 100 + (t->toInt (2, BYTE) - '0') * 10 + (t->toInt (3, BYTE) - '0'); - - std::ostringstream ld; - ld << "Version = " << ver << std::endl; - - int lenstype = t->getParent()->getTag (0x0083)->toInt (0, BYTE); - - std::ostringstream lid; - lid.setf (std::ios_base::hex, std::ios_base::basefield); - lid.setf (std::ios_base::uppercase); - - Tag *modelTag = t->getParent()->getRoot()->findTag ("Model"); - std::string model ( modelTag ? modelTag->valueToString() : ""); - int lidoffs = 7; - bool d100 = false; - - if (model.substr (0, 10) == "NIKON D100" || model.substr (0, 9) == "NIKON D1X") { - lidoffs = 0; - d100 = true; - } else if ( ver < 204) { - lidoffs = 7; - d100 = false; - } else { - lidoffs = 8; - d100 = false; - } - - unsigned char buffer[16]; - - if (d100) { - memcpy (buffer, t->getValue() + 6, 7); - } else { - memcpy (buffer, t->getValue() + 4, 16); - } - - if (ver >= 201) { - const unsigned char* serval = t->getParent()->getTag (0x001d)->getValue (); - int serial = 0; - - for (int i = 0; serval[i]; i++) { - serial = serial * 10 + (isdigit (serval[i]) ? serval[i] - '0' : serval[i] % 10); - } - - const unsigned char* scval = t->getParent()->getTag (0x00a7)->getValue (); - int key = 0; - - for (int i = 0; i < 4; i++) { - key ^= scval[i]; - } - - unsigned char ci = xlat[0][serial & 0xff]; - unsigned char cj = xlat[1][key]; - unsigned char ck = 0x60; - - for (int i = 0; i < 16; i++) { - buffer[i] ^= (cj += ci * ck++); - } - } - - std::string EffectiveMaxApertureString = ""; - - if (!d100) { - int EffectiveMaxApertureValue; - - if ( ver < 204 ) { - ld << "ExitPupilPosition = " << (int) buffer[0] << std::endl; - ld << "AFAperture = " << (int) buffer[1] << std::endl; - ld << "FocusPosition = " << (int) buffer[4] << std::endl; - ld << "FocusDistance = " << (int) buffer[5] << std::endl; - ld << "FocalLength = " << (int) buffer[6] << std::endl; - EffectiveMaxApertureValue = (int) buffer[14]; - } else { - ld << "ExitPupilPosition = " << (int) buffer[0] << std::endl; - ld << "AFAperture = " << (int) buffer[1] << std::endl; - ld << "FocusPosition = " << (int) buffer[4] << std::endl; - ld << "FocusDistance = " << (int) buffer[6] << std::endl; - ld << "FocalLength = " << (int) buffer[7] << std::endl; - EffectiveMaxApertureValue = (int) buffer[15]; - } - - switch (EffectiveMaxApertureValue) { - case 0x8: - EffectiveMaxApertureString = "1.2"; - break; - - case 0xc: - EffectiveMaxApertureString = "1.4"; - break; - - case 0x14: - EffectiveMaxApertureString = "1.8"; - break; - - case 0x18: - EffectiveMaxApertureString = "2.0"; - break; - - case 0x20: - EffectiveMaxApertureString = "2.5"; - break; - - case 0x24: - EffectiveMaxApertureString = "2.8"; - break; - - case 0x2a: - EffectiveMaxApertureString = "3.3"; - break; - - case 0x2c: - EffectiveMaxApertureString = "3.5"; - break; - - case 0x30: - EffectiveMaxApertureString = "4.0"; - break; - - case 0x34: - EffectiveMaxApertureString = "4.5"; - break; - - case 0x38: - EffectiveMaxApertureString = "5.0"; - break; - - case 0x3c: - EffectiveMaxApertureString = "5.6"; - break; - - case 0x40: - EffectiveMaxApertureString = "6.3"; - break; - - case 0x44: - EffectiveMaxApertureString = "7.1"; - break; - - case 0x48: - EffectiveMaxApertureString = "8.0"; - break; - - case 0x4e: - EffectiveMaxApertureString = "9.5"; - break; - - case 0x54: - EffectiveMaxApertureString = "11.0"; - break; - - case 0x5a: - EffectiveMaxApertureString = "13.0"; - break; - - case 0x5e: - EffectiveMaxApertureString = "15.0"; - break; - - case 0x60: - EffectiveMaxApertureString = "16.0"; - break; - - case 0x66: - EffectiveMaxApertureString = "19.0"; - break; - - case 0x6c: - EffectiveMaxApertureString = "22.0"; - break; - - default : - EffectiveMaxApertureString = ""; - } - - ld << "EffectiveMaxAperture = " << EffectiveMaxApertureString << std::endl; - } - - for (int i = 0; i < 7; i++) { - lid << std::setw (2) << std::setfill ('0') << (int)buffer[lidoffs + i] << ' '; - } - - lid << std::setw (2) << std::setfill ('0') << lenstype; - - std::map::const_iterator r = lenses.find (lid.str()); - - if (r != lenses.end()) { - if (r == lenses.begin() && EffectiveMaxApertureString != "") { // first entry is for unchipped lenses - Tag *FLTag = t->getParent()->getRoot()->findTag ("FocalLength"); - ld << "Lens = MF "; - - if(FLTag) { - ld << FLTag->valueToString () << "mm"; - } else { - ld << "0mm"; - } - - ld << " f/" << EffectiveMaxApertureString; - } else { - ld << "Lens = " << r->second; - } - } else { - ld << "Lens = Unknown, ID=" << lid.str(); - } - - return ld.str(); - } - -}; -NALensDataInterpreter naLensDataInterpreter; -const std::map NALensDataInterpreter::lenses = { - /* - * The Nikon LensID is constructed as a Composite tag from the raw hex values of 8 other tags: - * LensIDNumber, LensFStops, MinFocalLength, MaxFocalLength, MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in that order. - */ - {"00 00 00 00 00 00 00 01", "Manual Lens No CPU"}, - {"00 00 00 00 00 00 E1 12", "TC-17E II"}, - {"00 00 00 00 00 00 F1 0C", "TC-14E [II] or Sigma APO Tele Converter 1.4x EX DG or Kenko Teleplus PRO 300 DG 1.4x"}, - {"00 00 00 00 00 00 F2 18", "TC-20E [II] or Sigma APO Tele Converter 2x EX DG or Kenko Teleplus PRO 300 DG 2.0x"}, - {"00 00 48 48 53 53 00 01", "Loreo 40mm f/11-22 3D Lens in a Cap 9005"}, - {"00 36 1C 2D 34 3C 00 06", "Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical (IF) (A13)"}, - {"00 3C 1F 37 30 30 00 06", "Tokina AT-X 124 AF PRO DX (AF 12-24mm f/4)"}, - {"00 3C 2B 44 30 30 00 06", "Tokina AT-X 17-35 f/4 PRO FX (AF 17-35mm f/4)"}, - {"00 3C 5C 80 30 30 00 0E", "Tokina AT-X 70-200 f/4 FX VCM-S (AF 70-200mm f/4)"}, - {"00 3E 80 A0 38 3F 00 02", "Tamron SP AF 200-500mm f/5-6.3 Di LD (IF) (A08)"}, - {"00 3F 2D 80 2B 40 00 06", "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) (A14)"}, - {"00 3F 2D 80 2C 40 00 06", "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14)"}, - {"00 3F 80 A0 38 3F 00 02", "Tamron SP AF 200-500mm f/5-6.3 Di (A08)"}, - {"00 40 11 11 2C 2C 00 00", "Samyang 8mm f/3.5 Fish-Eye"}, - {"00 40 18 2B 2C 34 00 06", "Tokina AT-X 107 AF DX Fisheye (AF 10-17mm f/3.5-4.5)"}, - {"00 40 2A 72 2C 3C 00 06", "Tokina AT-X 16.5-135 DX (AF 16.5-135mm f/3.5-5.6)"}, - {"00 40 2B 2B 2C 2C 00 02", "Tokina AT-X 17 AF PRO (AF 17mm f/3.5)"}, - {"00 40 2D 2D 2C 2C 00 00", "Carl Zeiss Distagon T* 3.5/18 ZF.2"}, - {"00 40 2D 80 2C 40 00 06", "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)"}, - {"00 40 2D 88 2C 40 00 06", "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18NII)"}, - {"00 40 2D 88 2C 40 62 06", "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18)"}, - {"00 40 31 31 2C 2C 00 00", "Voigtlander Color Skopar 20mm f/3.5 SLII Aspherical"}, - {"00 40 37 80 2C 3C 00 02", "Tokina AT-X 242 AF (AF 24-200mm f/3.5-5.6)"}, - {"00 40 64 64 2C 2C 00 00", "Voigtlander APO-Lanthar 90mm f/3.5 SLII Close Focus"}, - {"00 44 60 98 34 3C 00 02", "Tokina AT-X 840 D (AF 80-400mm f/4.5-5.6)"}, - {"00 47 10 10 24 24 00 00", "Fisheye Nikkor 8mm f/2.8 AiS"}, - {"00 47 25 25 24 24 00 02", "Tamron SP AF 14mm f/2.8 Aspherical (IF) (69E)"}, - {"00 47 3C 3C 24 24 00 00", "Nikkor 28mm f/2.8 AiS"}, - {"00 47 44 44 24 24 00 06", "Tokina AT-X M35 PRO DX (AF 35mm f/2.8 Macro)"}, - {"00 47 53 80 30 3C 00 06", "Tamron AF 55-200mm f/4-5.6 Di II LD (A15)"}, - {"00 48 1C 29 24 24 00 06", "Tokina AT-X 116 PRO DX (AF 11-16mm f/2.8)"}, - {"00 48 29 3C 24 24 00 06", "Tokina AT-X 16-28 AF PRO FX (AF 16-28mm f/2.8)"}, - {"00 48 29 50 24 24 00 06", "Tokina AT-X 165 PRO DX (AF 16-50mm f/2.8)"}, - {"00 48 32 32 24 24 00 00", "Carl Zeiss Distagon T* 2.8/21 ZF.2"}, - {"00 48 37 5C 24 24 00 06", "Tokina AT-X 24-70 f/2.8 PRO FX (AF 24-70mm f/2.8)"}, - {"00 48 3C 3C 24 24 00 00", "Voigtlander Color Skopar 28mm f/2.8 SL II"}, - {"00 48 3C 60 24 24 00 02", "Tokina AT-X 280 AF PRO (AF 28-80mm f/2.8)"}, - {"00 48 3C 6A 24 24 00 02", "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)"}, - {"00 48 50 50 18 18 00 00", "Nikkor H 50mm f/2"}, - {"00 48 50 72 24 24 00 06", "Tokina AT-X 535 PRO DX (AF 50-135mm f/2.8)"}, - {"00 48 5C 80 30 30 00 0E", "Tokina AT-X 70-200 f/4 FX VCM-S (AF 70-200mm f/4)"}, - {"00 48 5C 8E 30 3C 00 06", "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17NII)"}, - {"00 48 68 68 24 24 00 00", "Series E 100mm f/2.8"}, - {"00 48 80 80 30 30 00 00", "Nikkor 200mm f/4 AiS"}, - {"00 49 30 48 22 2B 00 02", "Tamron SP AF 20-40mm f/2.7-3.5 (166D)"}, - {"00 4C 6A 6A 20 20 00 00", "Nikkor 105mm f/2.5 AiS"}, - {"00 4C 7C 7C 2C 2C 00 02", "Tamron SP AF 180mm f/3.5 Di Model (B01)"}, - {"00 53 2B 50 24 24 00 06", "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16)"}, - {"00 54 2B 50 24 24 00 06", "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"}, - {"00 54 38 38 18 18 00 00", "Carl Zeiss Distagon T* 2/25 ZF.2"}, - {"00 54 3C 3C 18 18 00 00", "Carl Zeiss Distagon T* 2/28 ZF.2"}, - {"00 54 44 44 0C 0C 00 00", "Carl Zeiss Distagon T* 1.4/35 ZF.2"}, - {"00 54 44 44 18 18 00 00", "Carl Zeiss Distagon T* 2/35 ZF.2"}, - {"00 54 48 48 18 18 00 00", "Voigtlander Ultron 40mm f/2 SLII Aspherical"}, - {"00 54 50 50 0C 0C 00 00", "Carl Zeiss Planar T* 1.4/50 ZF.2"}, - {"00 54 50 50 18 18 00 00", "Carl Zeiss Makro-Planar T* 2/50 ZF.2"}, - {"00 54 53 53 0C 0C 00 00", "Zeiss Otus 1.4/55"}, - {"00 54 55 55 0C 0C 00 00", "Voigtlander Nokton 58mm f/1.4 SLII"}, - {"00 54 56 56 30 30 00 00", "Coastal Optical Systems 60mm 1:4 UV-VIS-IR Macro Apo"}, - {"00 54 62 62 0C 0C 00 00", "Carl Zeiss Planar T* 1.4/85 ZF.2"}, - {"00 54 68 68 18 18 00 00", "Carl Zeiss Makro-Planar T* 2/100 ZF.2"}, - {"00 54 68 68 24 24 00 02", "Tokina AT-X M100 AF PRO D (AF 100mm f/2.8 Macro)"}, - {"00 54 72 72 18 18 00 00", "Carl Zeiss Apo Sonnar T* 2/135 ZF.2"}, - {"00 54 8E 8E 24 24 00 02", "Tokina AT-X 300 AF PRO (AF 300mm f/2.8)"}, - {"00 57 50 50 14 14 00 00", "Nikkor 50mm f/1.8 AI"}, - {"00 58 64 64 20 20 00 00", "Soligor C/D Macro MC 90mm f/2.5"}, - {"01 00 00 00 00 00 02 00", "TC-16A"}, - {"01 00 00 00 00 00 08 00", "TC-16A"}, - {"01 54 62 62 0C 0C 00 00", "Zeiss Otus 1.4/85"}, - {"01 58 50 50 14 14 02 00", "AF Nikkor 50mm f/1.8"}, - {"01 58 50 50 14 14 05 00", "AF Nikkor 50mm f/1.8"}, - {"02 2F 98 98 3D 3D 02 00", "Sigma APO 400mm f/5.6"}, - {"02 34 A0 A0 44 44 02 00", "Sigma APO 500mm f/7.2"}, - {"02 37 5E 8E 35 3D 02 00", "Sigma 75-300mm f/4.5-5.6 APO"}, - {"02 37 A0 A0 34 34 02 00", "Sigma APO 500mm f/4.5"}, - {"02 3A 37 50 31 3D 02 00", "Sigma 24-50mm f/4-5.6 UC"}, - {"02 3A 5E 8E 32 3D 02 00", "Sigma 75-300mm f/4.0-5.6"}, - {"02 3B 44 61 30 3D 02 00", "Sigma 35-80mm f/4-5.6"}, - {"02 3C B0 B0 3C 3C 02 00", "Sigma APO 800mm f/5.6"}, - {"02 3F 24 24 2C 2C 02 00", "Sigma 14mm f/3.5"}, - {"02 3F 3C 5C 2D 35 02 00", "Sigma 28-70mm f/3.5-4.5 UC"}, - {"02 40 44 5C 2C 34 02 00", "Exakta AF 35-70mm 1:3.5-4.5 MC"}, - {"02 40 44 73 2B 36 02 00", "Sigma 35-135mm f/3.5-4.5 a"}, - {"02 40 5C 82 2C 35 02 00", "Sigma APO 70-210mm f/3.5-4.5"}, - {"02 42 44 5C 2A 34 02 00", "AF Zoom-Nikkor 35-70mm f/3.3-4.5"}, - {"02 42 44 5C 2A 34 08 00", "AF Zoom-Nikkor 35-70mm f/3.3-4.5"}, - {"02 46 37 37 25 25 02 00", "Sigma 24mm f/2.8 Super Wide II Macro"}, - {"02 46 3C 5C 25 25 02 00", "Sigma 28-70mm f/2.8"}, - {"02 46 5C 82 25 25 02 00", "Sigma 70-210mm f/2.8 APO"}, - {"02 48 50 50 24 24 02 00", "Sigma Macro 50mm f/2.8"}, - {"02 48 65 65 24 24 02 00", "Sigma Macro 90mm f/2.8"}, - {"03 43 5C 81 35 35 02 00", "Soligor AF C/D Zoom UMCS 70-210mm 1:4.5"}, - {"03 48 5C 81 30 30 02 00", "AF Zoom-Nikkor 70-210mm f/4"}, - {"04 48 3C 3C 24 24 03 00", "AF Nikkor 28mm f/2.8"}, - {"05 54 50 50 0C 0C 04 00", "AF Nikkor 50mm f/1.4"}, - {"06 3F 68 68 2C 2C 06 00", "Cosina AF 100mm f/3.5 Macro"}, - {"06 54 53 53 24 24 06 00", "AF Micro-Nikkor 55mm f/2.8"}, - {"07 36 3D 5F 2C 3C 03 00", "Cosina AF Zoom 28-80mm f/3.5-5.6 MC Macro"}, - {"07 3E 30 43 2D 35 03 00", "Soligor AF Zoom 19-35mm 1:3.5-4.5 MC"}, - {"07 40 2F 44 2C 34 03 02", "Tamron AF 19-35mm f/3.5-4.5 (A10)"}, - {"07 40 30 45 2D 35 03 02", "Tamron AF 19-35mm f/3.5-4.5 (A10)"}, - {"07 40 3C 5C 2C 35 03 00", "Tokina AF 270 II (AF 28-70mm f/3.5-4.5)"}, - {"07 40 3C 62 2C 34 03 00", "AF Zoom-Nikkor 28-85mm f/3.5-4.5"}, - {"07 46 2B 44 24 30 03 02", "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical (IF) (A05)"}, - {"07 46 3D 6A 25 2F 03 00", "Cosina AF Zoom 28-105mm f/2.8-3.8 MC"}, - {"07 47 3C 5C 25 35 03 00", "Tokina AF 287 SD (AF 28-70mm f/2.8-4.5)"}, - {"07 48 3C 5C 24 24 03 00", "Tokina AT-X 287 AF (AF 28-70mm f/2.8)"}, - {"08 40 44 6A 2C 34 04 00", "AF Zoom-Nikkor 35-105mm f/3.5-4.5"}, - {"09 48 37 37 24 24 04 00", "AF Nikkor 24mm f/2.8"}, - {"0A 48 8E 8E 24 24 03 00", "AF Nikkor 300mm f/2.8 IF-ED"}, - {"0A 48 8E 8E 24 24 05 00", "AF Nikkor 300mm f/2.8 IF-ED N"}, - {"0B 3E 3D 7F 2F 3D 0E 00", "Tamron AF 28-200mm f/3.8-5.6 (71D)"}, - {"0B 3E 3D 7F 2F 3D 0E 02", "Tamron AF 28-200mm f/3.8-5.6D (171D)"}, - {"0B 48 7C 7C 24 24 05 00", "AF Nikkor 180mm f/2.8 IF-ED"}, - {"0D 40 44 72 2C 34 07 00", "AF Zoom-Nikkor 35-135mm f/3.5-4.5"}, - {"0E 48 5C 81 30 30 05 00", "AF Zoom-Nikkor 70-210mm f/4"}, - {"0E 4A 31 48 23 2D 0E 02", "Tamron SP AF 20-40mm f/2.7-3.5 (166D)"}, - {"0F 58 50 50 14 14 05 00", "AF Nikkor 50mm f/1.8 N"}, - {"10 3D 3C 60 2C 3C D2 02", "Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)"}, - {"10 48 8E 8E 30 30 08 00", "AF Nikkor 300mm f/4 IF-ED"}, - {"11 48 44 5C 24 24 08 00", "AF Zoom-Nikkor 35-70mm f/2.8"}, - {"11 48 44 5C 24 24 15 00", "AF Zoom-Nikkor 35-70mm f/2.8"}, - {"12 36 5C 81 35 3D 09 00", "Cosina AF Zoom 70-210mm f/4.5-5.6 MC Macro"}, - {"12 36 69 97 35 42 09 00", "Soligor AF Zoom 100-400mm 1:4.5-6.7 MC"}, - {"12 38 69 97 35 42 09 02", "Promaster Spectrum 7 100-400mm f/4.5-6.7"}, - {"12 39 5C 8E 34 3D 08 02", "Cosina AF Zoom 70-300mm f/4.5-5.6 MC Macro"}, - {"12 3B 68 8D 3D 43 09 02", "Cosina AF Zoom 100-300mm f/5.6-6.7 MC Macro"}, - {"12 3B 98 98 3D 3D 09 00", "Tokina AT-X 400 AF SD (AF 400mm f/5.6)"}, - {"12 3D 3C 80 2E 3C DF 02", "Tamron AF 28-200mm f/3.8-5.6 AF Aspherical LD (IF) (271D)"}, - {"12 44 5E 8E 34 3C 09 00", "Tokina AF 730 (AF 75-300mm f/4.5-5.6)"}, - {"12 48 5C 81 30 3C 09 00", "AF Nikkor 70-210mm f/4-5.6"}, - {"12 4A 5C 81 31 3D 09 00", "Soligor AF C/D Auto Zoom+Macro 70-210mm 1:4-5.6 UMCS"}, - {"13 42 37 50 2A 34 0B 00", "AF Zoom-Nikkor 24-50mm f/3.3-4.5"}, - {"14 48 60 80 24 24 0B 00", "AF Zoom-Nikkor 80-200mm f/2.8 ED"}, - {"14 48 68 8E 30 30 0B 00", "Tokina AT-X 340 AF (AF 100-300mm f/4)"}, - {"14 54 60 80 24 24 0B 00", "Tokina AT-X 828 AF (AF 80-200mm f/2.8)"}, - {"15 4C 62 62 14 14 0C 00", "AF Nikkor 85mm f/1.8"}, - {"17 3C A0 A0 30 30 0F 00", "Nikkor 500mm f/4 P ED IF"}, - {"17 3C A0 A0 30 30 11 00", "Nikkor 500mm f/4 P ED IF"}, - {"18 40 44 72 2C 34 0E 00", "AF Zoom-Nikkor 35-135mm f/3.5-4.5 N"}, - {"1A 54 44 44 18 18 11 00", "AF Nikkor 35mm f/2"}, - {"1B 44 5E 8E 34 3C 10 00", "AF Zoom-Nikkor 75-300mm f/4.5-5.6"}, - {"1C 48 30 30 24 24 12 00", "AF Nikkor 20mm f/2.8"}, - {"1D 42 44 5C 2A 34 12 00", "AF Zoom-Nikkor 35-70mm f/3.3-4.5 N"}, - {"1E 54 56 56 24 24 13 00", "AF Micro-Nikkor 60mm f/2.8"}, - {"1E 5D 64 64 20 20 13 00", "Tamron SP AF 90mm f/2.5 (52E)"}, - {"1F 54 6A 6A 24 24 14 00", "AF Micro-Nikkor 105mm f/2.8"}, - {"20 3C 80 98 3D 3D 1E 02", "Tamron AF 200-400mm f/5.6 LD IF (75D)"}, - {"20 48 60 80 24 24 15 00", "AF Zoom-Nikkor 80-200mm f/2.8 ED"}, - {"20 5A 64 64 20 20 14 00", "Tamron SP AF 90mm f/2.5 Macro (152E)"}, - {"21 40 3C 5C 2C 34 16 00", "AF Zoom-Nikkor 28-70mm f/3.5-4.5"}, - {"21 56 8E 8E 24 24 14 00", "Tamron SP AF 300mm f/2.8 LD-IF (60E)"}, - {"22 48 72 72 18 18 16 00", "AF DC-Nikkor 135mm f/2"}, - {"22 53 64 64 24 24 E0 02", "Tamron SP AF 90mm f/2.8 Macro 1:1 (72E)"}, - {"23 30 BE CA 3C 48 17 00", "Zoom-Nikkor 1200-1700mm f/5.6-8 P ED IF"}, - {"24 44 60 98 34 3C 1A 02", "Tokina AT-X 840 AF-II (AF 80-400mm f/4.5-5.6)"}, - {"24 48 60 80 24 24 1A 02", "AF Zoom-Nikkor 80-200mm f/2.8D ED"}, - {"24 54 60 80 24 24 1A 02", "Tokina AT-X 828 AF PRO (AF 80-200mm f/2.8)"}, - {"25 44 44 8E 34 42 1B 02", "Tokina AF 353 (AF 35-300mm f/4.5-6.7)"}, - {"25 48 3C 5C 24 24 1B 02", "Tokina AT-X 270 AF PRO II (AF 28-70mm f/2.6-2.8)"}, - {"25 48 3C 5C 24 24 1B 02", "Tokina AT-X 287 AF PRO SV (AF 28-70mm f/2.8)"}, - {"25 48 44 5C 24 24 1B 02", "AF Zoom-Nikkor 35-70mm f/2.8D"}, - {"25 48 44 5C 24 24 3A 02", "AF Zoom-Nikkor 35-70mm f/2.8D"}, - {"25 48 44 5C 24 24 52 02", "AF Zoom-Nikkor 35-70mm f/2.8D"}, - {"26 3C 54 80 30 3C 1C 06", "Sigma 55-200mm f/4-5.6 DC"}, - {"26 3C 5C 82 30 3C 1C 02", "Sigma 70-210mm f/4-5.6 UC-II"}, - {"26 3C 5C 8E 30 3C 1C 02", "Sigma 70-300mm f/4-5.6 DG Macro"}, - {"26 3C 98 98 3C 3C 1C 02", "Sigma APO Tele Macro 400mm f/5.6"}, - {"26 3D 3C 80 2F 3D 1C 02", "Sigma 28-300mm f/3.8-5.6 Aspherical"}, - {"26 3E 3C 6A 2E 3C 1C 02", "Sigma 28-105mm f/3.8-5.6 UC-III Aspherical IF"}, - {"26 40 27 3F 2C 34 1C 02", "Sigma 15-30mm f/3.5-4.5 EX DG Aspherical DF"}, - {"26 40 2D 44 2B 34 1C 02", "Sigma 18-35mm f/3.5-4.5 Aspherical"}, - {"26 40 2D 50 2C 3C 1C 06", "Sigma 18-50mm f/3.5-5.6 DC"}, - {"26 40 2D 70 2B 3C 1C 06", "Sigma 18-125mm f/3.5-5.6 DC"}, - {"26 40 2D 80 2C 40 1C 06", "Sigma 18-200mm f/3.5-6.3 DC"}, - {"26 40 37 5C 2C 3C 1C 02", "Sigma 24-70mm f/3.5-5.6 Aspherical HF"}, - {"26 40 3C 5C 2C 34 1C 02", "AF Zoom-Nikkor 28-70mm f/3.5-4.5D"}, - {"26 40 3C 60 2C 3C 1C 02", "Sigma 28-80mm f/3.5-5.6 Mini Zoom Macro II Aspherical"}, - {"26 40 3C 65 2C 3C 1C 02", "Sigma 28-90mm f/3.5-5.6 Macro"}, - {"26 40 3C 80 2B 3C 1C 02", "Sigma 28-200mm f/3.5-5.6 Compact Aspherical Hyperzoom Macro"}, - {"26 40 3C 80 2C 3C 1C 02", "Sigma 28-200mm f/3.5-5.6 Compact Aspherical Hyperzoom Macro"}, - {"26 40 3C 8E 2C 40 1C 02", "Sigma 28-300mm f/3.5-6.3 Macro"}, - {"26 40 7B A0 34 40 1C 02", "Sigma APO 170-500mm f/5-6.3 Aspherical RF"}, - {"26 41 3C 8E 2C 40 1C 02", "Sigma 28-300mm f/3.5-6.3 DG Macro"}, - {"26 44 73 98 34 3C 1C 02", "Sigma 135-400mm f/4.5-5.6 APO Aspherical"}, - {"26 48 11 11 30 30 1C 02", "Sigma 8mm f/4 EX Circular Fisheye"}, - {"26 48 27 27 24 24 1C 02", "Sigma 15mm f/2.8 EX Diagonal Fisheye"}, - {"26 48 2D 50 24 24 1C 06", "Sigma 18-50mm f/2.8 EX DC"}, - {"26 48 31 49 24 24 1C 02", "Sigma 20-40mm f/2.8"}, - {"26 48 37 56 24 24 1C 02", "Sigma 24-60mm f/2.8 EX DG"}, - {"26 48 3C 5C 24 24 1C 06", "Sigma 28-70mm f/2.8 EX DG"}, - {"26 48 3C 5C 24 30 1C 02", "Sigma 28-70mm f/2.8-4 DG"}, - {"26 48 3C 6A 24 30 1C 02", "Sigma 28-105mm f/2.8-4 Aspherical"}, - {"26 48 8E 8E 30 30 1C 02", "Sigma APO Tele Macro 300mm f/4"}, - {"26 54 2B 44 24 30 1C 02", "Sigma 17-35mm f/2.8-4 EX Aspherical"}, - {"26 54 37 5C 24 24 1C 02", "Sigma 24-70mm f/2.8 EX DG Macro"}, - {"26 54 37 73 24 34 1C 02", "Sigma 24-135mm f/2.8-4.5"}, - {"26 54 3C 5C 24 24 1C 02", "Sigma 28-70mm f/2.8 EX"}, - {"26 58 31 31 14 14 1C 02", "Sigma 20mm f/1.8 EX DG Aspherical RF"}, - {"26 58 37 37 14 14 1C 02", "Sigma 24mm f/1.8 EX DG Aspherical Macro"}, - {"26 58 3C 3C 14 14 1C 02", "Sigma 28mm f/1.8 EX DG Aspherical Macro"}, - {"27 48 8E 8E 24 24 1D 02", "AF-I Nikkor 300mm f/2.8D IF-ED"}, - {"27 48 8E 8E 24 24 E1 02", "AF-I Nikkor 300mm f/2.8D IF-ED + TC-17E"}, - {"27 48 8E 8E 24 24 F1 02", "AF-I Nikkor 300mm f/2.8D IF-ED + TC-14E"}, - {"27 48 8E 8E 24 24 F2 02", "AF-I Nikkor 300mm f/2.8D IF-ED + TC-20E"}, - {"27 48 8E 8E 30 30 1D 02", "Tokina AT-X 304 AF (AF 300mm f/4.0)"}, - {"27 54 8E 8E 24 24 1D 02", "Tamron SP AF 300mm f/2.8 LD-IF (360E)"}, - {"28 3C A6 A6 30 30 1D 02", "AF-I Nikkor 600mm f/4D IF-ED"}, - {"28 3C A6 A6 30 30 E1 02", "AF-I Nikkor 600mm f/4D IF-ED + TC-17E"}, - {"28 3C A6 A6 30 30 F1 02", "AF-I Nikkor 600mm f/4D IF-ED + TC-14E"}, - {"28 3C A6 A6 30 30 F2 02", "AF-I Nikkor 600mm f/4D IF-ED + TC-20E"}, - {"2A 54 3C 3C 0C 0C 26 02", "AF Nikkor 28mm f/1.4D"}, - {"2B 3C 44 60 30 3C 1F 02", "AF Zoom-Nikkor 35-80mm f/4-5.6D"}, - {"2C 48 6A 6A 18 18 27 02", "AF DC-Nikkor 105mm f/2D"}, - {"2D 48 80 80 30 30 21 02", "AF Micro-Nikkor 200mm f/4D IF-ED"}, - {"2E 48 5C 82 30 3C 22 02", "AF Nikkor 70-210mm f/4-5.6D"}, - {"2E 48 5C 82 30 3C 28 02", "AF Nikkor 70-210mm f/4-5.6D"}, - {"2F 40 30 44 2C 34 29 02", "Tokina AF 235 II (AF 20-35mm f/3.5-4.5)"}, - {"2F 40 30 44 2C 34 29 02", "Tokina AF 193 (AF 19-35mm f/3.5-4.5)"}, - {"2F 48 30 44 24 24 29 02", "AF Zoom-Nikkor 20-35mm f/2.8D IF"}, - {"2F 48 30 44 24 24 29 02", "Tokina AT-X 235 AF PRO (AF 20-35mm f/2.8)"}, - {"30 48 98 98 24 24 24 02", "AF-I Nikkor 400mm f/2.8D IF-ED"}, - {"30 48 98 98 24 24 E1 02", "AF-I Nikkor 400mm f/2.8D IF-ED + TC-17E"}, - {"30 48 98 98 24 24 F1 02", "AF-I Nikkor 400mm f/2.8D IF-ED + TC-14E"}, - {"30 48 98 98 24 24 F2 02", "AF-I Nikkor 400mm f/2.8D IF-ED + TC-20E"}, - {"31 54 56 56 24 24 25 02", "AF Micro-Nikkor 60mm f/2.8D"}, - {"32 53 64 64 24 24 35 02", "Tamron SP AF 90mm f/2.8 [Di] Macro 1:1 (172E/272E)"}, - {"32 54 50 50 24 24 35 02", "Sigma Macro 50mm f/2.8 EX DG"}, - {"32 54 6A 6A 24 24 35 02", "AF Micro-Nikkor 105mm f/2.8D"}, - {"32 54 6A 6A 24 24 35 02", "Sigma Macro 105mm f/2.8 EX DG"}, - {"33 48 2D 2D 24 24 31 02", "AF Nikkor 18mm f/2.8D"}, - {"33 54 3C 5E 24 24 62 02", "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09)"}, - {"34 48 29 29 24 24 32 02", "AF Fisheye Nikkor 16mm f/2.8D"}, - {"35 3C A0 A0 30 30 33 02", "AF-I Nikkor 500mm f/4D IF-ED"}, - {"35 3C A0 A0 30 30 E1 02", "AF-I Nikkor 500mm f/4D IF-ED + TC-17E"}, - {"35 3C A0 A0 30 30 F1 02", "AF-I Nikkor 500mm f/4D IF-ED + TC-14E"}, - {"35 3C A0 A0 30 30 F2 02", "AF-I Nikkor 500mm f/4D IF-ED + TC-20E"}, - {"36 48 37 37 24 24 34 02", "AF Nikkor 24mm f/2.8D"}, - {"37 48 30 30 24 24 36 02", "AF Nikkor 20mm f/2.8D"}, - {"38 4C 62 62 14 14 37 02", "AF Nikkor 85mm f/1.8D"}, - {"3A 40 3C 5C 2C 34 39 02", "AF Zoom-Nikkor 28-70mm f/3.5-4.5D"}, - {"3B 48 44 5C 24 24 3A 02", "AF Zoom-Nikkor 35-70mm f/2.8D N"}, - {"3C 48 60 80 24 24 3B 02", "AF Zoom-Nikkor 80-200mm f/2.8D ED"}, - {"3D 3C 44 60 30 3C 3E 02", "AF Zoom-Nikkor 35-80mm f/4-5.6D"}, - {"3E 48 3C 3C 24 24 3D 02", "AF Nikkor 28mm f/2.8D"}, - {"3F 40 44 6A 2C 34 45 02", "AF Zoom-Nikkor 35-105mm f/3.5-4.5D"}, - {"41 48 7C 7C 24 24 43 02", "AF Nikkor 180mm f/2.8D IF-ED"}, - {"42 54 44 44 18 18 44 02", "AF Nikkor 35mm f/2D"}, - {"43 54 50 50 0C 0C 46 02", "AF Nikkor 50mm f/1.4D"}, - {"44 44 60 80 34 3C 47 02", "AF Zoom-Nikkor 80-200mm f/4.5-5.6D"}, - {"45 3D 3C 60 2C 3C 48 02", "Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)"}, - {"45 40 3C 60 2C 3C 48 02", "AF Zoom-Nikkor 28-80mm f/3.5-5.6D"}, - {"45 41 37 72 2C 3C 48 02", "Tamron SP AF 24-135mm f/3.5-5.6 AD Aspherical (IF) Macro (190D)"}, - {"46 3C 44 60 30 3C 49 02", "AF Zoom-Nikkor 35-80mm f/4-5.6D N"}, - {"47 42 37 50 2A 34 4A 02", "AF Zoom-Nikkor 24-50mm f/3.3-4.5D"}, - {"48 38 1F 37 34 3C 4B 06", "Sigma 12-24mm f/4.5-5.6 EX DG Aspherical HSM"}, - {"48 3C 19 31 30 3C 4B 06", "Sigma 10-20mm f/4-5.6 EX DC HSM"}, - {"48 3C 50 A0 30 40 4B 02", "Sigma 50-500mm f/4-6.3 EX APO RF HSM"}, - {"48 3C 8E B0 3C 3C 4B 02", "Sigma APO 300-800mm f/5.6 EX DG HSM"}, - {"48 3C B0 B0 3C 3C 4B 02", "Sigma APO 800mm f/5.6 EX HSM"}, - {"48 44 A0 A0 34 34 4B 02", "Sigma APO 500mm f/4.5 EX HSM"}, - {"48 48 24 24 24 24 4B 02", "Sigma 14mm f/2.8 EX Aspherical HSM"}, - {"48 48 2B 44 24 30 4B 06", "Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM"}, - {"48 48 68 8E 30 30 4B 02", "Sigma APO 100-300mm f/4 EX IF HSM"}, - {"48 48 76 76 24 24 4B 06", "Sigma APO Macro 150mm f/2.8 EX DG HSM"}, - {"48 48 8E 8E 24 24 4B 02", "AF-S Nikkor 300mm f/2.8D IF-ED"}, - {"48 48 8E 8E 24 24 E1 02", "AF-S Nikkor 300mm f/2.8D IF-ED + TC-17E"}, - {"48 48 8E 8E 24 24 F1 02", "AF-S Nikkor 300mm f/2.8D IF-ED + TC-14E"}, - {"48 48 8E 8E 24 24 F2 02", "AF-S Nikkor 300mm f/2.8D IF-ED + TC-20E"}, - {"48 4C 7C 7C 2C 2C 4B 02", "Sigma APO Macro 180mm f/3.5 EX DG HSM"}, - {"48 4C 7D 7D 2C 2C 4B 02", "Sigma APO Macro 180mm f/3.5 EX DG HSM"}, - {"48 54 3E 3E 0C 0C 4B 06", "Sigma 30mm f/1.4 EX DC HSM"}, - {"48 54 5C 80 24 24 4B 02", "Sigma 70-200mm f/2.8 EX APO IF HSM"}, - {"48 54 6F 8E 24 24 4B 02", "Sigma APO 120-300mm f/2.8 EX DG HSM"}, - {"48 54 8E 8E 24 24 4B 02", "Sigma APO 300mm f/2.8 EX DG HSM"}, - {"49 3C A6 A6 30 30 4C 02", "AF-S Nikkor 600mm f/4D IF-ED"}, - {"49 3C A6 A6 30 30 E1 02", "AF-S Nikkor 600mm f/4D IF-ED + TC-17E"}, - {"49 3C A6 A6 30 30 F1 02", "AF-S Nikkor 600mm f/4D IF-ED + TC-14E"}, - {"49 3C A6 A6 30 30 F2 02", "AF-S Nikkor 600mm f/4D IF-ED + TC-20E"}, - {"4A 40 11 11 2C 0C 4D 02", "Samyang 8mm f/3.5 Fish-Eye CS"}, - {"4A 48 1E 1E 24 0C 4D 02", "Samyang 12mm f/2.8 ED AS NCS Fish-Eye"}, - {"4A 48 24 24 24 0C 4D 02", "Samyang 10mm f/2.8 ED AS NCS CS"}, - {"4A 48 24 24 24 0C 4D 02", "Samyang AE 14mm f/2.8 ED AS IF UMC"}, - {"4A 4C 24 24 1E 6C 4D 06", "Samyang 14mm f/2.4 Premium"}, - {"4A 54 29 29 18 0C 4D 02", "Samyang 16mm f/2.0 ED AS UMC CS"}, - {"4A 54 62 62 0C 0C 4D 02", "AF Nikkor 85mm f/1.4D IF"}, - {"4A 60 36 36 0C 0C 4D 02", "Samyang 24mm f/1.4 ED AS UMC"}, - {"4A 60 44 44 0C 0C 4D 02", "Samyang 35mm f/1.4 AS UMC"}, - {"4A 60 62 62 0C 0C 4D 02", "Samyang AE 85mm f/1.4 AS IF UMC"}, - {"4B 3C A0 A0 30 30 4E 02", "AF-S Nikkor 500mm f/4D IF-ED"}, - {"4B 3C A0 A0 30 30 E1 02", "AF-S Nikkor 500mm f/4D IF-ED + TC-17E"}, - {"4B 3C A0 A0 30 30 F1 02", "AF-S Nikkor 500mm f/4D IF-ED + TC-14E"}, - {"4B 3C A0 A0 30 30 F2 02", "AF-S Nikkor 500mm f/4D IF-ED + TC-20E"}, - {"4C 40 37 6E 2C 3C 4F 02", "AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF"}, - {"4D 3E 3C 80 2E 3C 62 02", "Tamron AF 28-200mm f/3.8-5.6 XR Aspherical (IF) Macro (A03N)"}, - {"4D 40 3C 80 2C 3C 62 02", "AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF"}, - {"4D 41 3C 8E 2B 40 62 02", "Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical (IF) (A061)"}, - {"4D 41 3C 8E 2C 40 62 02", "Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical (IF) (185D)"}, - {"4E 48 72 72 18 18 51 02", "AF DC-Nikkor 135mm f/2D"}, - {"4F 40 37 5C 2C 3C 53 06", "IX-Nikkor 24-70mm f/3.5-5.6"}, - {"50 48 56 7C 30 3C 54 06", "IX-Nikkor 60-180mm f/4-5.6"}, - {"52 54 44 44 18 18 00 00", "Zeiss Milvus 35mm f/2"}, - {"53 48 60 80 24 24 57 02", "AF Zoom-Nikkor 80-200mm f/2.8D ED"}, - {"53 48 60 80 24 24 60 02", "AF Zoom-Nikkor 80-200mm f/2.8D ED"}, - {"53 54 50 50 0C 0C 00 00", "Zeiss Milvus 50mm f/1.4"}, - {"54 44 5C 7C 34 3C 58 02", "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"}, - {"54 44 5C 7C 34 3C 61 02", "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"}, - {"54 54 50 50 18 18 00 00", "Zeiss Milvus 50mm f/2 Macro"}, - {"55 54 62 62 0C 0C 00 00", "Zeiss Milvus 85mm f/1.4"}, - {"56 3C 5C 8E 30 3C 1C 02", "Sigma 70-300mm f/4-5.6 APO Macro Super II"}, - {"56 48 5C 8E 30 3C 5A 02", "AF Zoom-Nikkor 70-300mm f/4-5.6D ED"}, - {"56 54 68 68 18 18 00 00", "Zeiss Milvus 100mm f/2 Macro"}, - {"59 48 98 98 24 24 5D 02", "AF-S Nikkor 400mm f/2.8D IF-ED"}, - {"59 48 98 98 24 24 E1 02", "AF-S Nikkor 400mm f/2.8D IF-ED + TC-17E"}, - {"59 48 98 98 24 24 F1 02", "AF-S Nikkor 400mm f/2.8D IF-ED + TC-14E"}, - {"59 48 98 98 24 24 F2 02", "AF-S Nikkor 400mm f/2.8D IF-ED + TC-20E"}, - {"5A 3C 3E 56 30 3C 5E 06", "IX-Nikkor 30-60mm f/4-5.6"}, - {"5B 44 56 7C 34 3C 5F 06", "IX-Nikkor 60-180mm f/4.5-5.6"}, - {"5D 48 3C 5C 24 24 63 02", "AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED"}, - {"5E 48 60 80 24 24 64 02", "AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED"}, - {"5F 40 3C 6A 2C 34 65 02", "AF Zoom-Nikkor 28-105mm f/3.5-4.5D IF"}, - {"60 40 3C 60 2C 3C 66 02", "AF Zoom-Nikkor 28-80mm f/3.5-5.6D"}, - {"61 44 5E 86 34 3C 67 02", "AF Zoom-Nikkor 75-240mm f/4.5-5.6D"}, - {"63 48 2B 44 24 24 68 02", "AF-S Nikkor 17-35mm f/2.8D IF-ED"}, - {"64 00 62 62 24 24 6A 02", "PC Micro-Nikkor 85mm f/2.8D"}, - {"65 44 60 98 34 3C 6B 0A", "AF VR Zoom-Nikkor 80-400mm f/4.5-5.6D ED"}, - {"66 40 2D 44 2C 34 6C 02", "AF Zoom-Nikkor 18-35mm f/3.5-4.5D IF-ED"}, - {"67 48 37 62 24 30 6D 02", "AF Zoom-Nikkor 24-85mm f/2.8-4D IF"}, - {"67 54 37 5C 24 24 1C 02", "Sigma 24-70mm f/2.8 EX DG Macro"}, - {"68 42 3C 60 2A 3C 6E 06", "AF Zoom-Nikkor 28-80mm f/3.3-5.6G"}, - {"69 47 5C 8E 30 3C 00 02", "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17N)"}, - {"69 48 5C 8E 30 3C 6F 02", "Tamron AF 70-300mm f/4-5.6 LD Macro 1:2 (572D/772D)"}, - {"69 48 5C 8E 30 3C 6F 06", "AF Zoom-Nikkor 70-300mm f/4-5.6G"}, - {"6A 48 8E 8E 30 30 70 02", "AF-S Nikkor 300mm f/4D IF-ED"}, - {"6B 48 24 24 24 24 71 02", "AF Nikkor ED 14mm f/2.8D"}, - {"6D 48 8E 8E 24 24 73 02", "AF-S Nikkor 300mm f/2.8D IF-ED II"}, - {"6E 48 98 98 24 24 74 02", "AF-S Nikkor 400mm f/2.8D IF-ED II"}, - {"6F 3C A0 A0 30 30 75 02", "AF-S Nikkor 500mm f/4D IF-ED II"}, - {"70 3C A6 A6 30 30 76 02", "AF-S Nikkor 600mm f/4D IF-ED II"}, - {"72 48 4C 4C 24 24 77 00", "Nikkor 45mm f/2.8 P"}, - {"74 40 37 62 2C 34 78 06", "AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"}, - {"75 40 3C 68 2C 3C 79 06", "AF Zoom-Nikkor 28-100mm f/3.5-5.6G"}, - {"76 58 50 50 14 14 7A 02", "AF Nikkor 50mm f/1.8D"}, - {"77 44 60 98 34 3C 7B 0E", "Sigma 80-400mm f/4.5-5.6 APO DG D OS"}, - {"77 44 61 98 34 3C 7B 0E", "Sigma 80-400mm f/4.5-5.6 EX OS"}, - {"77 48 5C 80 24 24 7B 0E", "AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED"}, - {"78 40 37 6E 2C 3C 7C 0E", "AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED"}, - {"79 40 11 11 2C 2C 1C 06", "Sigma 8mm f/3.5 EX Circular Fisheye"}, - {"79 40 3C 80 2C 3C 7F 06", "AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED"}, - {"79 48 3C 5C 24 24 1C 06", "Sigma 28-70mm f/2.8 EX DG"}, - {"79 48 5C 5C 24 24 1C 06", "Sigma Macro 70mm f/2.8 EX DG"}, - {"79 54 31 31 0C 0C 4B 06", "Sigma 20mm f/1.4 DG HSM | A"}, - {"7A 3B 53 80 30 3C 4B 06", "Sigma 55-200mm f/4-5.6 DC HSM"}, - {"7A 3C 1F 37 30 30 7E 06", "AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED"}, - {"7A 3C 1F 37 30 30 7E 06", "Tokina AT-X 124 AF PRO DX II (AF 12-24mm f/4)"}, - {"7A 3C 1F 3C 30 30 7E 06", "Tokina AT-X 12-28 PRO DX (AF 12-28mm f/4)"}, - {"7A 40 2D 50 2C 3C 4B 06", "Sigma 18-50mm f/3.5-5.6 DC HSM"}, - {"7A 40 2D 80 2C 40 4B 0E", "Sigma 18-200mm f/3.5-6.3 DC OS HSM"}, - {"7A 47 2B 5C 24 34 4B 06", "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"}, - {"7A 47 50 76 24 24 4B 06", "Sigma 50-150mm f/2.8 EX APO DC HSM"}, - {"7A 48 1C 29 24 24 7E 06", "Tokina AT-X 116 PRO DX II (AF 11-16mm f/2.8)"}, - {"7A 48 1C 30 24 24 7E 06", "Tokina AT-X 11-20 f/2.8 PRO DX (AF 11-20mm f/2.8)"}, - {"7A 48 2B 5C 24 34 4B 06", "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"}, - {"7A 48 2D 50 24 24 4B 06", "Sigma 18-50mm f/2.8 EX DC Macro"}, - {"7A 48 5C 80 24 24 4B 06", "Sigma 70-200mm f/2.8 EX APO DG Macro HSM II"}, - {"7A 54 6E 8E 24 24 4B 02", "Sigma APO 120-300mm f/2.8 EX DG HSM"}, - {"7B 48 80 98 30 30 80 0E", "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED"}, - {"7D 48 2B 53 24 24 82 06", "AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED"}, - {"7F 40 2D 5C 2C 34 84 06", "AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED"}, - {"7F 48 2B 5C 24 34 1C 06", "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF"}, - {"7F 48 2D 50 24 24 1C 06", "Sigma 18-50mm f/2.8 EX DC Macro"}, - {"80 48 1A 1A 24 24 85 06", "AF DX Fisheye-Nikkor 10.5mm f/2.8G ED"}, - {"81 34 76 A6 38 40 4B 0E", "Sigma 150-600mm f/5-6.3 DG OS HSM | S"}, - {"81 54 80 80 18 18 86 0E", "AF-S VR Nikkor 200mm f/2G IF-ED"}, - {"82 34 76 A6 38 40 4B 0E", "Sigma 150-600mm f/5-6.3 DG OS HSM | C"}, - {"82 48 8E 8E 24 24 87 0E", "AF-S VR Nikkor 300mm f/2.8G IF-ED"}, - {"83 00 B0 B0 5A 5A 88 04", "FSA-L2, EDG 65, 800mm f/13 G"}, - {"88 54 50 50 0C 0C 4B 06", "Sigma 50mm f/1.4 DG HSM | A"}, - {"89 3C 53 80 30 3C 8B 06", "AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED"}, - {"8A 3C 37 6A 30 30 4B 0E", "Sigma 24-105mm f/4 DG OS HSM"}, - {"8A 54 6A 6A 24 24 8C 0E", "AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED"}, - {"8B 40 2D 80 2C 3C 8D 0E", "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED"}, - {"8B 40 2D 80 2C 3C FD 0E", "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED [II]"}, - {"8B 4C 2D 44 14 14 4B 06", "Sigma 18-35mm f/1.8 DC HSM"}, - {"8C 40 2D 53 2C 3C 8E 06", "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED"}, - {"8D 44 5C 8E 34 3C 8F 0E", "AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED"}, - {"8D 48 6E 8E 24 24 4B 0E", "Sigma 120-300mm f/2.8 DG OS HSM Sports"}, - {"8E 3C 2B 5C 24 30 4B 0E", "Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C"}, - {"8F 40 2D 72 2C 3C 91 06", "AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED"}, - {"8F 48 2B 50 24 24 4B 0E", "Sigma 17-50mm f/2.8 EX DC OS HSM"}, - {"90 3B 53 80 30 3C 92 0E", "AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED"}, - {"90 40 2D 80 2C 40 4B 0E", "Sigma 18-200mm f/3.5-6.3 II DC OS HSM"}, - {"91 54 44 44 0C 0C 4B 06", "Sigma 35mm f/1.4 DG HSM"}, - {"92 2C 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, - {"92 48 24 37 24 24 94 06", "AF-S Zoom-Nikkor 14-24mm f/2.8G ED"}, - {"93 48 37 5C 24 24 95 06", "AF-S Zoom-Nikkor 24-70mm f/2.8G ED"}, - {"94 40 2D 53 2C 3C 96 06", "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II"}, - {"94 48 7C 7C 24 24 4B 0E", "Sigma APO Macro 180mm f/2.8 EX DG OS HSM"}, - {"95 00 37 37 2C 2C 97 06", "PC-E Nikkor 24mm f/3.5D ED"}, - {"95 4C 37 37 2C 2C 97 02", "PC-E Nikkor 24mm f/3.5D ED"}, - {"96 38 1F 37 34 3C 4B 06", "Sigma 12-24mm f/4.5-5.6 II DG HSM"}, - {"96 48 98 98 24 24 98 0E", "AF-S VR Nikkor 400mm f/2.8G ED"}, - {"97 3C A0 A0 30 30 99 0E", "AF-S VR Nikkor 500mm f/4G ED"}, - {"97 48 6A 6A 24 24 4B 0E", "Sigma Macro 105mm f/2.8 EX DG OS HSM"}, - {"98 3C A6 A6 30 30 9A 0E", "AF-S VR Nikkor 600mm f/4G ED"}, - {"98 48 50 76 24 24 4B 0E", "Sigma 50-150mm f/2.8 EX APO DC OS HSM"}, - {"99 40 29 62 2C 3C 9B 0E", "AF-S DX VR Zoom-Nikkor 16-85mm f/3.5-5.6G ED"}, - {"99 48 76 76 24 24 4B 0E", "Sigma APO Macro 150mm f/2.8 EX DG OS HSM"}, - {"9A 40 2D 53 2C 3C 9C 0E", "AF-S DX VR Zoom-Nikkor 18-55mm f/3.5-5.6G"}, - {"9A 4C 50 50 14 14 9C 06", "Yongnuo YN50mm f/1.8N"}, - {"9B 00 4C 4C 24 24 9D 06", "PC-E Micro Nikkor 45mm f/2.8D ED"}, - {"9B 54 4C 4C 24 24 9D 02", "PC-E Micro Nikkor 45mm f/2.8D ED"}, - {"9B 54 62 62 0C 0C 4B 06", "Sigma 85mm f/1.4 EX DG HSM"}, - {"9C 48 5C 80 24 24 4B 0E", "Sigma 70-200mm f/2.8 EX DG OS HSM"}, - {"9C 54 56 56 24 24 9E 06", "AF-S Micro Nikkor 60mm f/2.8G ED"}, - {"9D 00 62 62 24 24 9F 06", "PC-E Micro Nikkor 85mm f/2.8D"}, - {"9D 48 2B 50 24 24 4B 0E", "Sigma 17-50mm f/2.8 EX DC OS HSM"}, - {"9D 54 62 62 24 24 9F 02", "PC-E Micro Nikkor 85mm f/2.8D"}, - {"9E 38 11 29 34 3C 4B 06", "Sigma 8-16mm f/4.5-5.6 DC HSM"}, - {"9E 40 2D 6A 2C 3C A0 0E", "AF-S DX VR Zoom-Nikkor 18-105mm f/3.5-5.6G ED"}, - {"9F 37 50 A0 34 40 4B 0E", "Sigma 50-500mm f/4.5-6.3 DG OS HSM"}, - {"9F 58 44 44 14 14 A1 06", "AF-S DX Nikkor 35mm f/1.8G"}, - {"A0 40 2D 53 2C 3C CA 0E", "AF-P DX Nikkor 18-55mm f/3.5-5.6G VR"}, - {"A0 40 2D 53 2C 3C CA 8E", "AF-P DX Nikkor 18-55mm f/3.5-5.6G"}, - {"A0 40 2D 74 2C 3C BB 0E", "AF-S DX Nikkor 18-140mm f/3.5-5.6G ED VR"}, - {"A0 48 2A 5C 24 30 4B 0E", "Sigma 17-70mm f/2.8-4 DC Macro OS HSM"}, - {"A0 54 50 50 0C 0C A2 06", "AF-S Nikkor 50mm f/1.4G"}, - {"A1 40 18 37 2C 34 A3 06", "AF-S DX Nikkor 10-24mm f/3.5-4.5G ED"}, - {"A1 41 19 31 2C 2C 4B 06", "Sigma 10-20mm f/3.5 EX DC HSM"}, - {"A1 54 55 55 0C 0C BC 06", "AF-S Nikkor 58mm f/1.4G"}, - {"A2 38 5C 8E 34 40 CD 86", "AF-P DX Nikkor 70-300mm f/4.5-6.3G VR"}, - {"A2 40 2D 53 2C 3C BD 0E", "AF-S DX Nikkor 18-55mm f/3.5-5.6G VR II"}, - {"A2 48 5C 80 24 24 A4 0E", "AF-S Nikkor 70-200mm f/2.8G ED VR II"}, - {"A3 38 5C 8E 34 40 CE 0E", "AF-P DX Nikkor 70-300mm f/4.5-6.3G ED"}, - {"A3 38 5C 8E 34 40 CE 8E", "AF-P DX Nikkor 70-300mm f/4.5-6.3G ED VR"}, - {"A3 3C 29 44 30 30 A5 0E", "AF-S Nikkor 16-35mm f/4G ED VR"}, - {"A3 3C 5C 8E 30 3C 4B 0E", "Sigma 70-300mm f/4-5.6 DG OS"}, - {"A4 40 2D 8E 2C 40 BF 0E", "AF-S DX Nikkor 18-300mm f/3.5-6.3G ED VR"}, - {"A4 47 2D 50 24 34 4B 0E", "Sigma 18-50mm f/2.8-4.5 DC OS HSM"}, - {"A4 48 5C 80 24 24 CF 0E", "AF-S Nikkor 70-200mm f/2.8E FL ED VR"}, - {"A4 48 5C 80 24 24 CF 4E", "AF-S Nikkor 70-200mm f/2.8E FL ED VR"}, - {"A4 54 37 37 0C 0C A6 06", "AF-S Nikkor 24mm f/1.4G ED"}, - {"A5 40 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC OS HSM"}, - {"A5 40 3C 8E 2C 3C A7 0E", "AF-S Nikkor 28-300mm f/3.5-5.6G ED VR"}, - {"A5 4C 44 44 14 14 C0 06", "AF-S Nikkor 35mm f/1.8G ED"}, - {"A5 54 6A 6A 0C 0C D0 06", "AF-S Nikkor 105mm f/1.4E ED"}, - {"A5 54 6A 6A 0C 0C D0 46", "AF-S Nikkor 105mm f/1.4E ED"}, - {"A6 48 2F 2F 30 30 D1 06", "PC Nikkor 19mm f/4E ED"}, - {"A6 48 2F 2F 30 30 D1 46", "PC Nikkor 19mm f/4E ED"}, - {"A6 48 37 5C 24 24 4B 06", "Sigma 24-70mm f/2.8 IF EX DG HSM"}, - {"A6 48 8E 8E 24 24 A8 0E", "AF-S Nikkor 300mm f/2.8G IF-ED VR II"}, - {"A6 48 98 98 24 24 C1 0E", "AF-S Nikkor 400mm f/2.8E FL ED VR"}, - {"A7 3C 53 80 30 3C C2 0E", "AF-S DX Nikkor 55-200mm f/4-5.6G ED VR II"}, - {"A7 40 11 26 2C 34 D2 06", "AF-S Fisheye Nikkor 8-15mm f/3.5-4.5E ED"}, - {"A7 40 11 26 2C 34 D2 46", "AF-S Fisheye Nikkor 8-15mm f/3.5-4.5E ED"}, - {"A7 49 80 A0 24 24 4B 06", "Sigma APO 200-500mm f/2.8 EX DG"}, - {"A7 4B 62 62 2C 2C A9 0E", "AF-S DX Micro Nikkor 85mm f/3.5G ED VR"}, - {"A8 38 18 30 34 3C D3 0E", "AF-P DX Nikkor 10-20mm f/4.5-5.6G VR"}, - {"A8 38 18 30 34 3C D3 8E", "AF-P DX Nikkor 10-20mm f/4.5-5.6G VR"}, - {"A8 48 80 98 30 30 AA 0E", "AF-S Zoom-Nikkor 200-400mm f/4G IF-ED VR II"}, - {"A8 48 8E 8E 30 30 C3 0E", "AF-S Nikkor 300mm f/4E PF ED VR"}, - {"A8 48 8E 8E 30 30 C3 4E", "AF-S Nikkor 300mm f/4E PF ED VR"}, - {"A9 48 7C 98 30 30 D4 0E", "AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR"}, - {"A9 48 7C 98 30 30 D4 4E", "AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR"}, - {"A9 4C 31 31 14 14 C4 06", "AF-S Nikkor 20mm f/1.8G ED"}, - {"A9 54 80 80 18 18 AB 0E", "AF-S Nikkor 200mm f/2G ED VR II"}, - {"AA 3C 37 6E 30 30 AC 0E", "AF-S Nikkor 24-120mm f/4G ED VR"}, - {"AA 48 37 5C 24 24 C5 0E", "AF-S Nikkor 24-70mm f/2.8E ED VR"}, - {"AA 48 37 5C 24 24 C5 4E", "AF-S Nikkor 24-70mm f/2.8E ED VR"}, - {"AA 48 88 A4 3C 3C D5 0E", "AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR + 1.4x TC"}, - {"AA 48 88 A4 3C 3C D5 4E", "AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR + 1.4x TC"}, - {"AB 3C A0 A0 30 30 C6 4E", "AF-S Nikkor 500mm f/4E FL ED VR"}, - {"AB 44 5C 8E 34 3C D6 0E", "AF-P Nikkor 70-300mm f/4.5-5.6E ED VR"}, - {"AB 44 5C 8E 34 3C D6 CE", "AF-P Nikkor 70-300mm f/4.5-5.6E ED VR"}, - {"AC 38 53 8E 34 3C AE 0E", "AF-S DX Nikkor 55-300mm f/4.5-5.6G ED VR"}, - {"AC 3C A6 A6 30 30 C7 4E", "AF-S Nikkor 600mm f/4E FL ED VR"}, - {"AC 54 3C 3C 0C 0C D7 06", "AF-S Nikkor 28mm f/1.4E ED"}, - {"AC 54 3C 3C 0C 0C D7 46", "AF-S Nikkor 28mm f/1.4E ED"}, - {"AD 3C 2D 8E 2C 3C AF 0E", "AF-S DX Nikkor 18-300mm f/3.5-5.6G ED VR"}, - {"AD 3C A0 A0 3C 3C D8 0E", "AF-S Nikkor 500mm f/5.6E PF ED VR"}, - {"AD 3C A0 A0 3C 3C D8 4E", "AF-S Nikkor 500mm f/5.6E PF ED VR"}, - {"AD 48 28 60 24 30 C8 0E", "AF-S DX Nikkor 16-80mm f/2.8-4E ED VR"}, - {"AD 48 28 60 24 30 C8 4E", "AF-S DX Nikkor 16-80mm f/2.8-4E ED VR"}, - {"AE 3C 80 A0 3C 3C C9 0E", "AF-S Nikkor 200-500mm f/5.6E ED VR"}, - {"AE 3C 80 A0 3C 3C C9 4E", "AF-S Nikkor 200-500mm f/5.6E ED VR"}, - {"AE 54 62 62 0C 0C B0 06", "AF-S Nikkor 85mm f/1.4G"}, - {"AF 4C 37 37 14 14 CC 06", "AF-S Nikkor 24mm f/1.8G ED"}, - {"AF 54 44 44 0C 0C B1 06", "AF-S Nikkor 35mm f/1.4G"}, - {"B0 4C 50 50 14 14 B2 06", "AF-S Nikkor 50mm f/1.8G"}, - {"B1 48 48 48 24 24 B3 06", "AF-S DX Micro Nikkor 40mm f/2.8G"}, - {"B2 48 5C 80 30 30 B4 0E", "AF-S Nikkor 70-200mm f/4G ED VR"}, - {"B3 4C 62 62 14 14 B5 06", "AF-S Nikkor 85mm f/1.8G"}, - {"B4 40 37 62 2C 34 B6 0E", "AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED VR"}, - {"B5 4C 3C 3C 14 14 B7 06", "AF-S Nikkor 28mm f/1.8G"}, - {"B6 3C B0 B0 3C 3C B8 0E", "AF-S VR Nikkor 800mm f/5.6E FL ED"}, - {"B6 3C B0 B0 3C 3C B8 4E", "AF-S VR Nikkor 800mm f/5.6E FL ED"}, - {"B6 48 37 56 24 24 1C 02", "Sigma 24-60mm f/2.8 EX DG"}, - {"B7 44 60 98 34 3C B9 0E", "AF-S Nikkor 80-400mm f/4.5-5.6G ED VR"}, - {"B8 40 2D 44 2C 34 BA 06", "AF-S Nikkor 18-35mm f/3.5-4.5G ED"}, - {"BF 3C 1B 1B 30 30 01 04", "Irix 11mm f/4 Firefly"}, - {"BF 4E 26 26 1E 1E 01 04", "Irix 15mm f/2.4 Firefly"}, - {"C1 48 24 37 24 24 4B 46", "Sigma 14-24mm f/2.8 DG HSM | A"}, - {"C2 4C 24 24 14 14 4B 06", "Sigma 14mm f/1.8 DG HSM | A"}, - {"C3 34 68 98 38 40 4B 4E", "Sigma 100-400mm f/5-6.3 DG OS HSM | C"}, - {"C8 54 62 62 0C 0C 4B 46", "Sigma 85mm f/1.4 DG HSM | A"}, - {"C9 48 37 5C 24 24 4B 4E", "Sigma 24-70mm f/2.8 DG OS HSM | A"}, - {"CA 48 27 3E 24 24 DF 4E", "Tamron SP 15-30mm f/2.8 Di VC USD G2 (A041)"}, - {"CB 3C 2B 44 24 31 DF 46", "Tamron 17-35mm f/2.8-4 Di OSD (A037)"}, - {"CC 4C 50 68 14 14 4B 06", "Sigma 50-100mm f/1.8 DC HSM | A"}, - {"CD 3D 2D 70 2E 3C 4B 0E", "Sigma 18-125mm f/3.8-5.6 DC OS HSM"}, - {"CE 34 76 A0 38 40 4B 0E", "Sigma 150-500mm f/5-6.3 DG OS APO HSM"}, - {"CE 47 37 5C 25 25 DF 4E", "Tamron SP 24-70mm f/2.8 Di VC USD G2 (A032)"}, - {"CF 38 6E 98 34 3C 4B 0E", "Sigma APO 120-400mm f/4.5-5.6 DG OS HSM"}, - {"CF 47 5C 8E 31 3D DF 0E", "Tamron SP 70-300mm f/4-5.6 Di VC USD (A030)"}, - {"DC 48 19 19 24 24 4B 06", "Sigma 10mm f/2.8 EX DC HSM Fisheye"}, - {"DE 54 50 50 0C 0C 4B 06", "Sigma 50mm f/1.4 EX DG HSM"}, - {"E0 3C 5C 8E 30 3C 4B 06", "Sigma 70-300mm f/4-5.6 APO DG Macro HSM"}, - {"E0 40 2D 98 2C 41 DF 4E", "Tamron AF 18-400mm f/3.5-6.3 Di II VC HLD (B028)"}, - {"E1 40 19 36 2C 35 DF 4E", "Tamron 10-24mm f/3.5-4.5 Di II VC HLD (B023)"}, - {"E1 58 37 37 14 14 1C 02", "Sigma 24mm f/1.8 EX DG Aspherical Macro"}, - {"E2 47 5C 80 24 24 DF 4E", "Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)"}, - {"E3 40 76 A6 38 40 DF 4E", "Tamron SP 150-600mm f/5-6.3 Di VC USD G2"}, - {"E3 54 50 50 24 24 35 02", "Sigma Macro 50mm f/2.8 EX DG"}, - {"E4 54 64 64 24 24 DF 0E", "Tamron SP 90mm f/2.8 Di VC USD Macro 1:1 (F017)"}, - {"E5 54 6A 6A 24 24 35 02", "Sigma Macro 105mm f/2.8 EX DG"}, - {"E6 40 2D 80 2C 40 DF 0E", "Tamron AF 18-200mm f/3.5-6.3 Di II VC (B018)"}, - {"E6 41 3C 8E 2C 40 1C 02", "Sigma 28-300mm f/3.5-6.3 DG Macro"}, - {"E7 4C 4C 4C 14 14 DF 0E", "Tamron SP 45mm f/1.8 Di VC USD (F013)"}, - {"E8 4C 44 44 14 14 DF 0E", "Tamron SP 35mm f/1.8 Di VC USD (F012)"}, - {"E9 48 27 3E 24 24 DF 0E", "Tamron SP 15-30mm f/2.8 Di VC USD (A012)"}, - {"E9 54 37 5C 24 24 1C 02", "Sigma 24-70mm f/2.8 EX DG Macro"}, - {"EA 40 29 8E 2C 40 DF 0E", "Tamron AF 16-300mm f/3.5-6.3 Di II VC PZD (B016)"}, - {"EA 48 27 27 24 24 1C 02", "Sigma 15mm f/2.8 EX Diagonal Fisheye"}, - {"EB 40 76 A6 38 40 DF 0E", "Tamron SP AF 150-600mm f/5-6.3 VC USD (A011)"}, - {"ED 40 2D 80 2C 40 4B 0E", "Sigma 18-200mm f/3.5-6.3 DC OS HSM"}, - {"EE 48 5C 80 24 24 4B 06", "Sigma 70-200mm f/2.8 EX APO DG Macro HSM II"}, - {"F0 38 1F 37 34 3C 4B 06", "Sigma 12-24mm f/4.5-5.6 EX DG Aspherical HSM"}, - {"F0 3F 2D 8A 2C 40 DF 0E", "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)"}, - {"F1 44 A0 A0 34 34 4B 02", "Sigma APO 500mm f/4.5 EX DG HSM"}, - {"F1 47 5C 8E 30 3C DF 0E", "Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)"}, - {"F3 48 68 8E 30 30 4B 02", "Sigma APO 100-300mm f/4 EX IF HSM"}, - {"F3 54 2B 50 24 24 84 0E", "Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical (IF) (B005)"}, - {"F4 54 56 56 18 18 84 06", "Tamron SP AF 60mm f/2.0 Di II Macro 1:1 (G005)"}, - {"F5 40 2C 8A 2C 40 40 0E", "Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical (IF) Macro (B003)"}, - {"F5 48 76 76 24 24 4B 06", "Sigma APO Macro 150mm f/2.8 EX DG HSM"}, - {"F6 3F 18 37 2C 34 84 06", "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)"}, - {"F6 3F 18 37 2C 34 DF 06", "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)"}, - {"F6 48 2D 50 24 24 4B 06", "Sigma 18-50mm f/2.8 EX DC Macro"}, - {"F7 53 5C 80 24 24 40 06", "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"}, - {"F7 53 5C 80 24 24 84 06", "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"}, - {"F8 54 3E 3E 0C 0C 4B 06", "Sigma 30mm f/1.4 EX DC HSM"}, - {"F8 54 64 64 24 24 DF 06", "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)"}, - {"F8 55 64 64 24 24 84 06", "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)"}, - {"F9 3C 19 31 30 3C 4B 06", "Sigma 10-20mm f/4-5.6 EX DC HSM"}, - {"F9 40 3C 8E 2C 40 40 0E", "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical (IF) Macro (A20)"}, - {"FA 54 3C 5E 24 24 84 06", "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)"}, - {"FA 54 3C 5E 24 24 DF 06", "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)"}, - {"FA 54 6E 8E 24 24 4B 02", "Sigma APO 120-300mm f/2.8 EX DG HSM"}, - {"FB 54 2B 50 24 24 84 06", "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"}, - {"FB 54 8E 8E 24 24 4B 02", "Sigma APO 300mm f/2.8 EX DG HSM"}, - {"FC 40 2D 80 2C 40 DF 06", "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)"}, - {"FD 47 50 76 24 24 4B 06", "Sigma 50-150mm f/2.8 EX APO DC HSM II"}, - {"FE 47 00 00 24 24 4B 06", "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye"}, - {"FE 48 37 5C 24 24 DF 0E", "Tamron SP 24-70mm f/2.8 Di VC USD (A007)"}, - {"FE 53 5C 80 24 24 84 06", "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"}, - {"FE 54 5C 80 24 24 DF 0E", "Tamron SP 70-200mm f/2.8 Di VC USD (A009)"}, - {"FE 54 64 64 24 24 DF 0E", "Tamron SP 90mm f/2.8 Di VC USD Macro 1:1 (F004)"}, - {"FF 40 2D 80 2C 40 4B 06", "Sigma 18-200mm f/3.5-6.3 DC"}, - - // There are cases where one lens uses multiple IDs which change based on the focal length or aperture. - // These IDs cannot be listed using ExifTool, and so must be entered manually below. - // #4135 - - {"92 2B 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (210mm) - {"92 2C 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (185mm) - {"92 2D 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (155mm) - {"92 2E 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (130mm) - {"92 2F 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (105mm) - {"92 30 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (90mm) - {"92 32 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (75mm) - {"92 33 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (62mm) - {"92 35 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (52mm) - {"92 37 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (44mm) - {"92 39 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (38mm) - {"92 3A 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (32mm) - {"92 3E 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"}, // (22mm) - {"92 40 2D 88 2C 40 4B 0E", "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"} // (18mm) -}; - -const TagAttrib nikonISOInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "ISO", &naISOInfoISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, SHORT, "ISOExpansion", &naISOExpansionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "ISO2", &naISOInfoISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000a, SHORT, "ISOExpansion2", &naISOExpansionInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib nikon2Attribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "Unknown", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "Quality", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "ColorMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "ImageAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "ISOSpeed", &naISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "WhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0008, AUTO, "Focus", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0009, AUTO, "Unknown", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000a, AUTO, "DigitalZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000b, AUTO, "AuxiliaryLens", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0f00, AUTO, "Unknown", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib nikon3Attribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "MakerNoteVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "ISOSpeed", &naISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "ColorMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "Quality", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "WhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "FocusMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0008, AUTO, "FlashSetting", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0009, AUTO, "FlashType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000b, AUTO, "WhiteBalanceFineTune", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x000c, AUTO, "ColorBalance1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000d, AUTO, "ProgramShift", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000e, AUTO, "ExposureDifference", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "ISOSelection", &naISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0010, AUTO, "DataDump", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0011, AUTO, "NikonPreview", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0013, AUTO, "ISOSetting", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0016, AUTO, "ImageBoundary", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0018, AUTO, "FlashExposureBracketValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0019, AUTO, "ExposureBracketValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001a, AUTO, "ImageProcessing", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001b, AUTO, "CropHiSpeed", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001d, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001e, AUTO, "ColorSpace", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0020, AUTO, "ImageAuthentication", &stdInterpreter}, - {0, AC_WRITE, 0, nikonISOInfoAttribs, 0x0025, AUTO, "ISOInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0080, AUTO, "ImageAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0081, AUTO, "ToneComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0082, AUTO, "AuxiliaryLens", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0083, AUTO, "LensType", &naLensTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0084, AUTO, "Lens", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0085, AUTO, "ManualFocusDistance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0086, AUTO, "DigitalZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0087, AUTO, "FlashMode", &naFlashModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0088, AUTO, "AFInfo", &naAFInfoInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0089, AUTO, "ShootingMode", &naShootingModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008a, AUTO, "AutoBracketRelease", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008b, AUTO, "LensFStops", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008c, AUTO, "NEFCurve1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008d, AUTO, "ColorHue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008f, AUTO, "SceneMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0090, AUTO, "LightSource", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0091, AUTO, "ShotInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0092, AUTO, "HueAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0094, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0095, AUTO, "NoiseReduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0096, AUTO, "NEFCurve2", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x0097, AUTO, "ColorBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0098, AUTO, "LensData", &naLensDataInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0099, AUTO, "RawImageCenter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x009a, AUTO, "SensorPixelSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a0, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a2, AUTO, "ImageDataSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a5, AUTO, "ImageCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a6, AUTO, "DeletedImageCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a7, AUTO, "ShutterCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a9, AUTO, "ImageOptimization", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00aa, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00ab, AUTO, "VariProgram", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00ac, AUTO, "ImageStabilization", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00ad, AUTO, "AFResponse", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b0, AUTO, "MultiExposure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00b1, AUTO, "HighISONoiseReduction", &naHiISONRInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0x0e01, AUTO, "NikonCaptureData", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0x0e09, AUTO, "NikonCaptureVersion", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0x0e0e, AUTO, "NikonCaptureOffsets", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0x0e10, AUTO, "NikonScanIFD", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -} -#endif - diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc deleted file mode 100644 index e42763e35..000000000 --- a/rtexif/olympusattribs.cc +++ /dev/null @@ -1,846 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _OLYMPUSATTRIBS_ -#define _OLYMPUSATTRIBS_ - -#include -#include -#include -#include - -#include "rtexif.h" - -namespace rtexif -{ - -class OLOnOffInterpreter : public Interpreter -{ -public: - OLOnOffInterpreter () {} - std::string toString (const Tag* t) const override - { - if (t->toInt() == 0) { - return "Off"; - } else { - return "On"; - } - } -}; -OLOnOffInterpreter olOnOffInterpreter; - -class OLYesNoInterpreter : public Interpreter -{ -public: - OLYesNoInterpreter () {} - std::string toString (const Tag* t) const override - { - if (t->toInt() == 0) { - return "No"; - } else { - return "Yes"; - } - } -}; -OLYesNoInterpreter olYesNoInterpreter; - -class OLApertureInterpreter : public Interpreter -{ -public: - OLApertureInterpreter () {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - str.precision (2); - str << pow (2, t->toInt() / 512.0); - return str.str(); - } -}; -OLApertureInterpreter olApertureInterpreter; - -class OLLensTypeInterpreter : public Interpreter -{ - std::map lenses; -public: - OLLensTypeInterpreter () - { - lenses["00 01 00"] = "Olympus Zuiko Digital ED 50mm f/2.0 Macro"; - lenses["00 01 01"] = "Olympus Zuiko Digital 40-150mm f/3.5-4.5"; - lenses["00 01 10"] = "Olympus M.Zuiko Digital ED 14-42mm f/3.5-5.6"; - lenses["00 02 00"] = "Olympus Zuiko Digital ED 150mm f/2.0"; - lenses["00 02 10"] = "Olympus M.Zuiko Digital 17mm f/2.8 Pancake"; - lenses["00 03 00"] = "Olympus Zuiko Digital ED 300mm f/2.8"; - lenses["00 03 10"] = "Olympus M.Zuiko Digital ED 14-150mm f/4.0-5.6 [II]"; - lenses["00 04 10"] = "Olympus M.Zuiko Digital ED 9-18mm f/4.0-5.6"; - lenses["00 05 00"] = "Olympus Zuiko Digital 14-54mm f/2.8-3.5"; - lenses["00 05 01"] = "Olympus Zuiko Digital Pro ED 90-250mm f/2.8"; - lenses["00 05 10"] = "Olympus M.Zuiko Digital ED 14-42mm f/3.5-5.6 L"; - lenses["00 06 00"] = "Olympus Zuiko Digital ED 50-200mm f/2.8-3.5"; - lenses["00 06 01"] = "Olympus Zuiko Digital ED 8mm f/3.5 Fisheye"; - lenses["00 06 10"] = "Olympus M.Zuiko Digital ED 40-150mm f/4.0-5.6"; - lenses["00 07 00"] = "Olympus Zuiko Digital 11-22mm f/2.8-3.5"; - lenses["00 07 01"] = "Olympus Zuiko Digital 18-180mm f/3.5-6.3"; - lenses["00 07 10"] = "Olympus M.Zuiko Digital ED 12mm f/2.0"; - lenses["00 08 01"] = "Olympus Zuiko Digital 70-300mm f/4.0-5.6"; - lenses["00 08 10"] = "Olympus M.Zuiko Digital ED 75-300mm f/4.8-6.7"; - lenses["00 09 10"] = "Olympus M.Zuiko Digital 14-42mm f/3.5-5.6 II"; - lenses["00 10 01"] = "Kenko Tokina Reflex 300mm f/6.3 MF Macro"; - lenses["00 10 10"] = "Olympus M.Zuiko Digital ED 12-50mm f/3.5-6.3 EZ"; - lenses["00 11 10"] = "Olympus M.Zuiko Digital 45mm f/1.8"; - lenses["00 12 10"] = "Olympus M.Zuiko Digital ED 60mm f/2.8 Macro"; - lenses["00 13 10"] = "Olympus M.Zuiko Digital 14-42mm f/3.5-5.6 II R"; - lenses["00 14 10"] = "Olympus M.Zuiko Digital ED 40-150mm f/4.0-5.6 R"; - lenses["00 15 00"] = "Olympus Zuiko Digital ED 7-14mm f/4.0"; - lenses["00 15 10"] = "Olympus M.Zuiko Digital ED 75mm f/1.8"; - lenses["00 16 10"] = "Olympus M.Zuiko Digital 17mm f/1.8"; - lenses["00 17 00"] = "Olympus Zuiko Digital Pro ED 35-100mm f/2.0"; - lenses["00 18 00"] = "Olympus Zuiko Digital 14-45mm f/3.5-5.6"; - lenses["00 18 10"] = "Olympus M.Zuiko Digital ED 75-300mm f/4.8-6.7 II"; - lenses["00 19 10"] = "Olympus M.Zuiko Digital ED 12-40mm f/2.8 Pro"; - lenses["00 20 00"] = "Olympus Zuiko Digital 35mm f/3.5 Macro"; - lenses["00 20 10"] = "Olympus M.Zuiko Digital ED 40-150mm f/2.8 Pro"; - lenses["00 21 10"] = "Olympus M.Zuiko Digital ED 14-42mm f/3.5-5.6 EZ"; - lenses["00 22 00"] = "Olympus Zuiko Digital 17.5-45mm f/3.5-5.6"; - lenses["00 22 10"] = "Olympus M.Zuiko Digital 25mm f/1.8"; - lenses["00 23 00"] = "Olympus Zuiko Digital ED 14-42mm f/3.5-5.6"; - lenses["00 23 10"] = "Olympus M.Zuiko Digital ED 7-14mm f/2.8 Pro"; - lenses["00 24 00"] = "Olympus Zuiko Digital ED 40-150mm f/4.0-5.6"; - lenses["00 24 10"] = "Olympus M.Zuiko Digital ED 300mm f/4.0 IS Pro"; - lenses["00 25 10"] = "Olympus M.Zuiko Digital ED 8mm f/1.8 Fisheye Pro"; - lenses["00 26 10"] = "Olympus M.Zuiko Digital ED 12-100mm f/4.0 IS Pro"; - lenses["00 27 10"] = "Olympus M.Zuiko Digital ED 30mm f/3.5 Macro"; - lenses["00 28 10"] = "Olympus M.Zuiko Digital ED 25mm f/1.2 Pro"; - lenses["00 29 10"] = "Olympus M.Zuiko Digital ED 17mm f/1.2 Pro"; - lenses["00 30 00"] = "Olympus Zuiko Digital ED 50-200mm f/2.8-3.5 SWD"; - lenses["00 30 10"] = "Olympus M.Zuiko Digital ED 45mm f/1.2 Pro"; - lenses["00 31 00"] = "Olympus Zuiko Digital ED 12-60mm f/2.8-4.0 SWD"; - lenses["00 32 00"] = "Olympus Zuiko Digital ED 14-35mm f/2.0 SWD"; - lenses["00 33 00"] = "Olympus Zuiko Digital 25mm f/2.8"; - lenses["00 34 00"] = "Olympus Zuiko Digital ED 9-18mm f/4.0-5.6"; - lenses["00 35 00"] = "Olympus Zuiko Digital 14-54mm f/2.8-3.5 II"; - lenses["01 01 00"] = "Sigma 18-50mm f/3.5-5.6 DC"; - lenses["01 01 10"] = "Sigma 30mm f/2.8 EX DN"; - lenses["01 02 00"] = "Sigma 55-200mm f/4.0-5.6 DC"; - lenses["01 02 10"] = "Sigma 19mm f/2.8 EX DN"; - lenses["01 03 00"] = "Sigma 18-125mm f/3.5-5.6 DC"; - lenses["01 03 10"] = "Sigma 30mm f/2.8 DN | A"; - lenses["01 04 00"] = "Sigma 18-125mm f/3.5-5.6 DC"; - lenses["01 04 10"] = "Sigma 19mm f/2.8 DN | A"; - lenses["01 05 00"] = "Sigma 30mm f/1.4 EX DC HSM"; - lenses["01 05 10"] = "Sigma 60mm f/2.8 DN | A"; - lenses["01 06 00"] = "Sigma APO 50-500mm f/4.0-6.3 EX DG HSM"; - lenses["01 06 10"] = "Sigma 30mm f/1.4 DC DN | C"; - lenses["01 07 00"] = "Sigma Macro 105mm f/2.8 EX DG"; - lenses["01 07 10"] = "Sigma 16mm f/1.4 DC DN | C (017)"; - lenses["01 08 00"] = "Sigma APO Macro 150mm f/2.8 EX DG HSM"; - lenses["01 09 00"] = "Sigma 18-50mm f/2.8 EX DC Macro"; - lenses["01 10 00"] = "Sigma 24mm f/1.8 EX DG Aspherical Macro"; - lenses["01 11 00"] = "Sigma APO 135-400mm f/4.5-5.6 DG"; - lenses["01 12 00"] = "Sigma APO 300-800mm f/5.6 EX DG HSM"; - lenses["01 13 00"] = "Sigma 30mm f/1.4 EX DC HSM"; - lenses["01 14 00"] = "Sigma APO 50-500mm f/4.0-6.3 EX DG HSM"; - lenses["01 15 00"] = "Sigma 10-20mm f/4.0-5.6 EX DC HSM"; - lenses["01 16 00"] = "Sigma APO 70-200mm f/2.8 II EX DG Macro HSM"; - lenses["01 17 00"] = "Sigma 50mm f/1.4 EX DG HSM"; - lenses["02 01 00"] = "Leica D Vario Elmarit 14-50mm f/2.8-3.5 Asph."; - lenses["02 01 10"] = "Lumix G Vario 14-45mm f/3.5-5.6 Asph. Mega OIS"; - lenses["02 02 00"] = "Leica D Summilux 25mm f/1.4 Asph."; - lenses["02 02 10"] = "Lumix G Vario 45-200mm f/4.0-5.6 Mega OIS"; - lenses["02 03 00"] = "Leica D Vario Elmar 14-50mm f/3.8-5.6 Asph. Mega OIS"; - lenses["02 03 01"] = "Leica D Vario Elmar 14-50mm f/3.8-5.6 Asph."; - lenses["02 03 10"] = "Lumix G Vario HD 14-140mm f/4.0-5.8 Asph. Mega OIS"; - lenses["02 04 00"] = "Leica D Vario Elmar 14-150mm f/3.5-5.6"; - lenses["02 04 10"] = "Lumix G Vario 7-14mm f/4.0 Asph."; - lenses["02 05 10"] = "Lumix G 20mm f/1.7 Asph."; - lenses["02 06 10"] = "Leica DG Macro-Elmarit 45mm f/2.8 Asph. Mega OIS"; - lenses["02 07 10"] = "Lumix G Vario 14-42mm f/3.5-5.6 Asph. Mega OIS"; - lenses["02 08 10"] = "Lumix G Fisheye 8mm f/3.5"; - lenses["02 09 10"] = "Lumix G Vario 100-300mm f/4.0-5.6 Mega OIS"; - lenses["02 10 10"] = "Lumix G 14mm f/2.5 Asph."; - lenses["02 11 10"] = "Lumix G 12.5mm f/12 3D"; - lenses["02 12 10"] = "Leica DG Summilux 25mm f/1.4 Asph."; - lenses["02 13 10"] = "Lumix G X Vario PZ 45-175mm f/4.0-5.6 Asph. Power OIS"; - lenses["02 14 10"] = "Lumix G X Vario PZ 14-42mm f/3.5-5.6 Asph. Power OIS"; - lenses["02 15 10"] = "Lumix G X Vario 12-35mm f/2.8 Asph. Power OIS"; - lenses["02 16 10"] = "Lumix G Vario 45-150mm f/4.0-5.6 Asph. Mega OIS"; - lenses["02 17 10"] = "Lumix G X Vario 35-100mm f/2.8 Power OIS"; - lenses["02 18 10"] = "Lumix G Vario 14-42mm f/3.5-5.6 II Asph. Mega OIS"; - lenses["02 19 10"] = "Lumix G Vario 14-140mm f/3.5-5.6 Asph. Power OIS"; - lenses["02 20 10"] = "Lumix G Vario 12-32mm f/3.5-5.6 Asph. Mega OIS"; - lenses["02 21 10"] = "Leica DG Nocticron 42.5mm f/1.2 Asph. Power OIS"; - lenses["02 22 10"] = "Leica DG Summilux 15mm f/1.7 Asph."; - lenses["02 23 10"] = "Lumix G Vario 35-100mm f/4.0-5.6 Asph. Mega OIS"; - lenses["02 24 10"] = "Lumix G Macro 30mm f/2.8 Asph. Mega OIS"; - lenses["02 25 10"] = "Lumix G 42.5mm f/1.7 Asph. Power OIS"; - lenses["02 26 10"] = "Lumix G 25mm f/1.7 Asph."; - lenses["02 27 10"] = "Leica DG Vario-Elmar 100-400mm f/4.0-6.3 Asph. Power OIS"; - lenses["02 28 10"] = "Lumix G Vario 12-60mm f/3.5-5.6 Asph. Power OIS"; - lenses["03 01 00"] = "Leica D Vario Elmarit 14-50mm f/2.8-3.5 Asph."; - lenses["03 02 00"] = "Leica D Summilux 25mm f/1.4 Asph."; - lenses["05 01 10"] = "Tamron 14-150mm f/3.5-5.8 Di III"; - } - std::string toString (const Tag* t) const override - { - std::ostringstream lid; - lid.setf (std::ios_base::hex, std::ios_base::basefield); - lid.setf (std::ios_base::uppercase); - lid << std::setw (2) << std::setfill ('0') << t->toInt (0) << ' '; //maker - lid << std::setw (2) << std::setfill ('0') << t->toInt (2) << ' '; //model - lid << std::setw (2) << std::setfill ('0') << t->toInt (3); // submodel - - std::map::const_iterator r = lenses.find (lid.str()); - - if (r != lenses.end()) { - return r->second; - } else { - return "Unknown"; - } - } -}; -OLLensTypeInterpreter olLensTypeInterpreter; - -class OLFlashTypeInterpreter : public ChoiceInterpreter<> -{ -public: - OLFlashTypeInterpreter () - { - choices[0] = "None"; - choices[2] = "Simple E-System"; - choices[3] = "E-System"; - } -}; -OLFlashTypeInterpreter olFlashTypeInterpreter; - -class OLExposureModeInterpreter : public ChoiceInterpreter<> -{ -public: - OLExposureModeInterpreter () - { - choices[1] = "Manual"; - choices[2] = "Program"; - choices[3] = "Aperture-priority AE"; - choices[4] = "Shutter speed priority AE"; - choices[5] = "Program-shift"; - } -}; -OLExposureModeInterpreter olExposureModeInterpreter; - -class OLMeteringModeInterpreter : public ChoiceInterpreter<> -{ -public: - OLMeteringModeInterpreter () - { - choices[2] = "Center-weighted average"; - choices[3] = "Spot"; - choices[5] = "ESP"; - choices[261] = "Pattern+AF"; - choices[515] = "Spot+Highlight control"; - choices[1027] = "Spot+Shadow control"; - } -}; -OLMeteringModeInterpreter olMeteringModeInterpreter; - -class OLFocusModeInterpreter : public ChoiceInterpreter<> -{ -public: - OLFocusModeInterpreter () - { - choices[0] = "Single AF"; - choices[1] = "Sequential shooting AF"; - choices[2] = "Continuous AF"; - choices[3] = "Multi AF"; - choices[4] = "Face detect"; - choices[10] = "MF"; - } -}; -OLFocusModeInterpreter olFocusModeInterpreter; - -class OLWhitebalance2Interpreter : public ChoiceInterpreter<> -{ -public: - OLWhitebalance2Interpreter () - { - choices[0] = "Auto"; - choices[1] = "Auto (Keep Warm Color Off)"; - choices[16] = "7500K (Fine Weather with Shade)"; - choices[17] = "6000K (Cloudy)"; - choices[18] = "5300K (Fine Weather)"; - choices[20] = "3000K (Tungsten light)"; - choices[21] = "3600K (Tungsten light-like)"; - choices[22] = "Auto Setup"; - choices[23] = "5500K (Flash)"; - choices[33] = "6600K (Daylight fluorescent)"; - choices[34] = "4500K (Neutral white fluorescent)"; - choices[35] = "4000K (Cool white fluorescent)"; - choices[36] = "White Fluorescent"; - choices[48] = "3600K (Tungsten light-like)"; - choices[67] = "Underwater"; - choices[256] = "One Touch WB 1"; - choices[257] = "One Touch WB 2"; - choices[258] = "One Touch WB 3"; - choices[259] = "One Touch WB 4"; - choices[512] = "Custom WB 1"; - choices[513] = "Custom WB 2"; - choices[514] = "Custom WB 3"; - choices[515] = "Custom WB 4"; - } -}; -OLWhitebalance2Interpreter olWhitebalance2Interpreter; - -class OLSceneModeInterpreter : public ChoiceInterpreter<> -{ -public: - OLSceneModeInterpreter () - { - choices[0] = "Standard"; - choices[6] = "Auto"; - choices[7] = "Sport"; - choices[8] = "Portrait"; - choices[9] = "Landscape+Portrait"; - choices[10] = "Landscape"; - choices[11] = "Night Scene"; - choices[12] = "Self Portrait"; - choices[13] = "Panorama"; - choices[14] = "2 in 1"; - choices[15] = "Movie"; - choices[16] = "Landscape+Portrait"; - choices[17] = "Night+Portrait"; - choices[18] = "Indoor"; - choices[19] = "Fireworks"; - choices[20] = "Sunset"; - choices[21] = "Beauty Skin"; - choices[22] = "Macro"; - choices[23] = "Super Macro"; - choices[24] = "Food"; - choices[25] = "Documents"; - choices[26] = "Museum"; - choices[27] = "Shoot & Select"; - choices[28] = "Beach & Snow"; - choices[29] = "Self Protrait+Timer"; - choices[30] = "Candle"; - choices[31] = "Available Light"; - choices[32] = "Behind Glass"; - choices[33] = "My Mode"; - choices[34] = "Pet"; - choices[35] = "Underwater Wide1"; - choices[36] = "Underwater Macro"; - choices[37] = "Shoot & Select1"; - choices[38] = "Shoot & Select2"; - choices[39] = "High Key"; - choices[40] = "Digital Image Stabilization"; - choices[41] = "Auction"; - choices[42] = "Beach"; - choices[43] = "Snow"; - choices[44] = "Underwater Wide2"; - choices[45] = "Low Key"; - choices[46] = "Children"; - choices[47] = "Vivid"; - choices[48] = "Nature Macro"; - choices[49] = "Underwater Snapshot"; - choices[50] = "Shooting Guide"; - choices[54] = "Face Portrait"; - choices[57] = "Bulb"; - choices[59] = "Smile Shot"; - choices[60] = "Quick Shutter"; - choices[63] = "Slow Shutter"; - choices[64] = "Bird Watching"; - choices[65] = "Multiple Exposure"; - choices[66] = "e-Portrait"; - choices[67] = "Soft Background Shot"; - choices[142] = "Hand-held Starlight"; - choices[154] = "HDR"; - } -}; -OLSceneModeInterpreter olSceneModeInterpreter; - -class OLPictureModeBWFilterInterpreter : public ChoiceInterpreter<> -{ -public: - OLPictureModeBWFilterInterpreter () - { - choices[0] = "n/a"; - choices[1] = "Neutral"; - choices[2] = "Yellow"; - choices[3] = "Orange"; - choices[4] = "Red"; - choices[5] = "Green"; - } -}; -OLPictureModeBWFilterInterpreter olPictureModeBWFilterInterpreter; - -class OLPictureModeToneInterpreter : public ChoiceInterpreter<> -{ -public: - OLPictureModeToneInterpreter () - { - choices[0] = "n/a"; - choices[1] = "Neutral"; - choices[2] = "Sepia"; - choices[3] = "Blue"; - choices[4] = "Purple"; - choices[5] = "Green"; - } -}; -OLPictureModeToneInterpreter olPictureModeToneInterpreter; - -class OLImageQuality2Interpreter : public ChoiceInterpreter<> -{ -public: - OLImageQuality2Interpreter () - { - choices[1] = "SQ"; - choices[2] = "HQ"; - choices[3] = "SHQ"; - choices[4] = "RAW"; - choices[5] = "SQ (5)"; - } -}; -OLImageQuality2Interpreter olImageQuality2Interpreter; - -class OLDevEngineInterpreter : public ChoiceInterpreter<> -{ -public: - // RawDevEngine - OLDevEngineInterpreter () - { - choices[0] = "High Speed"; - choices[1] = "High Function"; - choices[2] = "Advanced High Speed"; - choices[3] = "Advanced High Function"; - } -}; -OLDevEngineInterpreter olDevEngineInterpreter; - -class OLPictureModeInterpreter : public ChoiceInterpreter<> -{ -public: - OLPictureModeInterpreter () - { - choices[1] = "Vivid"; - choices[2] = "Natural"; - choices[3] = "Muted"; - choices[4] = "Portrait"; - choices[5] = "i-Enhance"; - choices[7] = "Color Creator"; - choices[9] = "Color Profile 1"; - choices[10] = "Color Profile 2"; - choices[11] = "Color Profile 3"; - choices[12] = "Monochrome Profile 1"; - choices[13] = "Monochrome Profile 2"; - choices[14] = "Monochrome Profile 3"; - choices[256] = "Monotone"; - choices[512] = "Sepia"; - } -}; -OLPictureModeInterpreter olPictureModeInterpreter; - -class OLColorSpaceInterpreter : public ChoiceInterpreter<> -{ -public: - OLColorSpaceInterpreter () - { - choices[0] = "sRGB"; - choices[1] = "Adobe RGB"; - choices[2] = "Pro Photo RGB"; - } -}; -OLColorSpaceInterpreter olColorSpaceInterpreter; - -class OLNoiseFilterInterpreter : public Interpreter -{ -public: - OLNoiseFilterInterpreter () {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0); - int b = t->toInt (2); - int c = t->toInt (4); - - if (a == -1 && b == -2 && c == 1) { - return "Low"; - } else if (a == -2 && b == -2 && c == 1) { - return "Off"; - } else if (a == 0 && b == -2 && c == 1) { - return "Standard"; - } else if (a == 1 && b == -2 && c == 1) { - return "High"; - } else { - return "Unknown"; - } - } -}; -OLNoiseFilterInterpreter olNoiseFilterInterpreter; - -class OLFlashModeInterpreter : public Interpreter -{ -public: - OLFlashModeInterpreter () {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - int a = t->toInt (); - str << "Flash Used = " << ((a & 1) ? "Yes" : "No") << std::endl; - str << "Fill-in = " << ((a & 2) ? "On" : "Off") << std::endl; - str << "Red-eye = " << ((a & 4) ? "On" : "Off") << std::endl; - str << "Slow-sync = " << ((a & 8) ? "On" : "Off") << std::endl; - str << "Forced On = " << ((a & 16) ? "On" : "Off") << std::endl; - str << "2nd Curtain = " << ((a & 32) ? "On" : "Off"); - return str.str(); - } -}; -OLFlashModeInterpreter olFlashModeInterpreter; - -class OLNoiseReductionInterpreter : public Interpreter -{ -public: - OLNoiseReductionInterpreter () {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - int a = t->toInt (); - str << "Noise Reduction = " << ((a & 1) ? "On" : "Off") << std::endl; - str << "Noise Filter = " << ((a & 2) ? "On" : "Off") << std::endl; - str << "Noise Filter (ISO Boost) = " << ((a & 4) ? "On" : "Off") << std::endl; - str << "Auto = " << ((a & 8) ? "On" : "Off"); - return str.str(); - } -}; -OLNoiseReductionInterpreter olNoiseReductionInterpreter; - -class OLFlashModelInterpreter : public ChoiceInterpreter<> -{ -public: - OLFlashModelInterpreter () - { - choices[0] = "None"; - choices[1] = "FL-20"; - choices[2] = "FL-50"; - choices[3] = "RF-11"; - choices[4] = "TF-22"; - choices[5] = "FL-36"; - choices[6] = "FL-50R"; - choices[7] = "FL-36R"; - choices[9] = "FL-14"; - choices[11] = "FL-600R"; - } -}; -OLFlashModelInterpreter olFlashModelInterpreter; - -const TagAttrib olyFocusInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "FocusInfoVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0209, AUTO, "AutoFocus", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0210, AUTO, "SceneDetect", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0211, AUTO, "SceneArea", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0212, AUTO, "SceneDetectData", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0300, AUTO, "ZoomStepCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0301, AUTO, "FocusStepCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0303, AUTO, "FocusStepInfinity", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0304, AUTO, "FocusStepNear", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0305, AUTO, "FocusDistance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0308, AUTO, "AFPoint", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1201, AUTO, "ExternalFlash", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1203, AUTO, "ExternalFlashGuideNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1204, AUTO, "ExternalFlashBounce", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1205, AUTO, "ExternalFlashZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1208, AUTO, "InternalFlash", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1209, AUTO, "ManualFlash", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1500, AUTO, "SensorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1600, AUTO, "ImageStabilization", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olyImageProcessingAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "ImageProcessingVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0100, AUTO, "WB_RBLevels", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "WB_RBLevels3000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0103, AUTO, "WB_RBLevels3300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "WB_RBLevels3600K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0105, AUTO, "WB_RBLevels3900K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0106, AUTO, "WB_RBLevels4000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0107, AUTO, "WB_RBLevels4300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0108, AUTO, "WB_RBLevels4500K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0109, AUTO, "WB_RBLevels4800K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010a, AUTO, "WB_RBLevels5300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010b, AUTO, "WB_RBLevels6000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010c, AUTO, "WB_RBLevels6600K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010d, AUTO, "WB_RBLevels7500K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010e, AUTO, "WB_RBLevelsCWB1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010f, AUTO, "WB_RBLevelsCWB2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0110, AUTO, "WB_RBLevelsCWB3", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0111, AUTO, "WB_RBLevelsCWB4", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0113, AUTO, "WB_GLevel3000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0114, AUTO, "WB_GLevel3300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0115, AUTO, "WB_GLevel3600K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0116, AUTO, "WB_GLevel3900K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0117, AUTO, "WB_GLevel4000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0118, AUTO, "WB_GLevel4300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0119, AUTO, "WB_GLevel4500K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011a, AUTO, "WB_GLevel4800K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011b, AUTO, "WB_GLevel5300K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011c, AUTO, "WB_GLevel6000K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011d, AUTO, "WB_GLevel6600K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011e, AUTO, "WB_GLevel7500K", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x011f, AUTO, "WB_GLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0200, AUTO, "ColorMatrix", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0300, AUTO, "Enhancer", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0301, AUTO, "EnhancerValues", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0310, AUTO, "CoringFilter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0311, AUTO, "CoringValues", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0600, AUTO, "BlackLevel2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0610, AUTO, "GainBase", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0611, AUTO, "ValidBits", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0612, AUTO, "CropLeft", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0613, AUTO, "CropTop", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0614, AUTO, "CropWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0615, AUTO, "CropHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1010, AUTO, "NoiseReduction2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1011, AUTO, "DistortionCorrection2", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1012, AUTO, "ShadingCompensation2", &olOnOffInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x1103, AUTO, "UnknownBlock", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1200, AUTO, "FaceDetect", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1201, AUTO, "FaceDetectArea", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olyRawDevelopmentAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "RawDevVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0100, AUTO, "RawDevExposureBiasValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0101, AUTO, "RawDevWhiteBalanceValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "RawDevWBFineAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0103, AUTO, "RawDevGrayPoint", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "RawDevSaturationEmphasis", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0105, AUTO, "RawDevMemoryColorEmphasis", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0106, AUTO, "RawDevContrastValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0107, AUTO, "RawDevSharpnessValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0108, AUTO, "RawDevColorSpace", &olColorSpaceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0109, AUTO, "RawDevEngine", &olDevEngineInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010a, AUTO, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010b, AUTO, "RawDevEditStatus", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010c, AUTO, "RawDevSettings", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olyRawDevelopment2Attribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "RawDevVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0100, AUTO, "RawDevExposureBiasValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0101, AUTO, "RawDevWhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "RawDevWhiteBalanceValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0103, AUTO, "RawDevWBFineAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "RawDevGrayPoint", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0105, AUTO, "RawDevContrastValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0106, AUTO, "RawDevSharpnessValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0107, AUTO, "RawDevSaturationEmphasis", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0108, AUTO, "RawDevMemoryColorEmphasis", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0109, AUTO, "RawDevColorSpace", &olColorSpaceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010a, AUTO, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010b, AUTO, "RawDevEngine", &olDevEngineInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010c, AUTO, "RawDevPictureMode", &olPictureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010d, AUTO, "RawDevPMSaturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010e, AUTO, "RawDevPMContrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010f, AUTO, "RawDevPMSharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0110, AUTO, "RawDevPM_BWFilter", &olPictureModeBWFilterInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0111, AUTO, "RawDevPMPictureTone", &olPictureModeToneInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0112, AUTO, "RawDevGradation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0113, AUTO, "RawDevSaturation3", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0119, AUTO, "RawDevAutoGradation", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0120, AUTO, "RawDevPMNoiseFilter", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olyCameraSettingsAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "CameraSettingsVersion", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0100, AUTO, "PreviewImageValid", &olYesNoInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0101, AUTO, "PreviewImageStart", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0102, AUTO, "PreviewImageLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0200, AUTO, "ExposureMode", &olExposureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0201, AUTO, "AELock", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0202, AUTO, "MeteringMode", &olMeteringModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0300, AUTO, "MacroMode", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0301, AUTO, "FocusMode", &olFocusModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0302, AUTO, "FocusProcess", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0303, AUTO, "AFSearch", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0304, AUTO, "AFAreas", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0400, AUTO, "FlashMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0401, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0500, AUTO, "WhiteBalance2", &olWhitebalance2Interpreter}, - {0, AC_WRITE, 0, nullptr, 0x0501, AUTO, "WhiteBalanceTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0502, AUTO, "WhiteBalanceBracket", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0503, AUTO, "CustomSaturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0504, AUTO, "ModifiedSaturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0505, AUTO, "ContrastSetting", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0506, AUTO, "SharpnessSetting", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0507, AUTO, "ColorSpace", &olColorSpaceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0509, AUTO, "SceneMode", &olSceneModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x050a, AUTO, "NoiseReduction", &olNoiseReductionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x050b, AUTO, "DistortionCorrection", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x050c, AUTO, "ShadingCompensation", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x050d, AUTO, "CompressionFactor", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x050f, AUTO, "Gradation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0520, AUTO, "PictureMode", &olPictureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0521, AUTO, "PictureModeSaturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0522, AUTO, "PictureModeHue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0523, AUTO, "PictureModeContrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0524, AUTO, "PictureModeSharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0525, AUTO, "PictureModeBWFilter", &olPictureModeBWFilterInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0526, AUTO, "PictureModeTone", &olPictureModeToneInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0527, AUTO, "NoiseFilter", &olNoiseFilterInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0600, AUTO, "DriveMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0601, AUTO, "PanoramaMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0603, AUTO, "ImageQuality2", &olImageQuality2Interpreter}, - {0, AC_WRITE, 0, nullptr, 0x0900, AUTO, "ManometerPressure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0901, AUTO, "ManometerReading", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0902, AUTO, "ExtendedWBDetect", &olOnOffInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olyEquipmentAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "EquipmentVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0100, AUTO, "CameraType2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0101, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "InternalSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0103, AUTO, "FocalPlaneDiagonal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "BodyFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0201, AUTO, "LensType", &olLensTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0202, AUTO, "LensSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0204, AUTO, "LensFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0205, AUTO, "MaxApertureAtMinFocal", &olApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0206, AUTO, "MaxApertureAtMaxFocal", &olApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0207, AUTO, "MinFocalLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0208, AUTO, "MaxFocalLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020a, AUTO, "MaxApertureAtCurrentFocal", &olApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020b, AUTO, "LensProperties", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0301, AUTO, "Extender", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0302, AUTO, "ExtenderSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0303, AUTO, "ExtenderModel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0304, AUTO, "ExtenderFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1000, AUTO, "FlashType", &olFlashTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1001, AUTO, "FlashModel", &olFlashModelInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1002, AUTO, "FlashFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1003, AUTO, "FlashSerialNumber", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib olympusAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "BodyFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0200, AUTO, "SpecialMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0201, AUTO, "Quality", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0202, AUTO, "Macro", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0203, AUTO, "BWMode", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0204, AUTO, "DigitalZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0205, AUTO, "FocalPlaneDiagonal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0206, AUTO, "LensDistortionParams", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0207, AUTO, "CameraType", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0208, AUTO, "TextInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0209, AUTO, "CameraID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020b, AUTO, "EpsonImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020c, AUTO, "EpsonImageHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020d, AUTO, "EpsonSoftware", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0280, AUTO, "PreviewImage", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0300, AUTO, "PreCaptureFrames", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0301, AUTO, "WhiteBoard", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0302, AUTO, "OneTouchWB", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0303, AUTO, "WhiteBalanceBracket", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0304, AUTO, "WhiteBalanceBias", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0403, AUTO, "SceneMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0404, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0405, AUTO, "Firmware", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0f00, AUTO, "DataDump", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0f01, AUTO, "DataDump2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1000, AUTO, "ShutterSpeedValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1001, AUTO, "ISOValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1002, AUTO, "ApertureValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1003, AUTO, "BrightnessValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1004, AUTO, "FlashMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1005, AUTO, "FlashDevice", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1006, AUTO, "ExposureCompensation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1007, AUTO, "SensorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1008, AUTO, "LensTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1009, AUTO, "LightCondition", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100a, AUTO, "FocusRange", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100b, AUTO, "FocusMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100c, AUTO, "ManualFocusDistance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100d, AUTO, "ZoomStepCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100e, AUTO, "FocusStepCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x100f, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1010, AUTO, "FlashChargeLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1011, AUTO, "ColorMatrix", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1012, AUTO, "BlackLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1013, AUTO, "ColorTemperatureBG", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1014, AUTO, "ColorTemperatureRG", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1015, AUTO, "WBMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1017, AUTO, "RedBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1018, AUTO, "BlueBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1019, AUTO, "ColorMatrixNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101a, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101b, AUTO, "ExternalFlashAE1_0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101c, AUTO, "ExternalFlashAE2_0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101d, AUTO, "InternalFlashAE1_0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101e, AUTO, "InternalFlashAE2_0", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x101f, AUTO, "ExternalFlashAE1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1020, AUTO, "ExternalFlashAE2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1021, AUTO, "InternalFlashAE1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1022, AUTO, "InternalFlashAE2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1023, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1024, AUTO, "InternalFlashTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1025, AUTO, "ExternalFlashGValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1026, AUTO, "ExternalFlashBounce", &olYesNoInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1027, AUTO, "ExternalFlashZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1028, AUTO, "ExternalFlashMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1029, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102a, AUTO, "SharpnessFactor", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102b, AUTO, "ColorControl", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102c, AUTO, "ValidBits", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102d, AUTO, "CoringFilter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102e, AUTO, "OlympusImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x102f, AUTO, "OlympusImageHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1030, AUTO, "SceneDetect", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1031, AUTO, "SceneArea", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1033, AUTO, "SceneDetectData", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1034, AUTO, "CompressionRatio", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x1035, AUTO, "PreviewImageValid", &olYesNoInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x1036, AUTO, "PreviewImageStart", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x1037, AUTO, "PreviewImageLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1038, AUTO, "AFResult", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x1039, AUTO, "CCDScanMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103a, AUTO, "NoiseReduction", &olOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103b, AUTO, "InfinityLensStep", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103c, AUTO, "NearLensStep", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103d, AUTO, "LightValueCenter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103e, AUTO, "LightValuePeriphery", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x103f, AUTO, "FieldCount", &stdInterpreter}, - {0, AC_WRITE, 0, olyEquipmentAttribs, 0x2010, AUTO, "Equipment", &stdInterpreter}, - {0, AC_WRITE, 0, olyCameraSettingsAttribs, 0x2020, AUTO, "CameraSettings", &stdInterpreter}, - {0, AC_WRITE, 0, olyRawDevelopmentAttribs, 0x2030, AUTO, "RawDevelopment", &stdInterpreter}, - {0, AC_WRITE, 0, olyRawDevelopment2Attribs, 0x2031, AUTO, "RawDev2", &stdInterpreter}, - {0, AC_WRITE, 0, olyImageProcessingAttribs, 0x2040, AUTO, "ImageProcessing", &stdInterpreter}, - {0, AC_WRITE, 0, olyFocusInfoAttribs, 0x2050, AUTO, "FocusInfo", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2100, AUTO, "Olympus2100", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2300, AUTO, "Olympus2300", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2400, AUTO, "Olympus2400", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2500, AUTO, "Olympus2500", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2600, AUTO, "Olympus2600", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2700, AUTO, "Olympus2700", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2800, AUTO, "Olympus2800", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2900, AUTO, "Olympus2900", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x3000, AUTO, "RawInfo", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; -} -#endif - diff --git a/rtexif/panasonicattribs.cc b/rtexif/panasonicattribs.cc deleted file mode 100644 index 3062824cf..000000000 --- a/rtexif/panasonicattribs.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of RawTherapee. - */ -#ifndef _PANASONICATTRIBS_ -#define _PANASONICATTRIBS_ - -#include -#include "rtexif.h" - -namespace rtexif -{ - -// TODO: write interpreters - -const TagAttrib panasonicAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "Quality", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "FirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "WhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "FocusMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "AFMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001a, AUTO, "ImageStabilization", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001c, AUTO, "Macro", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001f, AUTO, "ShootingMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0020, AUTO, "Audio", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0023, AUTO, "WhiteBalanceBias", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0024, AUTO, "FlashBias", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0025, AUTO, "InternalSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "ExifVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0028, AUTO, "ColorEffect", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0029, AUTO, "TimeSincePowerOn", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002a, AUTO, "BurstMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002b, AUTO, "SequenceNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002c, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002d, AUTO, "NoiseReduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002e, AUTO, "SelfTimer", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0030, AUTO, "Rotation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0031, AUTO, "AFAssistLamp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0032, AUTO, "ColorMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0033, AUTO, "BabyAge1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0034, AUTO, "OpticalZoomMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0035, AUTO, "ConversionLens", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0036, AUTO, "TravelDay", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0039, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003a, AUTO, "WorldTimeLocation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003b, AUTO, "TextStamp1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003c, AUTO, "ProgramISO", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003d, AUTO, "AdvancedSceneType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003e, AUTO, "TextStamp2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003f, AUTO, "FacesDetected", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0040, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0041, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0042, AUTO, "FilmMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0044, AUTO, "ColorTempKelvin", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0045, AUTO, "BracketSettings", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0046, AUTO, "WBAdjustAB", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0047, AUTO, "WBAdjustGM", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0048, AUTO, "FlashCurtain", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0049, AUTO, "LongShutterNoiseReduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004b, AUTO, "ImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004c, AUTO, "ImageHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004d, AUTO, "AFPointPosition", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004e, AUTO, "FaceDetInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0051, AUTO, "LensType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0052, AUTO, "LensSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0053, AUTO, "AccessoryType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0054, AUTO, "AccessorySerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0059, AUTO, "Transform1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x005d, AUTO, "IntelligentExposure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0060, AUTO, "LensFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0061, AUTO, "FaceRecInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0062, AUTO, "FlashWarning", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0065, AUTO, "Title", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0066, AUTO, "BabyName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0067, AUTO, "Location", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0069, AUTO, "Country", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x006b, AUTO, "State", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x006d, AUTO, "City", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x006f, AUTO, "Landmark", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0070, AUTO, "IntelligentResolution", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0077, AUTO, "BurstSheed", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0079, AUTO, "IntelligentDRange", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x007c, AUTO, "ClearRetouch", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0080, AUTO, "City2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0086, AUTO, "ManometerPressure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0089, AUTO, "PhotoStyle", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008a, AUTO, "ShadingCompensation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008c, AUTO, "AccelerometerZ", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008d, AUTO, "AccelerometerX", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008e, AUTO, "AccelerometerY", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008f, AUTO, "CameraOrientation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0090, AUTO, "RollAngle", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0091, AUTO, "PitchAngle", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0093, AUTO, "SweepPanoramaDirection", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0094, AUTO, "PanoramaFieldOfView", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0096, AUTO, "TimerRecording", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x009d, AUTO, "InternalNDFilter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x009e, AUTO, "HDR", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x009f, AUTO, "ShutterType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00a3, AUTO, "ClearRetouchValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x00ab, AUTO, "TouchAE", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8000, AUTO, "MakerNoteVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8001, AUTO, "SceneMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8004, AUTO, "WBRedLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8005, AUTO, "WBGreenLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8006, AUTO, "WBBlueLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8007, AUTO, "FlashFired", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8008, AUTO, "TextStamp3", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8009, AUTO, "TextStamp4", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8010, AUTO, "BabyAge2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8012, AUTO, "Transform2", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - -const TagAttrib panasonicRawAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "Version", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "SensorWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "SensorHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "SensorTopBorder", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "SensorLeftBorder", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "ImageHeight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "ImageWidth", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0011, AUTO, "RedBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "BlueBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0017, AUTO, "ISOSpeed", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0024, AUTO, "WBRedLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0025, AUTO, "WBGreenLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "WBBlueLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002e, AUTO, "PreviewImage", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010f, AUTO, "Make", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0110, AUTO, "Model", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0111, AUTO, "StripOffsets", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0112, AUTO, "Orientation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0116, AUTO, "RowsPerStrip", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0117, AUTO, "StripByteCounts", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0118, AUTO, "RawDataOffset", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - -} -#endif - diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc deleted file mode 100644 index 7e861d64f..000000000 --- a/rtexif/pentaxattribs.cc +++ /dev/null @@ -1,2219 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _PENTAXATTRIBS_ -#define _PENTAXATTRIBS_ - -#include -#include -#include /* memcpy() */ -#include -#include - -#include "rtexif.h" - -namespace rtexif -{ - - -class PAQualityInterpreter : public ChoiceInterpreter<> -{ -public: - PAQualityInterpreter () - { - choices[0] = "Good"; - choices[1] = "Better"; - choices[2] = "Best"; - choices[3] = "TIFF"; - choices[4] = "RAW"; - choices[5] = "Premium"; - choices[6] = "RAW (HDR enabled)"; - choices[7] = "RAW (pixel shift enabled)"; - choices[8] = "RAW (pixel shift handheld mode enabled)"; - choices[65535] = "n/a"; - } -}; -PAQualityInterpreter paQualityInterpreter; - -class PAOnOffInterpreter : public ChoiceInterpreter<> -{ -public: - PAOnOffInterpreter () - { - choices[0] = "Off"; - choices[1] = "On"; - } -}; -PAOnOffInterpreter paOnOffInterpreter; - -class PAShakeReductionInterpreter : public ChoiceInterpreter<> -{ -public: - PAShakeReductionInterpreter () - { - choices[ 0] = "Off"; - choices[ 1] = "On"; - choices[ 4] = "On (4)"; - choices[ 5] = "On but Disabled"; - choices[ 6] = "On (Video)"; - choices[ 7] = "On (7)"; - choices[ 15] = "On (15)"; - choices[ 39] = "On (mode 2)"; - choices[135] = "On (135)"; - choices[167] = "On (mode 1)"; - } -}; -PAShakeReductionInterpreter paShakeReductionInterpreter; - -class PAShakeReduction2Interpreter : public ChoiceInterpreter<> -{ -public: - // ShakeReduction - PAShakeReduction2Interpreter () - { - choices[ 0] = "Off"; - choices[ 1] = "On"; - choices[ 4] = "Off (AA simulation off)"; - choices[ 5] = "On but Disabled"; - choices[ 6] = "On (Video)"; - choices[ 7] = "On (AA simulation off)"; - choices[12] = "Off (AA simulation type 1)"; - choices[15] = "On (AA simulation type 1)"; - choices[20] = "Off (AA simulation type 2)"; - choices[23] = "On (AA simulation type 2)"; - } -}; -PAShakeReduction2Interpreter paShakeReduction2Interpreter; - -class PAPictureModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAPictureModeInterpreter () - { - choices[0] = "Program"; - choices[1] = "Shutter Speed Priority"; - choices[2] = "Program AE"; - choices[3] = "Manual"; - choices[5] = "Portrait"; - choices[6] = "Landscape"; - choices[8] = "Sport"; - choices[9] = "Night Scene"; - choices[11] = "Soft"; - choices[12] = "Surf & Snow"; - choices[13] = "Candlelight"; - choices[14] = "Autumn"; - choices[15] = "Macro"; - choices[17] = "Fireworks"; - choices[18] = "Text"; - choices[19] = "Panorama"; - choices[20] = "3-D"; - choices[21] = "Black & White"; - choices[22] = "Sepia"; - choices[23] = "Red"; - choices[24] = "Pink"; - choices[25] = "Purple"; - choices[26] = "Blue"; - choices[27] = "Green"; - choices[28] = "Yellow"; - choices[30] = "Self Portrait"; - choices[31] = "Illustrations"; - choices[33] = "Digital Filter"; - choices[35] = "Night Scene Portrait"; - choices[37] = "Museum"; - choices[38] = "Food"; - choices[39] = "Underwater"; - choices[40] = "Green Mode"; - choices[49] = "Light Pet"; - choices[50] = "Dark Pet"; - choices[51] = "Medium Pet"; - choices[53] = "Underwater"; - choices[54] = "Candlelight"; - choices[55] = "Natural Skin Tone"; - choices[56] = "Synchro Sound Record"; - choices[58] = "Frame Composite"; - choices[59] = "Report"; - choices[60] = "Kids"; - choices[61] = "Blur Reduction"; - choices[63] = "Panorama 2"; - choices[65] = "Half-length Portrait"; - choices[66] = "Portrait 2"; - choices[74] = "Digital Microscope"; - choices[75] = "Blue Sky"; - choices[80] = "Miniature"; - choices[81] = "HDR"; - choices[83] = "Fisheye"; - choices[85] = "Digital Filter 4"; - choices[221] = "P"; - choices[255] = "PICT"; - } -}; -PAPictureModeInterpreter paPictureModeInterpreter; - -class PASceneModeInterpreter : public ChoiceInterpreter<> -{ -public: - PASceneModeInterpreter () - { - choices[0] = "Off"; - choices[1] = "HDR"; - choices[4] = "Auto PICT"; - choices[5] = "Portrait"; - choices[6] = "Landscape"; - choices[7] = "Macro"; - choices[8] = "Sport"; - choices[9] = "Night Scene Portrait"; - choices[10] = "No Flash"; - choices[11] = "Night Scene"; - choices[12] = "Surf & Snow"; - choices[14] = "Sunset"; - choices[15] = "Kids"; - choices[16] = "Pet"; - choices[17] = "Candlelight"; - choices[18] = "Museum"; - choices[20] = "Food"; - choices[21] = "Stage Lighting"; - choices[22] = "Night Snap"; - choices[25] = "Night Scene HDR"; - choices[26] = "Blue Sky"; - choices[27] = "Forest"; - choices[29] = "Backlight Silhouette"; - } -}; -PASceneModeInterpreter paSceneModeInterpreter; - -class PAAEProgramModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAAEProgramModeInterpreter () - { - choices[0] = "M, P or TAv"; - choices[1] = "Av, B or X"; - choices[2] = "Tv"; - choices[3] = "Sv or Green Mode"; - choices[8] = "Hi-speed Program"; - choices[11] = "Hi-speed Program (P-Shift)"; - choices[16] = "DOF Program"; - choices[19] = "DOF Program (P-Shift)"; - choices[24] = "MTF Program"; - choices[27] = "MTF Program (P-Shift)"; - choices[35] = "Standard"; - choices[43] = "Portrait"; - choices[51] = "Landscape"; - choices[59] = "Macro"; - choices[67] = "Sport"; - choices[75] = "Night Scene Portrait"; - choices[83] = "No Flash"; - choices[91] = "Night Scene"; - choices[99] = "Surf & Snow"; - choices[104] = "Night Snap"; - choices[107] = "Text"; - choices[115] = "Sunset"; - choices[123] = "Kids"; - choices[131] = "Pet"; - choices[139] = "Candlelight"; - choices[144] = "SCN"; - choices[147] = "Museum"; - choices[160] = "Program"; - choices[184] = "Shallow DOF Program"; - choices[216] = "HDR"; - } -}; -PAAEProgramModeInterpreter paAEProgramModeInterpreter; - -class PAFlashModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAFlashModeInterpreter () - { - choices[0] = "Auto, Did not fire"; - choices[1] = "Off, Did not fire"; - choices[2] = "On, Did not fire"; - choices[3] = "Auto, Did not fire, Red-eye reduction"; - choices[5] = "On, Did not fire, Wireless (Master)"; - choices[256] = "Auto, Fired"; - choices[258] = "On, Fired"; - choices[259] = "Auto, Fired, Red-eye reduction"; - choices[260] = "On, Red-eye reduction"; - choices[261] = "On, Wireless (Master)"; - choices[262] = "On, Wireless (Control)"; - choices[264] = "On, Soft"; - choices[265] = "On, Slow-sync"; - choices[266] = "On, Slow-sync, Red-eye reduction"; - choices[267] = "On, Trailing-curtain Sync"; - } -}; -PAFlashModeInterpreter paFlashModeInterpreter; - -class PAFocusModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAFocusModeInterpreter () - { - choices[0] = "Normal"; - choices[1] = "Macro"; - choices[2] = "Infinity"; - choices[3] = "Manual"; - choices[4] = "Super Macro"; - choices[5] = "Pan Focus"; - choices[16] = "AF-S (Focus-priority)"; - choices[17] = "AF-C (Focus-priority)"; - choices[18] = "AF-A (Focus-priority)"; - choices[32] = "Contrast-detect (Focus-priority)"; - choices[33] = "Tracking Contrast-detect (Focus-priority)"; - choices[272] = "AF-S (Release-priority)"; - choices[273] = "AF-C (Release-priority)"; - choices[274] = "AF-A (Release-priority)"; - choices[288] = "Contrast-detect (Release-priority)"; - } -}; -PAFocusModeInterpreter paFocusModeInterpreter; - -class PAAFPointInterpreter : public ChoiceInterpreter<> -{ -public: - // AFPointSelected - PAAFPointInterpreter () - { - choices[0] = "None"; - choices[1] = "Upper-left"; - choices[2] = "Top"; - choices[3] = "Upper-right"; - choices[4] = "Left"; - choices[5] = "Mid-left"; - choices[6] = "Center"; - choices[7] = "Mid-right"; - choices[8] = "Right"; - choices[9] = "Lower-left"; - choices[10] = "Bottom"; - choices[11] = "Lower-right"; - choices[65531] = "AF Select"; - choices[65532] = "Face Detect AF"; - choices[65533] = "Automatic Tracking AF"; - choices[65534] = "Fixed Center"; - choices[65535] = "Auto"; - } -}; -PAAFPointInterpreter paAFPointInterpreter; - -class PAAFFocusInterpreter : public ChoiceInterpreter<> -{ -public: - // AFPointsInFocus - PAAFFocusInterpreter () - { - choices[0] = "Fixed Center or Multiple"; - choices[1] = "Top-left"; - choices[2] = "Top-center"; - choices[3] = "Top-right"; - choices[4] = "Left"; - choices[5] = "Center"; - choices[6] = "Right"; - choices[7] = "Bottom-left"; - choices[8] = "Bottom-center"; - choices[9] = "Bottom-right"; - choices[65535] = "None"; - } -}; -PAAFFocusInterpreter paAFFocusInterpreter; - -class PAISOInterpreter : public ChoiceInterpreter<> -{ -public: - PAISOInterpreter () - { - choices[3] = "50"; - choices[4] = "64"; - choices[5] = "80"; - choices[6] = "100"; - choices[7] = "125"; - choices[8] = "160"; - choices[9] = "200"; - choices[10] = "250"; - choices[11] = "320"; - choices[12] = "400"; - choices[13] = "500"; - choices[14] = "640"; - choices[15] = "800"; - choices[16] = "1000"; - choices[17] = "1250"; - choices[18] = "1600"; - choices[19] = "2000"; - choices[20] = "2500"; - choices[21] = "3200"; - choices[22] = "4000"; - choices[23] = "5000"; - choices[24] = "6400"; - choices[25] = "8000"; - choices[26] = "10000"; - choices[27] = "12800"; - choices[28] = "16000"; - choices[29] = "20000"; - choices[30] = "25600"; - choices[31] = "32000"; - choices[32] = "40000"; - choices[33] = "51200"; - choices[34] = "64000"; - choices[35] = "80000"; - choices[36] = "102400"; - choices[37] = "128000"; - choices[38] = "160000"; - choices[39] = "204800"; - choices[40] = "256000"; - choices[41] = "320000"; - choices[42] = "409600"; - choices[43] = "512000"; - choices[44] = "640000"; - choices[45] = "819200"; - choices[50] = "50"; - choices[100] = "100"; - choices[200] = "200"; - choices[258] = "50"; - choices[259] = "70"; - choices[260] = "100"; - choices[261] = "140"; - choices[262] = "200"; - choices[263] = "280"; - choices[264] = "400"; - choices[265] = "560"; - choices[266] = "800"; - choices[267] = "1100"; - choices[268] = "1600"; - choices[269] = "2200"; - choices[270] = "3200"; - choices[271] = "4500"; - choices[272] = "6400"; - choices[273] = "9000"; - choices[274] = "12800"; - choices[275] = "18000"; - choices[276] = "25600"; - choices[277] = "36000"; - choices[278] = "51200"; - choices[400] = "400"; - choices[800] = "800"; - choices[1600] = "1600"; - choices[3200] = "3200"; - } -}; -PAISOInterpreter paISOInterpreter; - -class PAFNumberInterpreter: public Interpreter -{ -public: - PAFNumberInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = t->toDouble() / 10; - - if ( v < 0. || v > 1000. ) { - return "undef"; - } - - sprintf (buffer, "%.1f", v ); - return buffer; - } -}; -PAFNumberInterpreter paFNumberInterpreter; - -class PAMeteringModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAMeteringModeInterpreter () - { - choices[0] = "Multi-segment"; - choices[1] = "Center-weighted average"; - choices[2] = "Spot"; - } -}; -PAMeteringModeInterpreter paMeteringModeInterpreter; - -class PAWhiteBalanceInterpreter : public ChoiceInterpreter<> -{ -public: - PAWhiteBalanceInterpreter () - { - choices[0] = "Auto"; - choices[1] = "Daylight"; - choices[2] = "Shade"; - choices[3] = "Fluorescent"; - choices[4] = "Tungsten"; - choices[5] = "Manual"; - choices[6] = "Daylight Fluorescent"; - choices[7] = "Day White Fluorescent"; - choices[8] = "White Fluorescent"; - choices[9] = "Flash"; - choices[10] = "Cloudy"; - choices[11] = "Warm White Fluorescent"; - choices[14] = "Multi Auto"; - choices[15] = "Color Temperature Enhancement"; - choices[17] = "Kelvin"; - choices[65534] = "Unknown"; - choices[65535] = "User-Selected"; - } -}; -PAWhiteBalanceInterpreter paWhiteBalanceInterpreter; - -class PAWhiteBalanceModeInterpreter : public ChoiceInterpreter<> -{ -public: - PAWhiteBalanceModeInterpreter () - { - choices[1] = "Auto (Daylight)"; - choices[2] = "Auto (Shade)"; - choices[3] = "Auto (Flash)"; - choices[4] = "Auto (Tungsten)"; - choices[6] = "Auto (Daylight Fluorescent)"; - choices[7] = "Auto (Day White Fluorescent)"; - choices[8] = "Auto (White Fluorescent)"; - choices[10] = "Auto (Cloudy)"; - choices[65534] = "Unknown"; - choices[65535] = "User-Selected"; - } -}; -PAWhiteBalanceModeInterpreter paWhiteBalanceModeInterpreter; - -class PASaturationInterpreter : public ChoiceInterpreter<> -{ -public: - PASaturationInterpreter () - { - choices[0] = "-2 (low)"; - choices[1] = "0 (normal)"; - choices[2] = "+2 (high)"; - choices[3] = "-1 (med low)"; - choices[4] = "+1 (med high)"; - choices[5] = "-3 (very low)"; - choices[6] = "+3 (very high)"; - choices[7] = "-4 (minimum)"; - choices[8] = "+4 (maximum)"; - choices[65535] = "None"; - } -}; -PASaturationInterpreter paSaturationInterpreter; - -class PAContrastInterpreter : public ChoiceInterpreter<> -{ -public: - PAContrastInterpreter () - { - choices[0] = "-2 (low)"; - choices[1] = "0 (normal)"; - choices[2] = "+2 (high)"; - choices[3] = "-1 (med low)"; - choices[4] = "+1 (med high)"; - choices[5] = "-3 (very low)"; - choices[6] = "+3 (very high)"; - choices[7] = "-4 (minimum)"; - choices[8] = "+4 (maximum)"; - choices[65535] = "n/a"; - } -}; -PAContrastInterpreter paContrastInterpreter; - -class PASharpnessInterpreter : public ChoiceInterpreter<> -{ -public: - PASharpnessInterpreter () - { - choices[0] = "-2 (soft)"; - choices[1] = "0 (normal)"; - choices[2] = "+2 (hard)"; - choices[3] = "-1 (med soft)"; - choices[4] = "+1 (med hard)"; - choices[5] = "-3 (very soft)"; - choices[6] = "+3 (very hard)"; - choices[7] = "-4 (minimum)"; - choices[8] = "+4 (maximum)"; - } -}; -PASharpnessInterpreter paSharpnessInterpreter; - -class PAPictureModeInterpreter2: public ChoiceInterpreter<> -{ -public: - PAPictureModeInterpreter2() - { - choices[256 * 0 + 0] = "Program"; - choices[256 * 0 + 1] = "Hi-speed Program"; - choices[256 * 0 + 2] = "DOF Program"; - choices[256 * 0 + 3] = "MTF Program"; - choices[256 * 0 + 4] = "Standard"; - choices[256 * 0 + 5] = "Portrait"; - choices[256 * 0 + 6] = "Landscape"; - choices[256 * 0 + 7] = "Macro"; - choices[256 * 0 + 8] = "Sport"; - choices[256 * 0 + 9] = "Night Scene Portrait"; - choices[256 * 0 + 10] = "No Flash"; - choices[256 * 0 + 11] = "Night Scene"; - choices[256 * 0 + 12] = "Surf & Snow"; - choices[256 * 0 + 13] = "Text"; - choices[256 * 0 + 14] = "Sunset"; - choices[256 * 0 + 15] = "Kids"; - choices[256 * 0 + 16] = "Pet"; - choices[256 * 0 + 17] = "Candlelight"; - choices[256 * 0 + 18] = "Museum"; - choices[256 * 0 + 19] = "Food"; - choices[256 * 0 + 20] = "Stage Lighting"; - choices[256 * 0 + 21] = "Night Snap"; - choices[256 * 0 + 23] = "Blue Sky"; - choices[256 * 0 + 24] = "Sunset"; - choices[256 * 0 + 26] = "Night Scene HDR"; - choices[256 * 0 + 27] = "HDR"; - choices[256 * 0 + 28] = "Quick Macro"; - choices[256 * 0 + 29] = "Forest"; - choices[256 * 0 + 30] = "Backlight Silhouette"; - choices[256 * 1 + 4] = "Auto PICT (Standard)"; - choices[256 * 1 + 5] = "Auto PICT (Portrait)"; - choices[256 * 1 + 6] = "Auto PICT (Landscape)"; - choices[256 * 1 + 7] = "Auto PICT (Macro)"; - choices[256 * 1 + 8] = "Auto PICT (Sport)"; - choices[256 * 2 + 0] = "Program (HyP)"; - choices[256 * 2 + 1] = "Hi-speed Program (HyP)"; - choices[256 * 2 + 2] = "DOF Program (HyP)"; - choices[256 * 2 + 3] = "MTF Program (HyP)"; - choices[256 * 2 + 22] = "Shallow DOF (HyP)"; - choices[256 * 3 + 0] = "Green Mode"; - choices[256 * 4 + 0] = "Shutter Speed Priority"; - choices[256 * 5 + 0] = "Aperture Priority"; - choices[256 * 6 + 0] = "Program Tv Shift"; - choices[256 * 7 + 0] = "Program Av Shift"; - choices[256 * 8 + 0] = "Manual"; - choices[256 * 9 + 0] = "Bulb"; - choices[256 * 10 + 0] = "Aperture Priority, Off-Auto-Aperture"; - choices[256 * 11 + 0] = "Manual, Off-Auto-Aperture"; - choices[256 * 12 + 0] = "Bulb, Off-Auto-Aperture"; - choices[256 * 13 + 0] = "Shutter & Aperture Priority AE"; - choices[256 * 15 + 0] = "Sensitivity Priority AE"; - choices[256 * 16 + 0] = "Flash X-Sync Speed AE"; - choices[256 * 18 + 0] = "Auto Program (Normal)"; - choices[256 * 18 + 1] = "Auto Program (Hi-speed)"; - choices[256 * 18 + 2] = "Auto Program (DOF)"; - choices[256 * 18 + 3] = "Auto Program (MTF)"; - choices[256 * 18 + 22] = "Auto Program (Shallow DOF)"; - choices[256 * 20 + 22] = "Blur Control"; - choices[256 * 254 + 0] = "Video"; - choices[256 * 255 + 0] = "Video (Auto Aperture)"; - choices[256 * 255 + 4] = "Video (4)"; - } - std::string toString (const Tag* t) const override - { - int c = 256 * t->toInt (0, BYTE) + t->toInt (1, BYTE); - const ChoicesIterator r = choices.find (c); - - if (r != choices.end()) { - std::ostringstream s; - s << r->second; - - if ( t->toInt (1, BYTE) == 0 ) { - s << "\n1/2 EV steps"; - } else { - s << "\n1/3 EV steps"; - } - - return s.str(); - } else { - char buffer[1024]; - t->toString (buffer); - return std::string (buffer); - } - } -}; -PAPictureModeInterpreter2 paPictureModeInterpreter2; - -class PADriveModeInterpreter : public ChoiceInterpreter<> -{ - std::map choices1; - std::map choices2; - std::map choices3; -public: - PADriveModeInterpreter() - { - choices[0] = "Single-frame"; - choices[1] = "Continuous"; - choices[2] = "Continuous (Lo)"; - choices[3] = "Burst"; - choices[4] = "Continuous (Medium)"; - choices[255] = "Video"; - choices1[0] = "No Timer"; - choices1[1] = "Self-timer (12 s)"; - choices1[2] = "Self-timer (2 s)"; - choices1[15] = "Video"; - choices1[16] = "Mirror Lock-up"; - choices1[255] = "n/a"; - choices2[0] = "Shutter Button"; - choices2[1] = "Remote Control (3 s delay)"; - choices2[2] = "Remote Control"; - choices2[4] = "Remote Continuous Shooting"; - choices3[0] = "Single Exposure"; - choices3[1] = "Multiple Exposure"; - choices3[15] = "Interval Movie"; - choices3[16] = "HDR"; - choices3[32] = "HDR Strong 1"; - choices3[48] = "HDR Strong 2"; - choices3[64] = "HDR Strong 3"; - choices3[224] = "HDR Auto"; - choices3[255] = "Video"; - } - std::string toString (const Tag* t) const override - { - const ChoicesIterator r = choices.find (t->toInt (0, BYTE)); - std::map::const_iterator r1 = choices1.find (t->toInt (1, BYTE)); - std::map::const_iterator r2 = choices2.find (t->toInt (2, BYTE)); - std::map::const_iterator r3 = choices3.find (t->toInt (3, BYTE)); - std::ostringstream s; - s << ((r != choices.end()) ? r->second : ""); - s << ((r1 != choices1.end()) ? r1->second : "") << " "; - s << ((r2 != choices2.end()) ? r2->second : "") << " "; - s << ((r3 != choices3.end()) ? r3->second : "") << " "; - return s.str(); - } -}; -PADriveModeInterpreter paDriveModeInterpreter; - -class PAColorSpaceInterpreter: public ChoiceInterpreter<> -{ -public: - PAColorSpaceInterpreter() - { - choices[0] = "sRGB"; - choices[1] = "Adobe RGB"; - } -}; -PAColorSpaceInterpreter paColorSpaceInterpreter; - -class PALensTypeInterpreter : public IntLensInterpreter< int > -{ -public: - PALensTypeInterpreter () - { - choices.insert (p_t (256 * 0 + 0, "M-42 or No Lens")); - choices.insert (p_t (256 * 1 + 0, "K or M Lens")); - choices.insert (p_t (256 * 2 + 0, "A Series Lens")); - choices.insert (p_t (256 * 3 + 0, "Sigma")); - choices.insert (p_t (256 * 3 + 17, "smc PENTAX-FA SOFT 85mm f/2.8")); - choices.insert (p_t (256 * 3 + 18, "smc PENTAX-F 1.7X AF ADAPTER")); - choices.insert (p_t (256 * 3 + 19, "smc PENTAX-F 24-50mm f/4")); - choices.insert (p_t (256 * 3 + 20, "smc PENTAX-F 35-80mm f/4-5.6")); - choices.insert (p_t (256 * 3 + 21, "smc PENTAX-F 80-200mm f/4.7-5.6")); - choices.insert (p_t (256 * 3 + 22, "smc PENTAX-F FISH-EYE 17-28mm f/3.5-4.5")); - choices.insert (p_t (256 * 3 + 23, "smc PENTAX-F 100-300mm f/4.5-5.6 or Sigma Lens")); - choices.insert (p_t (256 * 3 + 23, "Sigma AF 28-300mm f/3.5-5.6 DL IF")); - choices.insert (p_t (256 * 3 + 23, "Sigma AF 28-300mm f/3.5-6.3 DG IF Macro")); - choices.insert (p_t (256 * 3 + 23, "Tokina 80-200mm f/2.8 ATX-Pro")); - choices.insert (p_t (256 * 3 + 24, "smc PENTAX-F 35-135mm f/3.5-4.5")); - choices.insert (p_t (256 * 3 + 25, "smc PENTAX-F 35-105mm f/4-5.6 or Sigma or Tokina Lens")); - choices.insert (p_t (256 * 3 + 25, "Sigma 55-200mm f/4-5.6 DC")); - choices.insert (p_t (256 * 3 + 25, "Sigma AF 28-300mm f/3.5-5.6 DL IF")); - choices.insert (p_t (256 * 3 + 25, "Sigma AF 28-300mm f/3.5-6.3 DL IF")); - choices.insert (p_t (256 * 3 + 25, "Sigma AF 28-300mm f/3.5-6.3 DG IF Macro")); - choices.insert (p_t (256 * 3 + 25, "Tokina 80-200mm f/2.8 ATX-Pro")); - choices.insert (p_t (256 * 3 + 26, "smc PENTAX-F* 250-600mm f/5.6 ED[IF]")); - choices.insert (p_t (256 * 3 + 27, "smc PENTAX-F 28-80mm f/3.5-4.5 or Tokina Lens")); - choices.insert (p_t (256 * 3 + 27, "Tokina AT-X Pro AF 28-70mm f/2.6-2.8")); - choices.insert (p_t (256 * 3 + 28, "smc PENTAX-F 35-70mm f/3.5-4.5 or Tokina Lens")); - choices.insert (p_t (256 * 3 + 28, "Tokina 19-35mm f/3.5-4.5 AF")); - choices.insert (p_t (256 * 3 + 28, "Tokina AT-X AF 400mm f/5.6")); - choices.insert (p_t (256 * 3 + 29, "PENTAX-F 28-80mm f/3.5-4.5 or Sigma or Tokina Lens")); - choices.insert (p_t (256 * 3 + 29, "Sigma AF 18-125mm f/3.5-5.6 DC")); - choices.insert (p_t (256 * 3 + 29, "Tokina AT-X PRO 28-70mm f/2.6-2.8")); - choices.insert (p_t (256 * 3 + 30, "PENTAX-F 70-200mm f/4-5.6")); - choices.insert (p_t (256 * 3 + 31, "smc PENTAX-F 70-210mm f/4-5.6 or Tokina or Takumar Lens")); - choices.insert (p_t (256 * 3 + 31, "Tokina AF 730 75-300mm f/4.5-5.6")); - choices.insert (p_t (256 * 3 + 31, "Takumar-F 70-210mm f/4-5.6")); - choices.insert (p_t (256 * 3 + 32, "smc PENTAX-F 50mm f/1.4")); - choices.insert (p_t (256 * 3 + 33, "smc PENTAX-F 50mm f/1.7")); - choices.insert (p_t (256 * 3 + 34, "smc PENTAX-F 135mm f/2.8 [IF]")); - choices.insert (p_t (256 * 3 + 35, "smc PENTAX-F 28mm f/2.8")); - choices.insert (p_t (256 * 3 + 36, "Sigma 20mm f/1.8 EX DG Aspherical RF")); - choices.insert (p_t (256 * 3 + 38, "smc PENTAX-F* 300mm f/4.5 ED[IF]")); - choices.insert (p_t (256 * 3 + 39, "smc PENTAX-F* 600mm f/4 ED[IF]")); - choices.insert (p_t (256 * 3 + 40, "smc PENTAX-F Macro 100mm f/2.8")); - choices.insert (p_t (256 * 3 + 41, "smc PENTAX-F Macro 50mm f/2.8 or Sigma Lens")); - choices.insert (p_t (256 * 3 + 41, "Sigma 50mm f/2.8 Macro")); - choices.insert (p_t (256 * 3 + 42, "Sigma 300mm f/2.8 EX DG APO IF")); - choices.insert (p_t (256 * 3 + 44, "Sigma or Tamron Lens (3 44)")); - choices.insert (p_t (256 * 3 + 44, "Sigma AF 10-20mm f/4-5.6 EX DC")); - choices.insert (p_t (256 * 3 + 44, "Sigma 12-24mm f/4.5-5.6 EX DG")); - choices.insert (p_t (256 * 3 + 44, "Sigma 17-70mm f/2.8-4.5 DC Macro")); - choices.insert (p_t (256 * 3 + 44, "Sigma 18-50mm f/3.5-5.6 DC")); - choices.insert (p_t (256 * 3 + 44, "Sigma 17-35mm f/2.8-4 EX DG")); - choices.insert (p_t (256 * 3 + 44, "Tamron 35-90mm f/4 AF")); - choices.insert (p_t (256 * 3 + 44, "Sigma AF 18-35mm f/3.5-4.5 Aspherical")); - choices.insert (p_t (256 * 3 + 46, "Sigma or Samsung Lens (3 46)")); - choices.insert (p_t (256 * 3 + 46, "Sigma APO 70-200mm f/2.8 EX")); - choices.insert (p_t (256 * 3 + 46, "Sigma EX APO 100-300mm f/4 IF")); - choices.insert (p_t (256 * 3 + 46, "Samsung/Schneider D-XENON 50-200mm f/4-5.6 ED")); - choices.insert (p_t (256 * 3 + 50, "smc PENTAX-FA 28-70mm f/4 AL")); - choices.insert (p_t (256 * 3 + 51, "Sigma 28mm f/1.8 EX DG Aspherical Macro")); - choices.insert (p_t (256 * 3 + 52, "smc PENTAX-FA 28-200mm f/3.8-5.6 AL[IF] or Tamron Lens")); - choices.insert (p_t (256 * 3 + 52, "Tamron AF LD 28-200mm f/3.8-5.6 [IF] Aspherical (171D)")); - choices.insert (p_t (256 * 3 + 53, "smc PENTAX-FA 28-80mm f/3.5-5.6 AL")); - choices.insert (p_t (256 * 3 + 247, "smc PENTAX-DA FISH-EYE 10-17mm f/3.5-4.5 ED[IF]")); - choices.insert (p_t (256 * 3 + 248, "smc PENTAX-DA 12-24mm f/4 ED AL[IF]")); - choices.insert (p_t (256 * 3 + 250, "smc PENTAX-DA 50-200mm f/4-5.6 ED")); - choices.insert (p_t (256 * 3 + 251, "smc PENTAX-DA 40mm f/2.8 Limited")); - choices.insert (p_t (256 * 3 + 252, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL")); - choices.insert (p_t (256 * 3 + 253, "smc PENTAX-DA 14mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 3 + 254, "smc PENTAX-DA 16-45mm f/4 ED AL")); - choices.insert (p_t (256 * 3 + 255, "Sigma Lens (3 255)")); - choices.insert (p_t (256 * 3 + 255, "Sigma 18-200mm f/3.5-6.3 DC")); - choices.insert (p_t (256 * 3 + 255, "Sigma DL-II 35-80mm f/4-5.6")); - choices.insert (p_t (256 * 3 + 255, "Sigma DL Zoom 75-300mm f/4-5.6")); - choices.insert (p_t (256 * 3 + 255, "Sigma DF EX Aspherical 28-70mm f/2.8")); - choices.insert (p_t (256 * 3 + 255, "Sigma AF Tele 400mm f/5.6 Multi-coated")); - choices.insert (p_t (256 * 3 + 255, "Sigma 24-60mm f/2.8 EX DG")); - choices.insert (p_t (256 * 3 + 255, "Sigma 70-300mm f/4-5.6 Macro")); - choices.insert (p_t (256 * 3 + 255, "Sigma 55-200mm f/4-5.6 DC")); - choices.insert (p_t (256 * 3 + 255, "Sigma 18-50mm f/2.8 EX DC")); - choices.insert (p_t (256 * 4 + 1, "smc PENTAX-FA SOFT 28mm f/2.8")); - choices.insert (p_t (256 * 4 + 2, "smc PENTAX-FA 80-320mm f/4.5-5.6")); - choices.insert (p_t (256 * 4 + 3, "smc PENTAX-FA 43mm f/1.9 Limited")); - choices.insert (p_t (256 * 4 + 6, "smc PENTAX-FA 35-80mm f/4-5.6")); - choices.insert (p_t (256 * 4 + 9, "Irix 11mm f/4 Firefly")); - choices.insert (p_t (256 * 4 + 10, "Irix 15mm f/2.4")); - choices.insert (p_t (256 * 4 + 12, "smc PENTAX-FA 50mm f/1.4")); - choices.insert (p_t (256 * 4 + 15, "smc PENTAX-FA 28-105mm f/4-5.6 [IF]")); - choices.insert (p_t (256 * 4 + 16, "Tamron AF 80-210mm f/4-5.6 (178D)")); - choices.insert (p_t (256 * 4 + 19, "Tamron SP AF 90mm f/2.8 (172E)")); - choices.insert (p_t (256 * 4 + 20, "smc PENTAX-FA 28-80mm f/3.5-5.6")); - choices.insert (p_t (256 * 4 + 21, "Cosina AF 100-300mm f/5.6-6.7")); - choices.insert (p_t (256 * 4 + 22, "Tokina 28-80mm f/3.5-5.6")); - choices.insert (p_t (256 * 4 + 23, "smc PENTAX-FA 20-35mm f/4 AL")); - choices.insert (p_t (256 * 4 + 24, "smc PENTAX-FA 77mm f/1.8 Limited")); - choices.insert (p_t (256 * 4 + 25, "Tamron SP AF 14mm f/2.8")); - choices.insert (p_t (256 * 4 + 26, "smc PENTAX-FA Macro 100mm f/3.5 or Cosina Lens")); - choices.insert (p_t (256 * 4 + 26, "Cosina 100mm f/3.5 Macro")); - choices.insert (p_t (256 * 4 + 27, "Tamron AF 28-300mm f/3.5-6.3 LD Aspherical[IF] Macro (185D/285D)")); - choices.insert (p_t (256 * 4 + 28, "smc PENTAX-FA 35mm f/2 AL")); - choices.insert (p_t (256 * 4 + 29, "Tamron AF 28-200mm f/3.8-5.6 LD Super II Macro (371D)")); - choices.insert (p_t (256 * 4 + 34, "smc PENTAX-FA 24-90mm f/3.5-4.5 AL[IF]")); - choices.insert (p_t (256 * 4 + 35, "smc PENTAX-FA 100-300mm f/4.7-5.8")); - choices.insert (p_t (256 * 4 + 36, "Tamron AF 70-300mm f/4-5.6 LD Macro 1:2")); - choices.insert (p_t (256 * 4 + 37, "Tamron SP AF 24-135mm f/3.5-5.6 AD AL (190D)")); - choices.insert (p_t (256 * 4 + 38, "smc PENTAX-FA 28-105mm f/3.2-4.5 AL[IF]")); - choices.insert (p_t (256 * 4 + 39, "smc PENTAX-FA 31mm f/1.8 AL Limited")); - choices.insert (p_t (256 * 4 + 41, "Tamron AF 28-200mm Super Zoom f/3.8-5.6 Aspherical XR [IF] Macro (A03)")); - choices.insert (p_t (256 * 4 + 43, "smc PENTAX-FA 28-90mm f/3.5-5.6")); - choices.insert (p_t (256 * 4 + 44, "smc PENTAX-FA J 75-300mm f/4.5-5.8 AL")); - choices.insert (p_t (256 * 4 + 45, "Tamron Lens (4 45)")); - choices.insert (p_t (256 * 4 + 45, "Tamron 28-300mm f/3.5-6.3 Ultra zoom XR")); - choices.insert (p_t (256 * 4 + 45, "Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical [IF] Macro")); - choices.insert (p_t (256 * 4 + 46, "smc PENTAX-FA J 28-80mm f/3.5-5.6 AL")); - choices.insert (p_t (256 * 4 + 47, "smc PENTAX-FA J 18-35mm f/4-5.6 AL")); - choices.insert (p_t (256 * 4 + 49, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro")); - choices.insert (p_t (256 * 4 + 51, "smc PENTAX-D FA 50mm f/2.8 Macro")); - choices.insert (p_t (256 * 4 + 52, "smc PENTAX-D FA 100mm f/2.8 Macro")); - choices.insert (p_t (256 * 4 + 55, "Samsung/Schneider D-XENOGON 35mm f/2")); - choices.insert (p_t (256 * 4 + 56, "Samsung/Schneider D-XENON 100mm f/2.8 Macro")); - choices.insert (p_t (256 * 4 + 75, "Tamron SP AF 70-200mm f/2.8 Di LD [IF] Macro (A001)")); - choices.insert (p_t (256 * 4 + 214, "smc PENTAX-DA 35mm f/2.4 AL")); - choices.insert (p_t (256 * 4 + 229, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL II")); - choices.insert (p_t (256 * 4 + 230, "Tamron SP AF 17-50mm f/2.8 XR Di II")); - choices.insert (p_t (256 * 4 + 231, "smc PENTAX-DA 18-250mm f/3.5-6.3 ED AL [IF]")); - choices.insert (p_t (256 * 4 + 237, "Samsung/Schneider D-XENOGON 10-17mm f/3.5-4.5")); - choices.insert (p_t (256 * 4 + 239, "Samsung/Schneider D-XENON 12-24mm f/4 ED AL [IF]")); - choices.insert (p_t (256 * 4 + 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 4 + 243, "smc PENTAX-DA 70mm f/2.4 Limited")); - choices.insert (p_t (256 * 4 + 244, "smc PENTAX-DA 21mm f/3.2 AL Limited")); - choices.insert (p_t (256 * 4 + 245, "Samsung/Schneider D-XENON 50-200mm f/4-5.6")); - choices.insert (p_t (256 * 4 + 246, "Samsung/Schneider D-XENON 18-55mm f/3.5-5.6")); - choices.insert (p_t (256 * 4 + 247, "smc PENTAX-DA FISH-EYE 10-17mm f/3.5-4.5 ED[IF]")); - choices.insert (p_t (256 * 4 + 248, "smc PENTAX-DA 12-24mm f/4 ED AL [IF]")); - choices.insert (p_t (256 * 4 + 249, "Tamron XR DiII 18-200mm f/3.5-6.3 (A14)")); - choices.insert (p_t (256 * 4 + 250, "smc PENTAX-DA 50-200mm f/4-5.6 ED")); - choices.insert (p_t (256 * 4 + 251, "smc PENTAX-DA 40mm f/2.8 Limited")); - choices.insert (p_t (256 * 4 + 252, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL")); - choices.insert (p_t (256 * 4 + 253, "smc PENTAX-DA 14mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 4 + 254, "smc PENTAX-DA 16-45mm f/4 ED AL")); - choices.insert (p_t (256 * 5 + 1, "smc PENTAX-FA* 24mm f/2 AL[IF]")); - choices.insert (p_t (256 * 5 + 2, "smc PENTAX-FA 28mm f/2.8 AL")); - choices.insert (p_t (256 * 5 + 3, "smc PENTAX-FA 50mm f/1.7")); - choices.insert (p_t (256 * 5 + 4, "smc PENTAX-FA 50mm f/1.4")); - choices.insert (p_t (256 * 5 + 5, "smc PENTAX-FA* 600mm f/4 ED[IF]")); - choices.insert (p_t (256 * 5 + 6, "smc PENTAX-FA* 300mm f/4.5 ED[IF]")); - choices.insert (p_t (256 * 5 + 7, "smc PENTAX-FA 135mm f/2.8 [IF]")); - choices.insert (p_t (256 * 5 + 8, "smc PENTAX-FA Macro 50mm f/2.8")); - choices.insert (p_t (256 * 5 + 9, "smc PENTAX-FA Macro 100mm f/2.8")); - choices.insert (p_t (256 * 5 + 10, "smc PENTAX-FA* 85mm f/1.4 [IF]")); - choices.insert (p_t (256 * 5 + 11, "smc PENTAX-FA* 200mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 5 + 12, "smc PENTAX-FA 28-80mm f/3.5-4.7")); - choices.insert (p_t (256 * 5 + 13, "smc PENTAX-FA 70-200mm f/4-5.6")); - choices.insert (p_t (256 * 5 + 14, "smc PENTAX-FA* 250-600mm f/5.6 ED[IF]")); - choices.insert (p_t (256 * 5 + 15, "smc PENTAX-FA 28-105mm f/4-5.6")); - choices.insert (p_t (256 * 5 + 16, "smc PENTAX-FA 100-300mm f/4.5-5.6")); - choices.insert (p_t (256 * 5 + 98, "smc PENTAX-FA 100-300mm f/4.5-5.6")); - choices.insert (p_t (256 * 6 + 1, "smc PENTAX-FA* 85mm f/1.4 [IF]")); - choices.insert (p_t (256 * 6 + 2, "smc PENTAX-FA* 200mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 6 + 3, "smc PENTAX-FA* 300mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 6 + 4, "smc PENTAX-FA* 28-70mm f/2.8 AL")); - choices.insert (p_t (256 * 6 + 5, "smc PENTAX-FA* 80-200mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 6 + 6, "smc PENTAX-FA* 28-70mm f/2.8 AL")); - choices.insert (p_t (256 * 6 + 7, "smc PENTAX-FA* 80-200mm f/2.8 ED[IF]")); - choices.insert (p_t (256 * 6 + 8, "smc PENTAX-FA 28-70mm f/4AL")); - choices.insert (p_t (256 * 6 + 9, "smc PENTAX-FA 20mm f/2.8")); - choices.insert (p_t (256 * 6 + 10, "smc PENTAX-FA* 400mm f/5.6 ED[IF]")); - choices.insert (p_t (256 * 6 + 13, "smc PENTAX-FA* 400mm f/5.6 ED[IF]")); - choices.insert (p_t (256 * 6 + 14, "smc PENTAX-FA* Macro 200mm f/4 ED[IF]")); - choices.insert (p_t (256 * 7 + 0, "smc PENTAX-DA 21mm f/3.2 AL Limited")); - choices.insert (p_t (256 * 7 + 58, "smc PENTAX-D FA Macro 100mm f/2.8 WR")); - choices.insert (p_t (256 * 7 + 75, "Tamron SP AF 70-200mm f/2.8 Di LD [IF] Macro (A001)")); - choices.insert (p_t (256 * 7 + 201, "smc Pentax-DA L 50-200mm f/4-5.6 ED WR")); - choices.insert (p_t (256 * 7 + 202, "smc PENTAX-DA L 18-55mm f/3.5-5.6 AL WR")); - choices.insert (p_t (256 * 7 + 203, "HD PENTAX-DA 55-300mm f/4-5.8 ED WR")); - choices.insert (p_t (256 * 7 + 204, "HD PENTAX-DA 15mm f/4 ED AL Limited")); - choices.insert (p_t (256 * 7 + 205, "HD PENTAX-DA 35mm f/2.8 Macro Limited")); - choices.insert (p_t (256 * 7 + 206, "HD PENTAX-DA 70mm f/2.4 Limited")); - choices.insert (p_t (256 * 7 + 207, "HD PENTAX-DA 21mm f/3.2 ED AL Limited")); - choices.insert (p_t (256 * 7 + 208, "HD PENTAX-DA 40mm f/2.8 Limited")); - choices.insert (p_t (256 * 7 + 212, "smc PENTAX-DA 50mm f/1.8")); - choices.insert (p_t (256 * 7 + 213, "smc PENTAX-DA 40mm f/2.8 XS")); - choices.insert (p_t (256 * 7 + 214, "smc PENTAX-DA 35mm f/2.4 AL")); - choices.insert (p_t (256 * 7 + 216, "smc PENTAX-DA L 55-300mm f/4-5.8 ED")); - choices.insert (p_t (256 * 7 + 217, "smc PENTAX-DA 50-200mm f/4-5.6 ED WR")); - choices.insert (p_t (256 * 7 + 218, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL WR")); - choices.insert (p_t (256 * 7 + 220, "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical [IF]")); - choices.insert (p_t (256 * 7 + 221, "smc PENTAX-DA L 50-200mm f/4-5.6 ED")); - choices.insert (p_t (256 * 7 + 222, "smc PENTAX-DA L 18-55mm f/3.5-5.6")); - choices.insert (p_t (256 * 7 + 223, "Samsung/Schneider D-XENON 18-55mm f/3.5-5.6 II")); - choices.insert (p_t (256 * 7 + 224, "smc PENTAX-DA 15mm f/4 ED AL Limited")); - choices.insert (p_t (256 * 7 + 225, "Samsung/Schneider D-XENON 18-250mm f/3.5-6.3")); - choices.insert (p_t (256 * 7 + 226, "smc PENTAX-DA* 55mm f/1.4 SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 227, "smc PENTAX-DA* 60-250mm f/4 [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 228, "Samsung 16-45mm f/4 ED")); - choices.insert (p_t (256 * 7 + 229, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL II")); - choices.insert (p_t (256 * 7 + 230, "Tamron AF 17-50mm f/2.8 XR Di-II LD (Model A16)")); - choices.insert (p_t (256 * 7 + 231, "smc PENTAX-DA 18-250mm f/3.5-6.3 ED AL [IF]")); - choices.insert (p_t (256 * 7 + 233, "smc PENTAX-DA 35mm f/2.8 Macro Limited")); - choices.insert (p_t (256 * 7 + 234, "smc PENTAX-DA* 300mm f/4 ED [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 235, "smc PENTAX-DA* 200mm f/2.8 ED [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 236, "smc PENTAX-DA 55-300mm f/4-5.8 ED")); - choices.insert (p_t (256 * 7 + 238, "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro")); - choices.insert (p_t (256 * 7 + 241, "smc PENTAX-DA* 50-135mm f/2.8 ED [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM (SDM unused)")); - choices.insert (p_t (256 * 7 + 243, "smc PENTAX-DA 70mm f/2.4 Limited")); - choices.insert (p_t (256 * 7 + 244, "smc PENTAX-DA 21mm f/3.2 AL Limited")); - choices.insert (p_t (256 * 8 + 0, "Sigma 50-150mm f/2.8 II APO EX DC HSM")); - choices.insert (p_t (256 * 8 + 3, "Sigma AF 18-125mm f/3.5-5.6 DC")); - choices.insert (p_t (256 * 8 + 4, "Sigma 50mm f/1.4 EX DG HSM")); - choices.insert (p_t (256 * 8 + 7, "Sigma 24-70mm f/2.8 IF EX DG HSM")); - choices.insert (p_t (256 * 8 + 8, "Sigma 18-250mm f/3.5-6.3 DC OS HSM")); - choices.insert (p_t (256 * 8 + 11, "Sigma 10-20mm f/3.5 EX DC HSM")); - choices.insert (p_t (256 * 8 + 12, "Sigma 70-300mm f/4-5.6 DG OS")); - choices.insert (p_t (256 * 8 + 13, "Sigma 120-400mm f/4.5-5.6 APO DG OS HSM")); - choices.insert (p_t (256 * 8 + 14, "Sigma 17-70mm f/2.8-4.0 DC Macro OS HSM")); - choices.insert (p_t (256 * 8 + 15, "Sigma 150-500mm f/5-6.3 APO DG OS HSM")); - choices.insert (p_t (256 * 8 + 16, "Sigma 70-200mm f/2.8 EX DG Macro HSM II")); - choices.insert (p_t (256 * 8 + 17, "Sigma 50-500mm f/4.5-6.3 DG OS HSM")); - choices.insert (p_t (256 * 8 + 18, "Sigma 8-16mm f/4.5-5.6 DC HSM")); - choices.insert (p_t (256 * 8 + 21, "Sigma 17-50mm f/2.8 EX DC OS HSM")); - choices.insert (p_t (256 * 8 + 22, "Sigma 85mm f/1.4 EX DG HSM")); - choices.insert (p_t (256 * 8 + 23, "Sigma 70-200mm f/2.8 APO EX DG OS HSM")); - choices.insert (p_t (256 * 8 + 25, "Sigma 17-50mm f/2.8 EX DC HSM")); - choices.insert (p_t (256 * 8 + 27, "Sigma 18-200mm f/3.5-6.3 II DC HSM")); - choices.insert (p_t (256 * 8 + 28, "Sigma 18-250mm f/3.5-6.3 DC Macro HSM")); - choices.insert (p_t (256 * 8 + 29, "Sigma 35mm f/1.4 DG HSM")); - choices.insert (p_t (256 * 8 + 30, "Sigma 17-70mm f/2.8-4 DC Macro HSM | C")); - choices.insert (p_t (256 * 8 + 31, "Sigma 18-35mm f/1.8 DC HSM")); - choices.insert (p_t (256 * 8 + 32, "Sigma 30mm f/1.4 DC HSM | A")); - choices.insert (p_t (256 * 8 + 33, "Sigma 18-200mm f/3.5-6.3 DC Macro HSM")); - choices.insert (p_t (256 * 8 + 34, "Sigma 18-300mm f/3.5-6.3 DC Macro HSM")); - choices.insert (p_t (256 * 8 + 59, "HD PENTAX-D FA 150-450mm f/4.5-5.6 ED DC AW")); - choices.insert (p_t (256 * 8 + 60, "HD PENTAX-D FA* 70-200mm f/2.8 ED DC AW")); - choices.insert (p_t (256 * 8 + 61, "HD PENTAX-D FA 28-105mm f/3.5-5.6 ED DC WR")); - choices.insert (p_t (256 * 8 + 62, "HD PENTAX-D FA 24-70mm f/2.8 ED SDM WR")); - choices.insert (p_t (256 * 8 + 63, "HD PENTAX-D FA 15-30mm f/2.8 ED SDM WR")); - choices.insert (p_t (256 * 8 + 64, "HD PENTAX-D FA* 50mm f/1.4 SDM AW")); - choices.insert (p_t (256 * 8 + 197, "HD PENTAX-DA 55-300mm f/4.5-6.3 ED PLM WR RE")); - choices.insert (p_t (256 * 8 + 198, "smc PENTAX-DA L 18-50mm f/4-5.6 DC WR RE")); - choices.insert (p_t (256 * 8 + 199, "HD PENTAX-DA 18-50mm f/4-5.6 DC WR RE")); - choices.insert (p_t (256 * 8 + 200, "HD PENTAX-DA 16-85mm f/3.5-5.6 ED DC WR")); - choices.insert (p_t (256 * 8 + 209, "HD PENTAX-DA 20-40mm f/2.8-4 ED Limited DC WR")); - choices.insert (p_t (256 * 8 + 210, "smc PENTAX-DA 18-270mm f/3.5-6.3 ED SDM")); - choices.insert (p_t (256 * 8 + 211, "HD PENTAX-DA 560mm f/5.6 ED AW")); - choices.insert (p_t (256 * 8 + 215, "smc PENTAX-DA 18-135mm f/3.5-5.6 ED AL [IF] DC WR")); - choices.insert (p_t (256 * 8 + 226, "smc PENTAX-DA* 55mm f/1.4 SDM")); - choices.insert (p_t (256 * 8 + 227, "smc PENTAX-DA* 60-250mm f/4 [IF] SDM")); - choices.insert (p_t (256 * 8 + 232, "smc PENTAX-DA 17-70mm f/4 AL [IF] SDM")); - choices.insert (p_t (256 * 8 + 234, "smc PENTAX-DA* 300mm f/4 ED [IF] SDM")); - choices.insert (p_t (256 * 8 + 235, "smc PENTAX-DA* 200mm f/2.8 ED [IF] SDM")); - choices.insert (p_t (256 * 8 + 241, "smc PENTAX-DA* 50-135mm f/2.8 ED [IF] SDM")); - choices.insert (p_t (256 * 8 + 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM")); - choices.insert (p_t (256 * 8 + 255, "Sigma Lens (8 255)")); - choices.insert (p_t (256 * 8 + 255, "Sigma 70-200mm f/2.8 EX DG Macro HSM II")); - choices.insert (p_t (256 * 8 + 255, "Sigma 150-500mm f/5-6.3 DG APO [OS] HSM")); - choices.insert (p_t (256 * 8 + 255, "Sigma 50-150mm f/2.8 II APO EX DC HSM")); - choices.insert (p_t (256 * 8 + 255, "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye")); - choices.insert (p_t (256 * 8 + 255, "Sigma 50-200mm f/4-5.6 DC OS")); - choices.insert (p_t (256 * 8 + 255, "Sigma 24-70mm f/2.8 EX DG HSM")); - choices.insert (p_t (256 * 9 + 0, "645 Manual Lens")); - choices.insert (p_t (256 * 10 + 0, "645 A Series Lens")); - choices.insert (p_t (256 * 11 + 1, "smc PENTAX-FA 645 75mm f/2.8")); - choices.insert (p_t (256 * 11 + 2, "smc PENTAX-FA 645 45mm f/2.8")); - choices.insert (p_t (256 * 11 + 3, "smc PENTAX-FA* 645 300mm f/4 ED [IF]")); - choices.insert (p_t (256 * 11 + 4, "smc PENTAX-FA 645 45-85mm f/4.5")); - choices.insert (p_t (256 * 11 + 5, "smc PENTAX-FA 645 400mm f/5.6 ED [IF]")); - choices.insert (p_t (256 * 11 + 7, "smc PENTAX-FA 645 Macro 120mm f/4")); - choices.insert (p_t (256 * 11 + 8, "smc PENTAX-FA 645 80-160mm f/4.5")); - choices.insert (p_t (256 * 11 + 9, "smc PENTAX-FA 645 200mm f/4 [IF]")); - choices.insert (p_t (256 * 11 + 10, "smc PENTAX-FA 645 150mm f/2.8 [IF]")); - choices.insert (p_t (256 * 11 + 11, "smc PENTAX-FA 645 35mm f/3.5 AL [IF]")); - choices.insert (p_t (256 * 11 + 12, "smc PENTAX-FA 645 300mm f/5.6 ED [IF]")); - choices.insert (p_t (256 * 11 + 14, "smc PENTAX-FA 645 55-110mm f/5.6")); - choices.insert (p_t (256 * 11 + 16, "smc PENTAX-FA 645 33-55mm f/4.5 AL")); - choices.insert (p_t (256 * 11 + 17, "smc PENTAX-FA 645 150-300mm f/5.6 ED [IF]")); - choices.insert (p_t (256 * 11 + 21, "HD PENTAX-D FA 645 35mm f/3.5 AL [IF]")); - choices.insert (p_t (256 * 13 + 18, "smc PENTAX-D FA 645 55mm f/2.8 AL [IF] SDM AW")); - choices.insert (p_t (256 * 13 + 19, "smc PENTAX-D FA 645 25mm f/4 AL [IF] SDM AW")); - choices.insert (p_t (256 * 13 + 20, "HD PENTAX-D FA 645 90mm f/2.8 ED AW SR")); - choices.insert (p_t (256 * 13 + 253, "HD PENTAX-DA 645 28-45mm f/4.5 ED AW SR")); - choices.insert (p_t (256 * 13 + 254, "smc PENTAX-DA 645 25mm f/4 AL [IF] SDM AW")); - choices.insert (p_t (256 * 21 + 0, "Pentax Q Manual Lens")); - choices.insert (p_t (256 * 21 + 1, "01 Standard Prime 8.5mm f/1.9")); - choices.insert (p_t (256 * 21 + 2, "02 Standard Zoom 5-15mm f/2.8-4.5")); - choices.insert (p_t (256 * 21 + 6, "06 Telephoto Zoom 15-45mm f/2.8")); - choices.insert (p_t (256 * 21 + 7, "07 Mount Shield 11.5mm f/9")); - choices.insert (p_t (256 * 21 + 8, "08 Wide Zoom 3.8-5.9mm f/3.7-4")); - choices.insert (p_t (256 * 21 + 233, "Adapter Q for K-mount Lens")); - choices.insert (p_t (256 * 22 + 3, "03 Fish-eye 3.2mm f/5.6")); - choices.insert (p_t (256 * 22 + 4, "04 Toy Lens Wide 6.3mm f/7.1")); - choices.insert (p_t (256 * 22 + 5, "05 Toy Lens Telephoto 18mm f/8")); - } - std::string toString (const Tag* t) const override - { - double *liArray = nullptr; - double maxApertureAtFocal = 0.; - double focalLength = 0.; - int lensID = 256 * t->toInt (0, BYTE) + t->toInt (1, BYTE); - TagDirectory *root = t->getParent()->getRoot(); - - if (root) { - - Tag *t1; - t1 = root->findTag ("FocalLength"); // Should get tag 0x920A (rational64u) from the standard Exif tag list - - if ( t1) { - focalLength = t1->toDouble(); // Focal Length - } - - t1 = root->findTag ("MaxAperture"); - - if (t1) { - double maxAperture = t1->toDouble(); // MaxApertureValue at focal Length - - if (maxAperture != 0.) { - maxApertureAtFocal = maxAperture; - } else { - t1 = root->findTag ("NominalMaxAperture"); - - if (t1) { - maxApertureAtFocal = t1->toDouble(); - } - } - } - - t1 = root->getTagP ("LensInfo"); - - if (t1) { - liArray = t1->toDoubleArray(); - } - - // Focal length below 10mm are set to 0 by the camera in the standard Exif tag, so we'll look into the makernotes - // This value will have decimals, which reflects more precision... or imprecision, due to the packed form of this value, who knows? - if (focalLength == 0.) { - rtexif::TagDirectory* mnote = root->findTag ("MakerNote")->getDirectory(); - rtexif::Tag* flt = mnote->getTagP ("LensInfo/FocalLength"); - - if (flt) { - focalLength = flt->toDouble (); - } else if ((flt = mnote->getTagP ("FocalLength"))) { - focalLength = flt->toDouble(); - } - } - } - - std::string retval = guess ( lensID, focalLength, maxApertureAtFocal, liArray); - - if (liArray) { - delete [] liArray; - } - - return retval; - } -}; -PALensTypeInterpreter paLensTypeInterpreter; - -class PASRResultInterpreter: public Interpreter -{ -public: - PASRResultInterpreter() { } - std::string toString (const Tag* t) const override - { - std::ostringstream str; - int b = t->toInt (0, BYTE); - - if (!b) { - str << "Not stabilized"; - } else if (b & 1) { - str << "Stabilized"; - } else if (b & 64) { - str << "Not Ready"; - } - - return str.str(); - } -}; -PASRResultInterpreter paSRResultInterpreter; - -class PAHighISONoiseInterpreter: public ChoiceInterpreter<> -{ -public: - // HighISONoiseReduction - PAHighISONoiseInterpreter() - { - choices[0] = "Off"; - choices[1] = "Weakest"; - choices[2] = "Weak"; - choices[3] = "Strong"; - choices[4] = "Medium"; - choices[255] = "Auto"; - } -}; -PAHighISONoiseInterpreter paHighISONoiseInterpreter; - -class PAMonochromeFilterEffectInterpreter: public ChoiceInterpreter<> -{ -public: - PAMonochromeFilterEffectInterpreter() - { - choices[1] = "Green"; - choices[2] = "Yellow"; - choices[3] = "Orange"; - choices[4] = "Red"; - choices[5] = "Magenta"; - choices[6] = "Blue"; - choices[7] = "Cyan"; - choices[8] = "Infrared"; - choices[65535] = "None"; - } -}; -PAMonochromeFilterEffectInterpreter paMonochromeFilterEffectInterpreter; - -class PAMonochromeToningInterpreter: public ChoiceInterpreter<> -{ -public: - PAMonochromeToningInterpreter() - { - choices[0] = "-4"; - choices[1] = "-3"; - choices[2] = "-2"; - choices[3] = "-1"; - choices[4] = "0"; - choices[5] = "1"; - choices[6] = "2"; - choices[7] = "3"; - choices[8] = "4"; - choices[65535] = "None"; - } -}; -PAMonochromeToningInterpreter paMonochromeToningInterpreter; - -class PAShadowCorrectionInterpreter: public ChoiceInterpreter<> -{ -public: - PAShadowCorrectionInterpreter() - { - choices[ 0 ] = "Off"; - choices[ 1 ] = "On"; - choices[ 2 ] = "Auto 2"; - choices[ 1 << 8 | 1 ] = "Weak"; - choices[ 1 << 8 | 2 ] = "Normal"; - choices[ 1 << 8 | 3 ] = "Strong"; - choices[ 2 << 8 | 4 ] = "Auto"; - } - - std::string toString (const Tag* t) const override - { - int idx = 0; - - if (t->getCount() == 1) { - idx = t->toInt (0, BYTE); - } else if (t->getCount() == 2) { - idx = t->toInt (0, BYTE) << 8 | t->toInt (1, BYTE); - } - - const ChoicesIterator r = choices.find (idx); - std::ostringstream s; - s << ((r != choices.end()) ? r->second : "n/a"); - return s.str(); - } -}; -PAShadowCorrectionInterpreter paShadowCorrectionInterpreter; - -class PAISOAutoParametersInterpreter: public ChoiceInterpreter<> -{ -public: - PAISOAutoParametersInterpreter() - { - choices[1] = "Slow"; - choices[2] = "Standard"; - choices[3] = "Fast"; - } - std::string toString (const Tag* t) const override - { - const ChoicesIterator r = choices.find (t->toInt (0, BYTE)); - std::ostringstream s; - s << ((r != choices.end()) ? r->second : "n/a"); - return s.str(); - } -}; -PAISOAutoParametersInterpreter paISOAutoParametersInterpreter; - -class PABleachBypassToningInterpreter: public ChoiceInterpreter<> -{ -public: - PABleachBypassToningInterpreter() - { - choices[1] = "Green"; - choices[2] = "Yellow"; - choices[3] = "Orange"; - choices[4] = "Red"; - choices[5] = "Magenta"; - choices[6] = "Purple"; - choices[7] = "Blue"; - choices[8] = "Cyan"; - choices[65535] = "Off"; - } -}; -PABleachBypassToningInterpreter paBleachBypassToningInterpreter; - -class PABlurControlInterpreter: public ChoiceInterpreter<> -{ -public: - PABlurControlInterpreter() - { - choices[0] = "Off"; - choices[1] = "Low"; - choices[2] = "Medium"; - choices[3] = "High"; - } - std::string toString (const Tag* t) const override - { - const ChoicesIterator r = choices.find (t->toInt (0, BYTE)); - std::ostringstream s; - s << ((r != choices.end()) ? r->second : "n/a"); - return s.str(); - } -}; -PABlurControlInterpreter paBlurControlInterpreter; - -class PAHDRInterpreter: public ChoiceInterpreter<> -{ - std::map choices1; - std::map choices2; -public: - PAHDRInterpreter() - { - choices[0] = "Off"; - choices[1] = "HDR Auto"; - choices[2] = "HDR 1"; - choices[3] = "HDR 2"; - choices[4] = "HDR 3"; - choices[5] = "Advanced"; - - choices1[0] = "Auto-align Off"; - choices1[1] = "Auto-align On"; - - choices2[0] = "n/a"; - choices2[4] = "1 EV"; - choices2[8] = "2 EV"; - choices2[12] = "3 EV"; - } - std::string toString (const Tag* t) const override - { - const ChoicesIterator r = choices.find (t->toInt (0, BYTE)); - std::map::const_iterator r1 = choices1.find (t->toInt (1, BYTE)); - std::map::const_iterator r2 = choices2.find (t->toInt (2, BYTE)); - std::ostringstream s; - s << ((r != choices.end() ) ? r->second : "") << std::endl; - s << ((r1 != choices1.end()) ? r1->second : "") << std::endl; - s << ((r2 != choices2.end()) ? r2->second : ""); - return s.str(); - } -}; -PAHDRInterpreter paHDRInterpreter; - -class PACrossProcessInterpreter: public ChoiceInterpreter<> -{ -public: - PACrossProcessInterpreter() - { - choices[ 0] = "Off"; - choices[ 1] = "Randow"; - choices[ 2] = "Preset 1"; - choices[ 3] = "Preset 2"; - choices[ 4] = "Preset 3"; - choices[33] = "Favorite 1"; - choices[34] = "Favorite 2"; - choices[35] = "Favorite 3"; - } -}; -PACrossProcessInterpreter paCrossProcessInterpreter; - -class PAPowerSourceInterpreter: public ChoiceInterpreter<> -{ -public: - PAPowerSourceInterpreter() - { - choices[2] = "Body Battery"; - choices[3] = "Grip Battery "; - choices[4] = "External Power Supply"; - } -}; -PAPowerSourceInterpreter paPowerSourceInterpreter; - -class PALensModelQInterpreter: public Interpreter -{ -public: - PALensModelQInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[31]; - buffer[0] = 0; // - return buffer; // TODO: how to get the string content!? - -// // normal path below (copy the content of the string), but has to be bug fixed -// memcpy (buffer, t->getValue(), 30); -// buffer[30] = 0; -// return buffer; - } -}; -PALensModelQInterpreter paLensModelQInterpreter; - -class PALensInfoQInterpreter: public Interpreter -{ -public: - PALensInfoQInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[21]; - buffer[0] = 0; - return buffer; // TODO: how to get the string content!? - -// // normal path below (copy the content of the string), but has to be bug fixed -// memcpy (buffer, t->getValue(), 20); -// buffer[20] = 0; -// return buffer; - } -}; -PALensInfoQInterpreter paLensInfoQInterpreter; - -class PAFlashExposureCompInterpreter: public Interpreter -{ -public: - PAFlashExposureCompInterpreter() {} - std::string toString (const Tag* t) const override - { - int a; - - if (t->getCount() == 1) { - a = t->toInt (0, SLONG) / 256; // int32u - } else { - a = t->toInt (0, SBYTE) / 6; // int8u[2] - } - - char buffer[32]; - sprintf (buffer, "%d", a ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a; - - if (t->getCount() == 1) { - a = t->toInt (0, SLONG) / 256; // int32u - } else { - a = t->toInt (0, SBYTE) / 6; // int8u[2] - } - - return double (a); - } -}; -PAFlashExposureCompInterpreter paFlashExposureCompInterpreter; - -class PAFocalLengthInterpreter: public Interpreter -{ -public: - PAFocalLengthInterpreter() {} - std::string toString (const Tag* t) const override - { - double a = double (t->toInt (0, LONG)); - - if (a > 1.) { - char buffer[32]; - sprintf (buffer, "%.2f", a / 100. ); - return buffer; - } else { - return "n/a"; - } - } - double toDouble (const Tag* t, int ofs) override - { - double a = double (t->toInt (0, LONG)); - - if (a > 1.) { - return a / 100.; - } else { - return 0.; - } - } -}; -PAFocalLengthInterpreter paFocalLengthInterpreter; - -class PALensDataFocalLengthInterpreter: public Interpreter -{ -public: - PALensDataFocalLengthInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - float b = float (10 * int (a >> 2)) * pow (4.f, float (int (a & 0x03) - 2)); - - if (b > 1.f) { - char buffer[32]; - sprintf (buffer, "%.2f", b ); - return buffer; - } else { - return "n/a"; - } - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (ofs, BYTE); - float b = float (10 * int (a >> 2)) * pow (4.f, float (int (a & 0x03) - 2)); - - if (b > 1.f) { - return b; - } else { - return 0.; - } - } -}; -PALensDataFocalLengthInterpreter paLensDataFocalLengthInterpreter; - -class PAISOfInterpreter: public Interpreter -{ -public: - PAISOfInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - char buffer[32]; - double v = 100.*exp (double (a - 32) * log (2.) / 8.); - sprintf (buffer, "%.1f", v ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE); - return 100.*exp (double (a - 32) * log (2.) / 8.); - } -}; -PAISOfInterpreter paISOfInterpreter; - -class PAMaxApertureInterpreter: public Interpreter -{ -public: - PAMaxApertureInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - a &= 0x7F; - - if (a > 1) { - char buffer[32]; - double v = pow (2.0, (a - 1) / 32.0); - - if ( v < 0. || v > 1000. ) { - return "undef"; - } - - sprintf (buffer, "%.1f", v ); - return buffer; - } else { - return "n/a"; - } - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE); - a &= 0x7F; - - if (a > 1) { - return pow (2.0, double (a - 1) / 32.0); - } else { - return 0.; - } - } -}; -PAMaxApertureInterpreter paMaxApertureInterpreter; - -class PAAEXvInterpreter: public Interpreter -{ -public: - PAAEXvInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - char buffer[32]; - double v = double (a - 64) / 8.; - sprintf (buffer, "%.1f", v ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE); - return double (a - 64) / 8.; - } -}; -PAAEXvInterpreter paAEXvInterpreter; - -class PAAEBXvInterpreter: public Interpreter -{ -public: - PAAEBXvInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, SBYTE); - char buffer[32]; - double v = double (a) / 8.; - sprintf (buffer, "%.1f", v ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, SBYTE); - return double (a) / 8.; - } -}; -PAAEBXvInterpreter paAEBXvInterpreter; - -class PAApertureInterpreter: public Interpreter -{ -public: - PAApertureInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - char buffer[32]; - double v = exp ((double (a) - 68.) * log (2.) / 16.); - sprintf (buffer, "%.1f", v ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE); - return exp ((double (a) - 68.) * log (2.) / 16.); - } -}; -PAApertureInterpreter paApertureInterpreter; - -class PAExposureTimeInterpreter: public Interpreter -{ -public: - PAExposureTimeInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->toInt (0, BYTE); - char buffer[32]; - double v = 24.*exp (- (double (a) - 32.) * log (2.) / 8.); - sprintf (buffer, "%.6f", v ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE); - return 24.*exp (- (double (a) - 32.) * log (2.) / 8.); - } -}; -PAExposureTimeInterpreter paExposureTimeInterpreter; - -class PANominalMinApertureInterpreter: public Interpreter -{ -public: - PANominalMinApertureInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - int a = t->toInt (0, BYTE); - int mina = a & 0x0F; - sprintf (buffer, "%.1f", double (int (pow (2.0, double (mina + 10) / 4.0) + 0.2))); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = t->toInt (0, BYTE) & 0x0F; - return double (int (pow (2.0, double (a + 10) / 4.0) + 0.2)); - } -}; -PANominalMinApertureInterpreter paNominalMinApertureInterpreter; - -class PANominalMaxApertureInterpreter: public Interpreter -{ -public: - PANominalMaxApertureInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - int a = t->toInt (0, BYTE); - int maxa = (a & 0xF0) >> 4; - sprintf (buffer, "%.1f", double (int (pow (2.0, double (maxa) / 4.0) + 0.2)) ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - int a = ( t->toInt (0, BYTE) & 0xF0) >> 4; - return double (int (pow (2.0, double (a) / 4.0) + 0.2)); - } -}; -PANominalMaxApertureInterpreter paNominalMaxApertureInterpreter; - -class PAFlashStatusInterpreter: public ChoiceInterpreter<> -{ -public: - PAFlashStatusInterpreter() - { - choices[0] = "Off"; - choices[1] = "Off (1)"; - choices[2] = "External, Did not fire"; - choices[6] = "External, Fired"; - choices[8] = "Internal, Did not fire (0x08)"; - choices[9] = "Internal, Did not fire"; - choices[13] = "Internal, Fired"; - } -}; -PAFlashStatusInterpreter paFlashStatusInterpreter; - -class PAInternalFlashModeInterpreter: public ChoiceInterpreter<> -{ -public: - PAInternalFlashModeInterpreter() - { - choices[0] = "n/a - Off-Auto-Aperture"; - choices[134] = "Fired, Wireless (Control)"; - choices[149] = "Fired, Wireless (Master)"; - choices[192] = "Fired"; - choices[193] = "Fired, Red-eye reduction"; - choices[194] = "Fired, Auto"; - choices[195] = "Fired, Auto, Red-eye reduction"; - choices[198] = "Fired, Wireless (Control), Fired normally not as control"; - choices[200] = "Fired, Slow-sync"; - choices[201] = "Fired, Slow-sync, Red-eye reduction"; - choices[202] = "Fired, Trailing-curtain Sync"; - choices[240] = "Did not fire, Normal"; - choices[241] = "Did not fire, Red-eye reduction"; - choices[242] = "Did not fire, Auto"; - choices[243] = "Did not fire, Auto, Red-eye reduction"; - choices[244] = "Did not fire, (Unknown 0xf4)"; - choices[245] = "Did not fire, Wireless (Master)"; - choices[246] = "Did not fire, Wireless (Control)"; - choices[248] = "Did not fire, Slow-sync"; - choices[249] = "Did not fire, Slow-sync, Red-eye reduction"; - choices[250] = "Did not fire, Trailing-curtain Sync"; - } -}; -PAInternalFlashModeInterpreter paInternalFlashModeInterpreter; - -class PAExternalFlashModeInterpreter: public ChoiceInterpreter<> -{ -public: - PAExternalFlashModeInterpreter() - { - choices[0] = "n/a - Off-Auto-Aperture"; - choices[63] = "Off"; - choices[64] = "On, Auto"; - choices[191] = "On, Flash Problem"; - choices[192] = "On, Manual"; - choices[196] = "On, P-TTL Auto"; - choices[197] = "On, Contrast-control Sync"; - choices[198] = "On, High-speed Sync"; - choices[204] = "On, Wireless"; - choices[205] = "On, Wireless, High-speed Sync"; - choices[240] = "Not Connected"; - } -}; -PAExternalFlashModeInterpreter paExternalFlashModeInterpreter; - -class PAExternalFlashExposureCompInterpreter: public ChoiceInterpreter<> -{ -public: - PAExternalFlashExposureCompInterpreter() - { - choices[0] = "n/a"; - choices[144] = "n/a (Manual Mode)"; - choices[164] = "-3.0"; - choices[167] = "-2.5"; - choices[168] = "-2.0"; - choices[171] = "-1.5"; - choices[172] = "-1.0"; - choices[175] = "-0.5"; - choices[176] = "0.0"; - choices[179] = "0.5"; - choices[180] = "1.0"; - } -}; -PAExternalFlashExposureCompInterpreter paExternalFlashExposureCompInterpreter; - -class PAExternalFlashBounceInterpreter: public ChoiceInterpreter<> -{ -public: - PAExternalFlashBounceInterpreter() - { - choices[0] = "n/a"; - choices[16] = "Direct"; - choices[48] = "Bonce"; - } -}; -PAExternalFlashBounceInterpreter paExternalFlashBounceInterpreter; - -class PAExternalFlashGNInterpreter: public Interpreter -{ -public: - PAExternalFlashGNInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - int b = t->toInt (0, BYTE) & 0x1F; - sprintf (buffer, "%.0f", pow (2., b / 16. + 4) ); - return buffer; - } -}; -PAExternalFlashGNInterpreter paExternalFlashGNInterpreter; - -class PAEVStepsInterpreter: public Interpreter -{ -public: - PAEVStepsInterpreter() {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - - if ( t->toInt (0, BYTE) & 0x20 ) { - str << "1/3 EV steps"; - } else { - str << "1/2 EV steps"; - } - - return str.str(); - } -}; -PAEVStepsInterpreter paEVStepsInterpreter; - -class PAEDialinInterpreter: public Interpreter -{ -public: - PAEDialinInterpreter() {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - - if ( t->toInt (0, BYTE) & 0x40 ) { - str << "P Shift"; - } else { - str << "Tv or Av"; - } - - return str.str(); - } -}; -PAEDialinInterpreter paEDialinInterpreter; - -class PAApertureRingUseInterpreter: public Interpreter -{ -public: - PAApertureRingUseInterpreter() {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - - if ( t->toInt (0, BYTE) & 0x80 ) { - str << "Permitted"; - } else { - str << "Prohibited"; - } - - return str.str(); - } -}; -PAApertureRingUseInterpreter paApertureRingUseInterpreter; - -class PAFlashOptionInterpreter: public ChoiceInterpreter<> -{ -public: - PAFlashOptionInterpreter() - { - choices[0] = "Normal"; - choices[1] = "Red-eye reduction"; - choices[2] = "Auto"; - choices[3] = "Auto, Red-eye reduction"; - choices[5] = "Wireless (Master)"; - choices[6] = "Wireless (Control)"; - choices[8] = "Slow-sync"; - choices[9] = "Slow-sync, Red-eye reduction"; - choices[10] = "Trailing-curtain Sync"; - } - std::string toString (const Tag* t) const override - { - const ChoicesIterator r = choices.find (t->toInt (0, BYTE) >> 4); - - if (r != choices.end()) { - return r->second; - } else { - char buffer[1024]; - t->toString (buffer); - return std::string (buffer); - } - } -}; -PAFlashOptionInterpreter paFlashOptionInterpreter; - -class PAMeteringMode2Interpreter: public Interpreter -{ -public: - PAMeteringMode2Interpreter() {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - int v = (t->toInt (0, BYTE) & 0xF); - - if (!v) { - str << "Multi-segment"; - } else if (v & 1) { - str << "Center-weighted average"; - } else if (v & 2) { - str << "Spot"; - } - - return str.str(); - } -}; -PAMeteringMode2Interpreter paMeteringMode2Interpreter; - -class PAExposureBracketStepSizeInterpreter: public ChoiceInterpreter<> -{ -public: - PAExposureBracketStepSizeInterpreter() - { - choices[3] = "0.3"; - choices[4] = "0.5"; - choices[5] = "0.7"; - choices[8] = "1.0"; - choices[11] = "1.3"; - choices[12] = "1.5"; - choices[13] = "1.7"; - choices[16] = "2.0"; - } -}; -PAExposureBracketStepSizeInterpreter paExposureBracketStepSizeInterpreter; - -class PAPictureMode2Interpreter: public ChoiceInterpreter<> -{ -public: - PAPictureMode2Interpreter() - { - choices[0] = "Scene Mode"; - choices[1] = "Auto PICT"; - choices[2] = "Program AE"; - choices[3] = "Green Mode"; - choices[4] = "Shutter Speed Priority"; - choices[5] = "Aperture Priority"; - choices[6] = "Program Tv Shift"; - choices[7] = "Program Av Shift"; - choices[8] = "Manual"; - choices[9] = "Bulb"; - choices[10] = "Aperture Priority, Off-Auto-Aperture"; - choices[11] = "Manual, Off-Auto-Aperture"; - choices[12] = "Bulb, Off-Auto-Aperture"; - choices[13] = "Shutter & Aperture Priority AE"; - choices[15] = "Sensitivity Priority AE"; - choices[16] = "Flash X-Sync Speed AE"; - } -}; -PAPictureMode2Interpreter paPictureMode2Interpreter; - -class PAProgramLineInterpreter: public Interpreter -{ -public: - PAProgramLineInterpreter() {} - std::string toString (const Tag* t) const override - { - std::ostringstream str; - int c = t->toInt (0, BYTE); - - switch (c & 0xf) { - case 0: - str << "Manual"; - break; - - case 1: - str << "AF-S"; - break; - - case 2: - str << "AF-C"; - break; - - case 3: - str << "AF-A"; - break; - } - - if ( (c & 0xF0) == 0) { - str << ", Point Selection Auto"; - } else if ( c & 0x20 ) { - str << ", Fixed Center Point Selected"; - } else if ( c & 0x10 ) { - str << ", Point Selected"; - } - - return str.str(); - } -}; -PAProgramLineInterpreter paProgramLineInterpreter; - -class PAAFModeInterpreter: public Interpreter -{ -public: - PAAFModeInterpreter() {} - std::string toString (const Tag* t) const override - { - switch (t->toInt (0, BYTE) & 0x3) { - case 0: - return "Normal"; - - case 1: - return "Hi Speed"; - - case 2: - return "Depth"; - - case 3: - return "MTF"; - } - - return"Normal"; - } - -}; -PAAFModeInterpreter paAFModeInterpreter; - -class PAAFPointSelectedInterpreter: public Interpreter -{ -public: - PAAFPointSelectedInterpreter() {} - std::string toString (const Tag* t) const override - { - int c = t->toInt (0, SHORT); - - if ( !c ) { - return "Auto"; - } else { - const char *ps[] = {"Upper-left", "Top", "Upper-right", "Left", "Mid-left", "Center", "Mid-right", "Right", "Lower-left", "Bottom", "Lower-right"}; - - for ( int iBit = 0; iBit < 11; iBit++) - if ( c & (1 << iBit) ) { - return ps[iBit]; - } - - return "n/a"; - } - } -}; -PAAFPointSelectedInterpreter paAFPointSelectedInterpreter; - -class PADriveMode2Interpreter: public Interpreter -{ -public: - PADriveMode2Interpreter() {} - std::string toString (const Tag* t) const override - { - int c = t->toInt (0, BYTE); - - if ( !c ) { - return "Single-frame"; - } else if ( c & 0x01) { - return "Continuous"; - } else if ( c & 0x02) { - return "Continuous (Lo)"; - } else if ( c & 0x04) { - return "Self-timer (12 s)"; - } else if ( c & 0x08) { - return "Self-timer (2 s)"; - } else if ( c & 0x10 ) { - return "Remote Control (3 s delay)"; - } else if ( c & 0x20) { - return "Remote Control"; - } else if ( c & 0x40) { - return "Exposure Bracket"; - } else if ( c & 0x80) { - return "Multiple Exposure"; - } else { - return "Unknown"; - } - } -}; -PADriveMode2Interpreter paDriveMode2Interpreter; - -const TagAttrib pentaxAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "PentaxVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "PentaxModelType", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0002, AUTO, "PreviewImageSize", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0003, AUTO, "PreviewImageLength", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0004, AUTO, "PreviewImageStart", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "PentaxModelID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "Date", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "Time", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0008, AUTO, "Quality", &paQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0009, AUTO, "PentaxImageSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000b, AUTO, "PictureMode", &paPictureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000c, AUTO, "FlashMode", &paFlashModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000d, AUTO, "FocusMode", &paFocusModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000e, AUTO, "AFPointSelected", &paAFPointInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "AFPointsInFocus", &paAFFocusInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0010, AUTO, "FocusPosition", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "ExposureTime", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0013, AUTO, "FNumber", &paFNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0014, AUTO, "ISO", &paISOInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0015, AUTO, "LightReading", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0016, AUTO, "ExposureCompensation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0017, AUTO, "MeteringMode", &paMeteringModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0018, AUTO, "AutoBracketing", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0019, AUTO, "WhiteBalance", &paWhiteBalanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001a, AUTO, "WhiteBalanceMode", &paWhiteBalanceModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001b, AUTO, "BlueBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001c, AUTO, "RedBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001d, AUTO, "FocalLength", &paFocalLengthInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001e, AUTO, "DigitalZoom", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001f, AUTO, "Saturation", &paSaturationInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0020, AUTO, "Contrast", &paContrastInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0021, AUTO, "Sharpness", &paSharpnessInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0022, AUTO, "WorldTimeLocation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0023, AUTO, "HometownCity", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x0024, AUTO, "DestinationCity", &stdInterpreter}, - {0, AC_NEW, 0, nullptr, 0x0025, AUTO, "HometownDST", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "DestinationDST", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0027, AUTO, "DSPFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0028, AUTO, "CPUFirmwareVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0029, AUTO, "FrameNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x002d, AUTO, "EffectiveLV", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0032, AUTO, "ImageProcessing", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0033, AUTO, "PictureMode", &paPictureModeInterpreter2}, - {0, AC_WRITE, 0, nullptr, 0x0034, AUTO, "DriveMode", &paDriveModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0037, AUTO, "ColorSpace", &paColorSpaceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0038, AUTO, "ImageAreaOffset", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0039, AUTO, "RawImageSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003c, AUTO, "AFPointsInFocus", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003e, AUTO, "PreviewImageBorders", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x003f, AUTO, "LensType", &paLensTypeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0040, AUTO, "SensitivityAdjust", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0041, AUTO, "ImageProcessingCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0047, AUTO, "CameraTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0048, AUTO, "AELock", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0049, AUTO, "NoiseReduction", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004d, AUTO, "FlashExposureComp", &paFlashExposureCompInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x004f, AUTO, "ImageTone", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0050, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxSRInfoAttribs, 0x005c, AUTO, "ShakeReductionInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x005d, AUTO, "ShutterCount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0069, AUTO, "DynamicRangeExpansion", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0071, AUTO, "HighISONoiseReduction", &paHighISONoiseInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0072, AUTO, "AFAdjustment", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0073, AUTO, "MonochromeFilterEffect", &paMonochromeFilterEffectInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0074, AUTO, "MonochromeToning", &paMonochromeToningInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0076, AUTO, "FaceDetect", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0077, AUTO, "FaceDetectFrameSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0079, AUTO, "ShadowCorrection", &paShadowCorrectionInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x007a, AUTO, "ISOAutoParameters", &paISOAutoParametersInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x007b, AUTO, "CrossProcess", &paCrossProcessInterpreter}, - {0, AC_WRITE, 0, pentaxLensCorrAttribs, 0x007d, AUTO, "LensCorr", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x007f, AUTO, "BleachBypassToning", &paBleachBypassToningInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0082, AUTO, "BlurControl", &paBlurControlInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0085, AUTO, "HDR", &paHDRInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0088, AUTO, "NeutralDensityFilter", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x008b, AUTO, "ISO", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0200, AUTO, "BlackPoint", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0201, AUTO, "WhitePoint", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0203, AUTO, "ColorMatrixA", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0204, AUTO, "ColorMatrixB", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxCameraSettingsAttribs, 0x0205, AUTO, "CameraSettings", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxAEInfoAttribs, 0x0206, AUTO, "AEInfo", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxLensDataAttribs, 0x0207, AUTO, "LensInfo", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxFlashInfoAttribs, 0x0208, AUTO, "FlashInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0209, AUTO, "AEMeteringSegments", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020a, AUTO, "FlashADump", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020b, AUTO, "FlashBDump", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020d, AUTO, "WB_RGGBLevelsDaylight", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020e, AUTO, "WB_RGGBLevelsShade", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x020f, AUTO, "WB_RGGBLevelsCloudy", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0210, AUTO, "WB_RGGBLevelsTungsten", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0211, AUTO, "WB_RGGBLevelsFluorescentD", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0212, AUTO, "WB_RGGBLevelsFluorescentN", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0213, AUTO, "WB_RGGBLevelsFluorescentW", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0214, AUTO, "WB_RGGBLevelsFlash", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxCameraInfoAttribs, 0x0215, AUTO, "CameraInfo", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxBatteryInfoAttribs, 0x0216, AUTO, "BatteryInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x021f, AUTO, "AFInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0222, AUTO, "ColorInfo", &stdInterpreter}, - {0, AC_WRITE, 0, pentaxLensInfoQAttribs, 0x0239, AUTO, "LensInfoQ", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03fe, AUTO, "DataDump", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x03ff, AUTO, "UnknownInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0402, AUTO, "ToneCurve", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0403, AUTO, "ToneCurves", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxSRInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "SRResult", &paSRResultInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ShakeReduction", &paShakeReductionInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "SRHalfPressTime", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "SRFocalLength", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxSRInfo2Attribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "SRResult", &paSRResultInterpreter}, // assuming it's the same interpreter, but that's not sure - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ShakeReduction", &paShakeReduction2Interpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxLensDataAttribs[] = { - {0, AC_WRITE, 0, nullptr, 9, AUTO, "FocalLength", &paLensDataFocalLengthInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "NominalMaxAperture", &paNominalMaxApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "NominalMinAperture", &paNominalMinApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 14, AUTO, "MaxAperture", &paMaxApertureInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxLensInfoQAttribs[] = { - {0, AC_WRITE, 0, nullptr, 12, AUTO, "LensModel", &paLensModelQInterpreter}, - {0, AC_WRITE, 0, nullptr, 42, AUTO, "LensInfo", &paLensInfoQInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxLensCorrAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "DistortionCorrection", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ChromaticAberrationCorrection", &paOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "VignettingCorrection", &paOnOffInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxCameraSettingsAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "PictureMode2", &paPictureMode2Interpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ProgramLine", &paProgramLineInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "EVSteps", &paEVStepsInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "E-DialinProgram", &paEDialinInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ApertureRing", &paApertureRingUseInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "FlashOptions", &paFlashOptionInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "MeteringMode2", &paMeteringMode2Interpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "AFMode", &paAFModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "AFPointSelected2", &paAFPointSelectedInterpreter}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "DriveMode2", &paDriveMode2Interpreter}, - {0, AC_WRITE, 0, nullptr, 8, AUTO, "ExposureBracketStepSize", &paExposureBracketStepSizeInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "BracketShotNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "WhiteBalanceSet", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxAEInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "AEAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "AE_ISO", &paISOfInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "AEXv", &paAEXvInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, SBYTE, "AEBXv", &paAEBXvInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "AEProgramMode", &paAEProgramModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "AEMaxAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "AEMaxAperture2", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 11, AUTO, "AEMinAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 12, AUTO, "AEMeteringMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 14, SBYTE, "FlashExposureCompSet", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxAEInfo2Attribs[] = { - {0, AC_WRITE, 0, nullptr, 2, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "AEAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "AE_ISO", &paISOfInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "AEXv", &paAEXvInterpreter}, - {0, AC_WRITE, 0, nullptr, 6, SBYTE, "AEBXv", &paAEBXvInterpreter}, - {0, AC_WRITE, 0, nullptr, 8, SBYTE, "AEError", &stdInterpreter}, -//{0, AC_WRITE, 0, 0, 11, AUTO, "AEApertureSteps", &}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "SceneMode", &paSceneModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "AEMaxAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "AEMaxAperture2", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "AEMinAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 19, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxAEInfo3Attribs[] = { - {0, AC_WRITE, 0, nullptr, 16, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "AEAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "AE_ISO", &paISOfInterpreter}, - {0, AC_WRITE, 0, nullptr, 28, AUTO, "AEMaxAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 29, AUTO, "AEMaxAperture2", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 30, AUTO, "AEMinAperture", &paApertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 31, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxFlashInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "FlashStatus", &paFlashStatusInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "InternalFlashMode", &paInternalFlashModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "ExternalFlashMode", &paExternalFlashModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "InternalFlashStrength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 24, AUTO, "ExternalFlashGuideNumber", &paExternalFlashGNInterpreter}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "ExternalFlashExposureComp", &paExternalFlashExposureCompInterpreter}, - {0, AC_WRITE, 0, nullptr, 26, AUTO, "ExternalFlashBounce", &paExternalFlashBounceInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxBatteryInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "PowerSource", &paPowerSourceInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "BatteryStates", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "BatteryADBodyNoLoad", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "BatteryADBodyLoad", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "BatteryADGripNoLoad", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "BatteryADGripLoad", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib pentaxCameraInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "PentaxModelID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ManufactureDate", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "ProductionCode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "InternalSerialNumber", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -} -#endif - - - - diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc deleted file mode 100644 index 571fd4e6b..000000000 --- a/rtexif/rtexif.cc +++ /dev/null @@ -1,3488 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * Some parts of the source code (e.g. ciff support) are taken from dcraw - * that is copyrighted by Dave Coffin - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "rtexif.h" - -#include "../rtengine/procparams.h" - -#include "../rtgui/cacheimagedata.h" -#include "../rtgui/version.h" -#include "../rtgui/ppversion.h" - -// see end of ExifManager::parse(bool, bool) -#define PRINT_METADATA_TREE 0 - -using namespace std; - -namespace rtexif -{ - -Interpreter stdInterpreter; - -//--------------- class TagDirectory ------------------------------------------ -// this class is a collection (an array) of tags -//----------------------------------------------------------------------------- - -TagDirectory::TagDirectory () - : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr) {} - -TagDirectory::TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border) - : attribs (ta), order (border), parent (p) {} - -TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored) - : attribs (ta), order (border), parent (p) -{ - - int numOfTags = get2 (f, order); - - if (numOfTags <= 0 || numOfTags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit - return; - } - - bool thumbdescr = false; - - for (int i = 0; i < numOfTags; i++) { - - Tag* newTag = new Tag (this, f, base); - - // filter out tags with unknown type - if ((int)newTag->getType() == 0) { - delete newTag; - continue; - } - - if (skipIgnored) { - int id = newTag->getID(); - - // detect and possibly ignore tags of directories belonging to the embedded thumbnail image - if (attribs == ifdAttribs && id == TIFFTAG_SUBFILETYPE && newTag->toInt() != 0) { - thumbdescr = true; - } - - const TagAttrib* attrib = getAttrib (id); - - if (!attrib || attrib->ignore == 1 || (thumbdescr && attrib->ignore == 2)) { - delete newTag; - } else { - addTag (newTag); - } - } else { - addTag (newTag); - } - } -} - -TagDirectory::~TagDirectory () -{ - - for (size_t i = 0; i < tags.size(); i++) { - delete tags[i]; - } -} - -class CompareTags -{ -public: - int operator() (Tag* const& a, Tag* const& b) const - { - return a->getID() < b->getID(); - } -}; - -void TagDirectory::sort () -{ - - std::sort (tags.begin(), tags.end(), CompareTags()); - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->isDirectory()) - for (int j = 0; tags[i]->getDirectory (j); j++) { - tags[i]->getDirectory (j)->sort (); - } -} -TagDirectory* TagDirectory::getRoot() -{ - if (parent) { - return parent->getRoot(); - } else { - return this; - } -} - -const TagAttrib* TagDirectory::getAttrib (int id) -{ - - if (attribs) - for (int i = 0; attribs[i].ignore != -1; i++) - if (attribs[i].ID == id) { - return &attribs[i]; - } - - return nullptr; -} - -const TagAttrib* TagDirectory::getAttrib (const char* name) -{ - - if (attribs) - for (int i = 0; attribs[i].ignore != -1; i++) - if (!strcmp (attribs[i].name, name)) { - return &attribs[i]; - } - - return nullptr; -} - -const TagAttrib* TagDirectory::getAttribP (const char* name) -{ - - if (attribs) - for (int i = 0; attribs[i].ignore != -1; i++) { - // Yeah, self made comparison! - const char *n = name; - const char *a = attribs[i].name; - - while (*n && *a && *n == *a) { - n++; - a++; - }; - - if (!*a && (!*n || *n == '/')) { - // we reached the end of the subpart of name and the end of attribs->name, so they match - if (*n == '/') { - Tag* tag = getTag (attribs[i].ID); - TagDirectory *tagDir; - - if (attribs[i].subdirAttribs && tag && (tagDir = tag->getDirectory())) { - return tagDir->getAttribP (n + 1); - } else { - return nullptr; - } - } else { - return &attribs[i]; - } - } - } - - return nullptr; -} - -void TagDirectory::printAll (unsigned int level) const -{ - - // set the spacer prefix string - char prefixStr[level * 4 + 1]; - unsigned int i; - - for (i = 0; i < level * 4; i++) { - prefixStr[i] = ' '; - } - - prefixStr[i] = '\0'; - - // recursively iterate over the tag list - for (size_t i = 0; i < tags.size(); i++) { - std::string name = tags[i]->nameToString (); - - TagDirectory* currTagDir; - if (tags[i]->isDirectory()) { - for (int j = 0; (currTagDir = tags[i]->getDirectory (j)) != nullptr; j++) { - printf ("%s+-- DIRECTORY %s[%d]:\n", prefixStr, name.c_str(), j); - currTagDir->printAll (level + 1); - } - } else { - printf ("%s- %s\n", prefixStr, name.c_str()); - } - } -} - -/** @brief Dump the TagDirectory and its sub-directories to the file 'fname' - * - * This method has been created to dump the metadata for the Custom Profile Builders. - * It contains an [RT General] section to communicate some parameters, then the TagDirectory follows. - * - * The key is composed as follow: "010F_Make", i.e. "tag number or ID _ tag name" - * Entries like: - * - * 927C_MakerNotesSony=$subdir - * - * indicates that this tag refer to a sub-directory. RT's Keywords begins with $, where & is the first char of the value. - * $subdir is the only keyword so far. - * - * You'll have then to check for the [EXIF/927C_MakerNotesSony] section, given that the root section - * is named [EXIF]. - * - * WARNING: Some string will be sanitized, i.e. the new line char will be replaced by "\n". You'll - * have to check for this escape string if you want a correct display of the value, but your KeyFile module - * will most likely handle that automatically for you. - * - * @param commFNname Absolute path of the temporary communication file's name - * @param commFNname Absolute path of the image's file name - * @param commFNname Absolute path of the output profiles's file name - * @param defaultPParams absolute or relative path (to the application's folder) of the default ProcParams to use - * @param cfs pointer to a CacheImageData object that will contain common values - * @param flagMode will tell whether the Custom Profile Builder is called for on flagging event or for real development - * @param keyfile The KeyFile object to dump to. Has to be NULL (default value) on first call! - * @param tagDirName Name of the current TagDirectory (full path, i.e. "EXIF/MakerNotes/LensInfo"). Can be empty on first call, "EXIF" will then be used - * - * @return True if everything went fine, false otherwise - */ -bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, - const CacheImageData* cfs, const bool flagMode, Glib::KeyFile *keyFile, Glib::ustring tagDirName) const -{ - const auto kf = keyFile ? keyFile : new Glib::KeyFile; - - if (!kf) { - return false; - } - - if (!keyFile || tagDirName.empty()) { - tagDirName = "EXIF"; - } - - std::vector tagDirList; - std::vector tagDirPaths; - - FILE *f = nullptr; - - if (!keyFile) { - // open the file in write mode - f = g_fopen (commFName.c_str (), "wt"); - - if (f == nullptr) { - printf ("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); - delete kf; - return false; - } - - try { - - kf->set_string ("RT General", "CachePath", options.cacheBaseDir); - kf->set_string ("RT General", "AppVersion", RTVERSION); - kf->set_integer ("RT General", "ProcParamsVersion", PPVERSION); - kf->set_string ("RT General", "ImageFileName", imageFName); - kf->set_string ("RT General", "OutputProfileFileName", profileFName); - kf->set_string ("RT General", "DefaultProcParams", defaultPParams); - kf->set_boolean ("RT General", "FlaggingMode", flagMode); - - kf->set_integer ("Common Data", "FrameCount", cfs->frameCount); - kf->set_integer ("Common Data", "SampleFormat", cfs->sampleFormat); - kf->set_boolean ("Common Data", "IsHDR", cfs->isHDR); - kf->set_boolean ("Common Data", "IsPixelShift", cfs->isPixelShift); - kf->set_double ("Common Data", "FNumber", cfs->fnumber); - kf->set_double ("Common Data", "Shutter", cfs->shutter); - kf->set_double ("Common Data", "FocalLength", cfs->focalLen); - kf->set_integer ("Common Data", "ISO", cfs->iso); - kf->set_string ("Common Data", "Lens", cfs->lens); - kf->set_string ("Common Data", "Make", cfs->camMake); - kf->set_string ("Common Data", "Model", cfs->camModel); - - } catch (Glib::KeyFileError&) {} - } - - // recursively iterate over the tag list - for (size_t i = 0; i < tags.size(); i++) { - std::string tagName = tags[i]->nameToString (); - - if (tags[i]->isDirectory()) - for (int j = 0; tags[i]->getDirectory (j); j++) { - // Accumulating the TagDirectories to dump later - tagDirPaths.push_back ( Glib::ustring ( tagDirName + "/" + getDumpKey (tags[i]->getID(), tagName) ) ); - tagDirList.push_back (tags[i]->getDirectory (j)); - - try { - kf->set_string (tagDirName, getDumpKey (tags[i]->getID(), tagName), "$subdir"); - } catch (Glib::KeyFileError&) {} - } else { - try { - kf->set_string (tagDirName, getDumpKey (tags[i]->getID(), tagName), tags[i]->valueToString()); - } catch (Glib::KeyFileError&) {} - } - } - - // dumping the sub-directories - for (size_t i = 0; i < tagDirList.size(); i++) { - tagDirList.at (i)->CPBDump (commFName, imageFName, profileFName, defaultPParams, cfs, flagMode, kf, tagDirPaths.at (i)); - } - - if (!keyFile) { - try { - fprintf (f, "%s", kf->to_data().c_str()); - } catch (Glib::KeyFileError&) {} - - fclose (f); - delete kf; - } - - return true; -} - -Glib::ustring TagDirectory::getDumpKey (int tagID, const Glib::ustring &tagName) -{ - Glib::ustring key; - - if (options.CPBKeys == CPBKT_TID || options.CPBKeys == CPBKT_TID_NAME) { - key = Glib::ustring (Glib::ustring::format (std::fixed, std::hex, std::setfill (L'0'), std::setw (4), tagID)); - } - - if (options.CPBKeys == CPBKT_TID_NAME) { - key += Glib::ustring ("_"); - } - - if (options.CPBKeys == CPBKT_TID_NAME || options.CPBKeys == CPBKT_NAME) { - key += Glib::ustring (tagName); - } - - return key; -} -void TagDirectory::addTag (Tag* &tag) -{ - - // look up if it already exists: - if (getTag (tag->getID())) { - delete tag; - tag = nullptr; - } else { - tags.push_back (tag); - } -} - -void TagDirectory::addTagFront (Tag* &tag) -{ - - // look up if it already exists: - if (getTag (tag->getID())) { - delete tag; - tag = nullptr; - } else { - tags.insert (tags.begin(), tag); - } -} - -void TagDirectory::replaceTag (Tag* tag) -{ - - // look up if it already exists: - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->getID() == tag->getID()) { - delete tags[i]; - tags[i] = tag; - return; - } - - tags.push_back (tag); -} - -Tag* TagDirectory::getTag (int ID) const -{ - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->getID() == ID) { - return tags[i]; - } - - return nullptr; -} - -Tag* TagDirectory::getTag (const char* name) const -{ - - if (attribs) { - for (int i = 0; attribs[i].ignore != -1; i++) - if (!strcmp (attribs[i].name, name)) { - return getTag (attribs[i].ID); - } - } - - return nullptr; -} - -Tag* TagDirectory::getTagP (const char* name) const -{ - - if (attribs) - for (int i = 0; attribs[i].ignore != -1; i++) { - // Yeah, self made comparison! - const char *n = name; - const char *a = attribs[i].name; - - while (*n && *a && *n == *a) { - n++; - a++; - }; - - if (!*a && (!*n || *n == '/')) { - // we reached the end of the subpart of name and the end of attribs->name, so they match - if (*n == '/') { - Tag* tag = getTag (attribs[i].ID); - TagDirectory *tagDir; - - if (attribs[i].subdirAttribs && tag && (tagDir = tag->getDirectory())) { - return tagDir->getTagP (n + 1); - } else { - return nullptr; - } - } else { - return getTag (attribs[i].ID); - } - } - } - - return nullptr; -} - -Tag* TagDirectory::findTag (const char* name, bool lookUpward) const -{ - Tag* t = getTag(name); - if (t) { - return t; - } - - Tag* foundTag = nullptr; - int tagDistance = 10000; - - for (auto tag : tags) { - if (tag->isDirectory()) { - TagDirectory *dir; - int i = 0; - // Find the shortest path to that tag - while ((dir = tag->getDirectory(i)) != nullptr) { - TagDirectory *dir = tag->getDirectory(); - Tag* t = dir->findTag (name); - - if (t) { - int currTagDistance = t->getDistanceFrom(this); - if (currTagDistance < tagDistance) { - tagDistance = currTagDistance; - foundTag = t; - } - } - ++i; - } - } - } - - if (foundTag) { - return foundTag; - } - - if (lookUpward && parent) { - Tag* t = parent->findTagUpward(name); - - if (t) { - return t; - } - } - - return nullptr; -} - -std::vector TagDirectory::findTags (int ID) -{ - - std::vector tagList; - - //assuming that an entry can only exist once - Tag* t = getTag(ID); - if (t) { - tagList.push_back(t); - } - - for (auto tag : tags) { - if (tag->isDirectory()) { - TagDirectory *dir; - int i = 0; - while ((dir = tag->getDirectory(i)) != nullptr) { - std::vector subTagList = dir->findTags (ID); - - if (!subTagList.empty()) { - // concatenating the 2 vectors - // not really optimal in a memory efficiency pov - for (auto tag2 : subTagList) { - tagList.push_back(tag2); - } - } - ++i; - } - } - } - - return tagList; -} - -std::vector TagDirectory::findTags (const char* name) -{ - - std::vector tagList; - - //assuming that an entry can only exist once - Tag* t = getTag(name); - if (t) { - tagList.push_back(t); - } - - for (auto tag : tags) { - if (tag->isDirectory()) { - TagDirectory *dir; - int i = 0; - while ((dir = tag->getDirectory(i)) != nullptr) { - std::vector subTagList = dir->findTags (name); - - if (!subTagList.empty()) { - // concatenating the 2 vectors - // not really optimal in a memory efficiency pov, but adding 10 items should be a maximum - for (auto tag2 : subTagList) { - tagList.push_back(tag2); - } - } - ++i; - } - } - } - - return tagList; -} - - -Tag* TagDirectory::findTagUpward (const char* name) const -{ - Tag* t = findTag(name); - if (t) { - return t; - } - - if (parent) { - Tag* t = parent->findTagUpward(name); - - if (t) { - return t; - } - } - - return nullptr; -} - - -// Searches a simple value, as either attribute or element -// only for simple values, not for entries with special chars or free text -bool TagDirectory::getXMPTagValue (const char* name, char* value) const -{ - *value = 0; - - if (!getTag ("ApplicationNotes")) { - return false; - } - - char *sXMP = (char*)getTag ("ApplicationNotes")->getValue(); - - // Check for full word - char *pos = sXMP; - - bool found = false; - - do { - pos = strstr (pos, name); - - if (pos) { - char nextChar = * (pos + strlen (name)); - - if (nextChar == ' ' || nextChar == '>' || nextChar == '=') { - found = true; - } else { - pos += strlen (name); - } - } - } while (pos && !found); - - if (!found) { - return false; - } - - char *posTag = strchr (pos, '>'); - char *posAttr = strchr (pos, '"'); - - if (!posTag && !posAttr) { - return false; - } - - if (posTag && (!posAttr || posTag < posAttr)) { - // Tag - pos = strchr (posTag + 1, '<'); - strncpy (value, posTag + 1, pos - posTag - 1); - value[pos - posTag - 1] = 0; - return true; - } else if (posAttr && (!posTag || posAttr < posTag)) { - // Attribute - pos = strchr (posAttr + 1, '"'); - strncpy (value, posAttr + 1, pos - posAttr - 1); - value[pos - posAttr - 1] = 0; - return true; - } else { - return false; - } -} - -void TagDirectory::keepTag (int ID) -{ - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->getID() == ID) { - tags[i]->setKeep (true); - } -} - -int TagDirectory::calculateSize () -{ - - int size = 2; // space to store the number of tags - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->getKeep()) { - size += 12 + tags[i]->calculateSize (); - } - - size += 4; // next ifd pointer - return size; -} - -TagDirectory* TagDirectory::clone (TagDirectory* parent) -{ - - TagDirectory* td = new TagDirectory (parent, attribs, order); - - for (size_t i = 0; i < tags.size(); i++) { - td->tags.push_back (tags[i]->clone (td)); - } - - return td; -} - -int TagDirectory::write (int start, unsigned char* buffer) -{ - - int size = calculateSize (); - int tagnum = 0; - int nondirspace = 0; - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->getKeep()) { - tagnum++; - - if (!tags[i]->isDirectory()) { - nondirspace += tags[i]->calculateSize(); - } - } - - int nextValOffs = start + 2 + tagnum * 12 + 4; - int nextDirOffs = nextValOffs + nondirspace; - int pos = start; - sset2 (tagnum, buffer + start, order); - pos += 2; - int maxPos = start + size; - - for (size_t i = 0; i < tags.size(); i++) { - if (tags[i]->getKeep()) { - if (!tags[i]->isDirectory()) { - nextValOffs = tags[i]->write (pos, nextValOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset - } else { - nextDirOffs = tags[i]->write (pos, nextDirOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset - } - - pos += 12; - } - } - - sset4 (0, buffer + pos, order); - return maxPos; -} - -void TagDirectory::applyChange (const std::string &name, const Glib::ustring &value) -{ - - std::string::size_type dp = name.find_first_of ('.'); - std::string fseg = name.substr (0, dp); - - // this is a final segment: apply change - if (dp == std::string::npos) { - - Tag* t = nullptr; - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->nameToString() == fseg) { - t = tags[i]; - break; - } - - if (value == "#keep" && t) { - t->setKeep (true); - } else if (value == "#delete" && t) { - t->setKeep (false); - } else if (t && !t->isDirectory()) { - if (name == "UserComment") { - // UserComment can be Unicode - t->userCommentFromString (value); - } else { - t->valueFromString (value); - } - } else { - const TagAttrib* attrib = nullptr; - - for (int i = 0; attribs[i].ignore != -1; i++) { - if (!strcmp (attribs[i].name, fseg.c_str())) { - attrib = &attribs[i]; - break; - } - } - - if (attrib) { - Tag* nt = new Tag (this, attrib); - if (name == "UserComment") { - // UserComment can be Unicode - nt->initUserComment (value); - } else { - nt->initString (value.c_str()); - } - addTag (nt); - } - } - } - // this is a subdirectory - else { - // try to find it - std::string::size_type dp1 = fseg.find_first_of ('['); - std::string basename = fseg.substr (0, dp1); - Tag* t = nullptr; - int dirnum = -1; - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->isDirectory()) { - for (int j = 0; tags[i]->getDirectory (j); j++) { - if (tags[i]->nameToString (j) == fseg) { - t = tags[i]; - dirnum = j; - break; - } - } - - if (!t && tags[i]->nameToString() == basename) { // found it, but that directory index does not exist - t = tags[i]; - dirnum = -1; - } - } - - if (!t && value != "#keep" && value != "#delete") { - const TagAttrib* attrib = nullptr; - - for (int i = 0; attribs[i].ignore != -1; i++) - if (!strcmp (attribs[i].name, fseg.c_str())) { - attrib = &attribs[i]; - break; - } - - if (attrib && attrib->subdirAttribs) { - t = new Tag (this, attrib); - t->initSubDir (); - addTag (t); - } - - dirnum = 0; - } - - if (t && dirnum >= 0) { - t->getDirectory (dirnum)->applyChange (name.substr (dp + 1, std::string::npos), value); - } - } -} - -TagDirectoryTable::TagDirectoryTable () - : values (nullptr), zeroOffset (0), valuesSize (0), defaultType (INVALID) -{ -} - -TagDirectoryTable::TagDirectoryTable (TagDirectory* p, unsigned char *v, int memsize, int offs, TagType type, const TagAttrib* ta, ByteOrder border) - : TagDirectory (p, ta, border), zeroOffset (offs), valuesSize (memsize), defaultType ( type ) -{ - values = new unsigned char[valuesSize]; - memcpy (values, v, valuesSize); - - // Security ; will avoid to read above the buffer limit if the RT's tagDirectoryTable is longer that what's in the file - int count = valuesSize / getTypeSize (type); - - for (const TagAttrib* tattr = ta; tattr->ignore != -1 && tattr->ID < count; ++tattr) { - Tag* newTag = new Tag (this, tattr, (values + zeroOffset + tattr->ID * getTypeSize (type)), tattr->type == AUTO ? type : tattr->type); - tags.push_back (newTag); // Here we can insert more tag in the same offset because of bitfield meaning - } -} - -TagDirectoryTable::TagDirectoryTable (TagDirectory* p, FILE* f, int memsize, int offs, TagType type, const TagAttrib* ta, ByteOrder border) - : TagDirectory (p, ta, border), zeroOffset (offs), valuesSize (memsize), defaultType ( type ) -{ - values = new unsigned char[valuesSize]; - if (fread (values, 1, valuesSize, f) == static_cast(valuesSize)) { - - // Security ; will avoid to read above the buffer limit if the RT's tagDirectoryTable is longer that what's in the file - int count = valuesSize / getTypeSize (type); - - for (const TagAttrib* tattr = ta; tattr->ignore != -1 && tattr->ID < count; ++tattr) { - Tag* newTag = new Tag (this, tattr, (values + zeroOffset + tattr->ID * getTypeSize (type)), tattr->type == AUTO ? type : tattr->type); - tags.push_back (newTag); // Here we can insert more tag in the same offset because of bitfield meaning - } - } -} -TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) -{ - - TagDirectory* td = new TagDirectoryTable (parent, values, valuesSize, zeroOffset, defaultType, attribs, order); - return td; -} - -TagDirectoryTable::~TagDirectoryTable() -{ - if (values) { - delete [] values; - } -} -int TagDirectoryTable::calculateSize () -{ - return valuesSize; -} - -int TagDirectoryTable::write (int start, unsigned char* buffer) -{ - if ( values && valuesSize) { - memcpy (buffer + start, values, valuesSize); - return start + valuesSize; - } else { - return start; - } -} - -//--------------- class Tag --------------------------------------------------- -// this class represents a tag stored in the directory -//----------------------------------------------------------------------------- - -Tag::Tag (TagDirectory* p, FILE* f, int base) - : type (INVALID), count (0), value (nullptr), allocOwnMemory (true), attrib (nullptr), parent (p), directory (nullptr) -{ - - ByteOrder order = getOrder(); - - tag = get2 (f, order); - type = (TagType)get2 (f, order); - count = get4 (f, order); - - if (!count) { - count = 1; - } - - makerNoteKind = NOMK; - keep = false; - - // filter out invalid tags - // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, - // (only a small part of it will actually be parsed though) - if ((int)type < 1 || (int)type > 14 || count > 10 * 1024 * 1024) { - type = INVALID; - valuesize = 0; - return; - } - - // store next Tag's position in file - int save = ftell (f) + 4; - - // load value field (possibly seek before) - valuesize = count * getTypeSize (type); - - if (valuesize > 4) { - fseek (f, get4 (f, getOrder()) + base, SEEK_SET); - } - - attrib = parent->getAttrib (tag); - - if (attrib && (attrib->action == AC_WRITE || attrib->action == AC_NEW)) { - keep = true; - } - - if ( tag == 0xc634 ) { // DNGPrivateData - int currPos = ftell (f); - const int buffersize = 32; - char buffer[buffersize], *p = buffer; - - while ( fread (p, 1, 1, f ) && *p != 0 && p - buffer < buffersize - 1 ) { - p++; - } - - *p = 0; - - if ( !strncmp (buffer, "Adobe", 5) ) { - fread (buffer, 1, 14, f ); - - if ( !strncmp ( buffer, "MakN", 4) ) { - ByteOrder bom = ((buffer[8] == 'M' && buffer[9] == 'M') ? MOTOROLA : INTEL) ; - Tag* tmake = parent->getRoot()->findTag ("Make"); - std::string make ( tmake ? tmake->valueToString() : ""); - int save = ftell (f); - int originalOffset = sget4 ( (unsigned char*)&buffer[10], ( make.find ("SONY") != std::string::npos ) || ( make.find ("Canon") != std::string::npos ) || ( make.find ("OLYMPUS") != std::string::npos ) ? MOTOROLA : bom ); - - if ( !parseMakerNote (f, save - originalOffset, bom )) { - type = INVALID; - } - } - } else if ( !strncmp (buffer, "PENTAX", 6) ) { - makerNoteKind = HEADERIFD; - fread (buffer, 1, 2, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, currPos, pentaxAttribs, strncmp (buffer, "MM", 2) ? INTEL : MOTOROLA); - directory[1] = nullptr; - } else - /* SONY uses this tag to write hidden info and pointer to private encrypted tags - { - unsigned offset =sget4((unsigned char*)buffer, order); - fseek(f,offset,SEEK_SET); - makerNoteKind = TABLESUBDIR; - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, sonyDNGMakerNote, order); - directory[1] = NULL; - fseek (f, save, SEEK_SET); - return; - }*/ - { - type = INVALID; - } - } - - if (tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras - ExifManager eManager(f, nullptr, true); - const auto fpos = ftell(f); - if (fpos >= 0) { - eManager.parseJPEG(fpos); // try to parse the exif data from the preview image - - if (eManager.roots.size()) { - const TagDirectory* const previewdir = eManager.roots.at(0); - if (previewdir->getTag ("Exif")) { - if (previewdir->getTag ("Make")) { - if (previewdir->getTag ("Make")->valueToString() == "Panasonic") { // "make" is not yet available here, so get it from the preview tags to assure we're doing the right thing - Tag* t = new Tag (parent->getRoot(), lookupAttrib (ifdAttribs, "Exif")); // replace raw exif with preview exif assuming there are the same - t->initSubDir (previewdir->getTag ("Exif")->getDirectory()); - parent->getRoot()->addTag (t); - } - } - } - } - } - } - - // if this tag is the makernote, it needs special treatment (brand specific parsing) - if (tag == 0x927C && attrib && !strcmp (attrib->name, "MakerNote") ) { - if ( !parseMakerNote (f, base, order )) { - type = INVALID; - fseek (f, save, SEEK_SET); - return; - } - } else if (attrib && attrib->subdirAttribs) { - // Some subdirs are specific of maker and model - char make[128], model[128]; - make[0] = 0; - model[0] = 0; - Tag* tmake = parent->getRoot()->getTag ("Make"); - - if (tmake) { - tmake->toString (make); - } - - Tag* tmodel = parent->getRoot()->getTag ("Model"); - - if (tmodel) { - tmodel->toString (model); - } - - if (!strncmp (make, "SONY", 4)) { - switch ( tag ) { - case 0x0010: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - - if (count == 15360) { - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, sonyCameraInfoAttribs, order); - } else { - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, sonyCameraInfo2Attribs, order); - } - - break; - - case 0x0114: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - - if (count == 280 || count == 364) { - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, SHORT, sonyCameraSettingsAttribs, MOTOROLA); - } else if (count == 332) { - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, SHORT, sonyCameraSettingsAttribs2, MOTOROLA); - } else if (count == 1536 || count == 2048) { - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, sonyCameraSettingsAttribs3, INTEL); - } else { - // Unknown CameraSettings - delete [] directory; - directory = nullptr; - type = INVALID; - } - - makerNoteKind = directory ? TABLESUBDIR : NOMK; - break; - - case 0x9405: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, SHORT, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - default: - goto defsubdirs; - } - } else if ((!strncmp (make, "PENTAX", 6)) || (!strncmp (make, "RICOH", 5) && !strncmp (model, "PENTAX", 6))) { // Either the former Pentax brand or the RICOH brand + PENTAX model" - switch ( tag ) { - case 0x007d: - case 0x0205: - case 0x0208: - case 0x0216: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - case 0x0215: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, LONG, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - case 0x005c: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - - if (count == 4) { // SRInfo - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, pentaxSRInfoAttribs, order); - } else if (count == 2) { // SRInfo2 - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, pentaxSRInfo2Attribs, order); - } else { - // Unknown SRInfo - delete [] directory; - directory = nullptr; - type = INVALID; - } - - makerNoteKind = directory ? TABLESUBDIR : NOMK; - break; - - case 0x0206: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - - if (count == 21) { // AEInfo2 - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, pentaxAEInfo2Attribs, order); - } else if (count == 48) { // AEInfo3 - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, pentaxAEInfo3Attribs, order); - } else if (count <= 25) { // AEInfo - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, pentaxAEInfoAttribs, order); - } else { - // Unknown AEInfo - delete [] directory; - directory = nullptr; - type = INVALID; - } - - makerNoteKind = directory ? TABLESUBDIR : NOMK; - break; - - case 0x0207: { - // There are 2 format pentaxLensDataAttribs - int offsetFirst = 4; // LensInfo2 - - if ( strstr (model, "*ist") || strstr (model, "GX-1") || strstr (model, "K200D") || (strstr (model, "K100D") && !strstr (model, "K100D Super")) || strstr (model, "K110D") || strstr (model, "645Z")) { - offsetFirst = 3; // LensInfo - } else if ( strstr (model, "645D") ) { - offsetFirst = 13; // LensInfo3 - } else if ( strstr (model, "K-01") || strstr (model, "K-30") || strstr (model, "K-50")) { - offsetFirst = 15; // LensInfo5 - } else if ( strstr (model, "K-5") || strstr (model, "K-r") ) { - offsetFirst = 12; // LensInfo4 - } else if (!strncmp (make, "RICOH", 5)) { // all PENTAX camera model produced under the RICOH era uses LensInfo5, for now... - offsetFirst = 15; // LensInfo5 too - } - - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, offsetFirst, BYTE, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - } - break; - - case 0x0239: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - default: - goto defsubdirs; - } - } else if (!strncmp (make, "Canon", 5)) { - switch ( tag ) { - case 0x0001: - case 0x0002: - case 0x0004: - case 0x0005: - case 0x0093: - case 0x0098: - case 0x00a0: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, SSHORT, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - case 0x009a: - case 0x4013: - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, LONG, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - - default: - goto defsubdirs; - } - } else if (!strncmp (make, "NIKON", 5)) { - switch (tag) { - case 0x0025: { - directory = new TagDirectory*[2]; - directory[1] = nullptr; - directory[0] = new TagDirectoryTable (parent, f, valuesize, 0, BYTE, attrib->subdirAttribs, order); - makerNoteKind = TABLESUBDIR; - break; - } - - default: - goto defsubdirs; - } - } else if (type == UNDEFINED) { - count = 1; - type = LONG; - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order); - directory[1] = nullptr; - } else { - goto defsubdirs; - } - } else { - // read value - value = new unsigned char [valuesize + 1]; - auto readSize = fread (value, 1, valuesize, f); - value[readSize] = '\0'; - } - - // seek back to the saved position - fseek (f, save, SEEK_SET); - return; - -defsubdirs: - // read value - value = new unsigned char [valuesize]; - if (fread (value, 1, valuesize, f) != static_cast(valuesize)) { - type = INVALID; - } else { - // count the number of valid subdirs - int sdcount = count; - - if (sdcount > 0) { - if (parent->getAttribTable() == olympusAttribs) { - sdcount = 1; - } - - // allocate space - directory = new TagDirectory*[sdcount + 1]; - - // load directories - for (size_t j = 0, i = 0; j < count; j++, i++) { - int newpos = base + toInt (j * 4, LONG); - fseek (f, newpos, SEEK_SET); - directory[i] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order); - } - - // set the terminating NULL - directory[sdcount] = nullptr; - } else { - type = INVALID; - } - } - // seek back to the saved position - fseek (f, save, SEEK_SET); - return; - -} - -bool Tag::parseMakerNote (FILE* f, int base, ByteOrder bom ) -{ - value = nullptr; - Tag* tmake = parent->getRoot()->findTag ("Make"); - std::string make ( tmake ? tmake->valueToString() : ""); - - Tag* tmodel = parent->getRoot()->findTag ("Model"); - std::string model ( tmodel ? tmodel->valueToString() : ""); - - if ( make.find ( "NIKON" ) != std::string::npos ) { - if ( model.find ("NIKON E700") != std::string::npos || - model.find ("NIKON E800") != std::string::npos || - model.find ("NIKON E900") != std::string::npos || - model.find ("NIKON E900S") != std::string::npos || - model.find ("NIKON E910") != std::string::npos || - model.find ("NIKON E950") != std::string::npos ) { - makerNoteKind = HEADERIFD; - valuesize = 8; - value = new unsigned char[8]; - fread (value, 1, 8, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, nikon2Attribs, bom); - directory[1] = nullptr; - } else if ( model.find ("NIKON E990") != std::string::npos || - (model.find ("NIKON D1") != std::string::npos && model.size() > 8 && model.at (8) != '0')) { - makerNoteKind = IFD; - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, nikon3Attribs, bom); - directory[1] = nullptr; - } else { - // needs refinement! (embedded tiff header parsing) - makerNoteKind = NIKON3; - valuesize = 18; - value = new unsigned char[18]; - int basepos = ftell (f); - fread (value, 1, 18, f); - directory = new TagDirectory*[2]; - // byte order for makernotes can be different from exif byte order. We have to get it from makernotes header - ByteOrder MakerNoteOrder; - - if (value[10] == 'M' && value[11] == 'M') { - MakerNoteOrder = rtexif::MOTOROLA; - } else { - MakerNoteOrder = rtexif::INTEL; - } - - directory[0] = new TagDirectory (parent, f, basepos + 10, nikon3Attribs, MakerNoteOrder); - directory[1] = nullptr; - } - } else if ( make.find ( "Canon" ) != std::string::npos ) { - makerNoteKind = IFD; - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, canonAttribs, bom); - directory[1] = nullptr; - } else if ( make.find ( "PENTAX" ) != std::string::npos ) { - makerNoteKind = HEADERIFD; - valuesize = 6; - value = new unsigned char[6]; - fread (value, 1, 6, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, pentaxAttribs, bom); - directory[1] = nullptr; - } else if ( (make.find ( "RICOH" ) != std::string::npos ) && (model.find ("PENTAX") != std::string::npos) ) { - makerNoteKind = HEADERIFD; - valuesize = 10; - value = new unsigned char[10]; - fread (value, 1, 10, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, ftell (f) - 10, pentaxAttribs, bom); - directory[1] = nullptr; - } else if ( make.find ( "FUJIFILM" ) != std::string::npos ) { - makerNoteKind = FUJI; - valuesize = 12; - value = new unsigned char[12]; - fread (value, 1, 12, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, ftell (f) - 12, fujiAttribs, INTEL); - directory[1] = nullptr; - } else if ( make.find ( "KONICA MINOLTA" ) != std::string::npos || make.find ( "Minolta" ) != std::string::npos ) { - makerNoteKind = IFD; - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, minoltaAttribs, bom); - directory[1] = nullptr; - } else if ( make.find ( "SONY" ) != std::string::npos ) { - valuesize = 12; - value = new unsigned char[12]; - fread (value, 1, 12, f); - - if (!strncmp ((char*)value, "SONY DSC", 8)) { - makerNoteKind = HEADERIFD; - } else { - makerNoteKind = IFD; - fseek (f, -12, SEEK_CUR); - } - - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, sonyAttribs, bom ); - directory[1] = nullptr; - } else if ( make.find ( "OLYMPUS" ) != std::string::npos ) { - makerNoteKind = HEADERIFD; - valuesize = 8; - value = new unsigned char[12]; - fread (value, 1, 8, f); - directory = new TagDirectory*[2]; - directory[1] = nullptr; - - if (!strncmp ((char*)value, "OLYMPUS", 7)) { - makerNoteKind = OLYMPUS2; - fread (value + 8, 1, 4, f); - valuesize = 12; - directory[0] = new TagDirectory (parent, f, ftell (f) - 12, olympusAttribs, value[8] == 'I' ? INTEL : MOTOROLA); - } else { - directory[0] = new TagDirectory (parent, f, base, olympusAttribs, bom); - } - } else if ( make.find ( "Panasonic" ) != std::string::npos) { - makerNoteKind = HEADERIFD; - valuesize = 12; - value = new unsigned char[12]; - fread (value, 1, 12, f); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom); - directory[1] = nullptr; - } else { - return false; - } - - return true; -} - -Tag* Tag::clone (TagDirectory* parent) -{ - - Tag* t = new Tag (parent, attrib); - - t->tag = tag; - t->type = type; - t->count = count; - t->keep = keep; - t->valuesize = valuesize; - - if (value) { - t->value = new unsigned char [valuesize]; - memcpy (t->value, value, valuesize); - } else { - value = nullptr; - } - - t->makerNoteKind = makerNoteKind; - - if (directory) { - int ds = 0; - - for (; directory[ds]; ds++); - - t->directory = new TagDirectory*[ds + 1]; - - for (int i = 0; i < ds; i++) { - t->directory[i] = directory[i]->clone (parent); - } - - t->directory[ds] = nullptr; - } else { - t->directory = nullptr; - } - - return t; -} - -Tag::~Tag () -{ - - // delete value - if (value && allocOwnMemory) { - delete [] value; - } - - // if there are directories behind the tag, delete them - if (directory) { - int i = 0; - - while (directory[i]) { - delete directory[i++]; - } - - delete [] directory; - } -} - -int Tag::getDistanceFrom(const TagDirectory *root) -{ - int i = 0; - TagDirectory *currTagDir = parent; - while (currTagDir != nullptr && currTagDir != root) { - ++i; - if (parent->getParent() == currTagDir) { - break; - } - currTagDir = parent->getParent(); - } - return i; -} - -void Tag::setInt (int v, int ofs, TagType astype) -{ - - if (astype == SHORT) { - sset2 (v, value + ofs, getOrder()); - } else if (astype == RATIONAL) { - sset4 (v, value + ofs, getOrder()); - sset4 (1, value + ofs + 4, getOrder()); - } else { - sset4 (v, value + ofs, getOrder()); - } -} - -void Tag::fromInt (int v) -{ - - if (type == SHORT) { - sset2 (v, value, getOrder()); - } else { - sset4 (v, value, getOrder()); - } -} - -void Tag::fromString (const char* v, int size) -{ - - if ( value && allocOwnMemory) { - delete [] value; - } - - if (size < 0) { - valuesize = strlen (v) + 1; - } else { - valuesize = size; - } - - count = valuesize; - - if ( allocOwnMemory ) { - value = new unsigned char [valuesize]; - } - - if(value) { - memcpy ((char*)value, v, valuesize); - } -} - -int Tag::toInt (int ofs, TagType astype) const -{ - if (attrib) { - return attrib->interpreter->toInt (this, ofs, astype); - } - - int a; - - if (astype == INVALID) { - astype = type; - } - - switch (astype) { - //case SBYTE: return (signed char)(value[ofs]); - case SBYTE: - return int ((reinterpret_cast (value))[ofs]); - - case BYTE: - return value[ofs]; - - case ASCII: - return 0; - - case SSHORT: - return (int)int2_to_signed (sget2 (value + ofs, getOrder())); - - case SHORT: - return (int)sget2 (value + ofs, getOrder()); - - case SLONG: - case LONG: - return (int)sget4 (value + ofs, getOrder()); - - case SRATIONAL: - case RATIONAL: - a = (int)sget4 (value + ofs + 4, getOrder()); - return a == 0 ? 0 : (int)sget4 (value + ofs, getOrder()) / a; - - case FLOAT: - return (int)toDouble (ofs); - - case UNDEFINED: - return 0; - - default: - return 0; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) - } - - return 0; -} - -double Tag::toDouble (int ofs) const -{ - if (attrib) { - return attrib->interpreter->toDouble (this, ofs); - } - - union IntFloat { - uint32_t i; - float f; - } conv; - - double ud, dd; - - switch (type) { - case SBYTE: - return (double) (int ((reinterpret_cast (value))[ofs])); - - case BYTE: - return (double) ((int)value[ofs]); - - case ASCII: - return 0.0; - - case SSHORT: - return (double)int2_to_signed (sget2 (value + ofs, getOrder())); - - case SHORT: - return (double) ((int)sget2 (value + ofs, getOrder())); - - case SLONG: - case LONG: - return (double) ((int)sget4 (value + ofs, getOrder())); - - case SRATIONAL: - case RATIONAL: - ud = (int)sget4 (value + ofs, getOrder()); - dd = (int)sget4 (value + ofs + 4, getOrder()); - return dd == 0. ? 0. : (double)ud / (double)dd; - - case FLOAT: - conv.i = sget4 (value + ofs, getOrder()); - return conv.f; // IEEE FLOATs are already C format, they just need a recast - - case UNDEFINED: - return 0.; - - default: - return 0.; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) - } - -} - -/** - * @brief Create an array of the elements - */ -double* Tag::toDoubleArray (int ofs) const -{ - double *values = new double[count]; - - for (unsigned int i = 0; i < count; ++i) { - values[i] = toDouble (ofs + i * getTypeSize (type)); - } - - return values; -} - -void Tag::toRational (int& num, int& denom, int ofs) const -{ - - switch (type) { - case BYTE: - num = (int)value[ofs]; - denom = 1; - break; - - case ASCII: - num = 0; - denom = 0; - break; - - case SSHORT: - case SHORT: - num = (int)sget2 (value + ofs, getOrder()); - denom = 1; - break; - - case SLONG: - case LONG: - num = (int)sget4 (value + ofs, getOrder()); - denom = 1; - break; - - case SRATIONAL: - case RATIONAL: - num = (int)sget4 (value + ofs, getOrder()); - denom = (int)sget4 (value + ofs + 4, getOrder()); - break; - - case FLOAT: - num = 0; - denom = 0; - break; - - case UNDEFINED: - num = 0; - denom = 0; - break; - - default: - num = 0; - denom = 0; - break; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) - } -} - -void Tag::toString (char* buffer, int ofs) const -{ - - if (type == UNDEFINED && !directory) { - bool isstring = true; - unsigned int i = 0; - - for (i = 0; i + ofs < count && i < 64 && value[i + ofs]; i++) - if (value[i + ofs] < 32 || value[i + ofs] > 126) { - isstring = false; - } - - if (isstring) { - int j = 0; - - for (i = 0; i + ofs < count && i < 64 && value[i + ofs]; i++) { - if (value[i + ofs] == '<' || value[i + ofs] == '>') { - buffer[j++] = '\\'; - } - - buffer[j++] = value[i + ofs]; - } - - buffer[j++] = 0; - return; - } - } else if (type == ASCII) { - sprintf (buffer, "%.64s", value + ofs); - return; - } - - size_t maxcount = rtengine::min(count, 10); - - strcpy (buffer, ""); - - for (ssize_t i = 0; i < rtengine::min(maxcount, valuesize - ofs); i++) { - if (i > 0) { - strcat (buffer, ", "); - } - - char* b = buffer + strlen (buffer); - - switch (type) { - case UNDEFINED: - case BYTE: - sprintf (b, "%d", value[i + ofs]); - break; - - case SSHORT: - sprintf (b, "%d", toInt (2 * i + ofs)); - break; - - case SHORT: - sprintf (b, "%u", toInt (2 * i + ofs)); - break; - - case SLONG: - sprintf (b, "%d", toInt (4 * i + ofs)); - break; - - case LONG: - sprintf (b, "%u", toInt (4 * i + ofs)); - break; - - case SRATIONAL: - case RATIONAL: - sprintf (b, "%d/%d", (int)sget4 (value + 8 * i + ofs, getOrder()), (int)sget4 (value + 8 * i + ofs + 4, getOrder())); - break; - - case FLOAT: - sprintf (b, "%g", toDouble (8 * i + ofs)); - break; - - default: - break; - } - } - - if (count > maxcount) { - strcat (buffer, "..."); - } -} - -std::string Tag::nameToString (int i) -{ - - char buffer[1025]; - - if (attrib) { - strncpy (buffer, attrib->name, 1024); - } else { - sprintf (buffer, "0x%x", tag); - } - - if (i > 0) { - sprintf (buffer + strlen (buffer) - 1, "[%d]", i); - } - - return buffer; -} - -std::string Tag::valueToString () const -{ - - if (attrib && attrib->interpreter) { - return attrib->interpreter->toString (this); - } else { - char buffer[1024]; - toString (buffer); - return buffer; - } -} - -void Tag::valueFromString (const std::string& value) -{ - - if (attrib && attrib->interpreter) { - attrib->interpreter->fromString (this, value); - } -} - -void Tag::userCommentFromString (const Glib::ustring& text) -{ - - if (!allocOwnMemory) { - return; - } - if (value) { - delete [] value; - value = nullptr; - } - initUserComment(text); -} - -int Tag::calculateSize () -{ - int size = 0; - - if (directory) { - int j; - - for (j = 0; directory[j]; j++) { - size += directory[j]->calculateSize (); - } - - if (j > 1) { - size += 4 * j; - } - if (makerNoteKind != NOMK) { - count = directory[0]->calculateSize () / getTypeSize (type); - } - } else if (valuesize > 4) { - size += valuesize + (valuesize % 2); // we align tags to even byte positions - } - - - if (makerNoteKind == NIKON3 || makerNoteKind == OLYMPUS2 || makerNoteKind == FUJI || makerNoteKind == HEADERIFD) { - size += valuesize; - } - - return size; -} - -int Tag::write (int offs, int dataOffs, unsigned char* buffer) -{ - - if ((int)type == 0 || offs > 65500) { - return dataOffs; - } - - sset2 (tag, buffer + offs, parent->getOrder()); - offs += 2; - unsigned short typ = type; - sset2 (typ, buffer + offs, parent->getOrder()); - offs += 2; - sset4 (count, buffer + offs, parent->getOrder()); - offs += 4; - - if (!directory) { - if (valuesize > 4) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - memcpy (buffer + dataOffs, value, valuesize); - - if (valuesize % 2) { - buffer[dataOffs + valuesize] = 0; // zero padding required by the exif standard - } - - return dataOffs + valuesize + (valuesize % 2); - } else { - memcpy (buffer + offs, value, valuesize); - return dataOffs; - } - } else { - if (makerNoteKind == NIKON3) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - memcpy (buffer + dataOffs, value, 18); - dataOffs += 10; - dataOffs += directory[0]->write (8, buffer + dataOffs); - return dataOffs; - } else if (makerNoteKind == OLYMPUS2 || makerNoteKind == FUJI) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - memcpy (buffer + dataOffs, value, valuesize); - dataOffs += valuesize + directory[0]->write (valuesize, buffer + dataOffs); - return dataOffs; - } else if (makerNoteKind == HEADERIFD) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - memcpy (buffer + dataOffs, value, valuesize); - dataOffs += valuesize; - dataOffs += directory[0]->write (dataOffs, buffer); - return dataOffs; - } else if ( makerNoteKind == TABLESUBDIR) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - dataOffs = directory[0]->write (dataOffs, buffer); - return dataOffs; - } else if (!directory[1]) { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - return directory[0]->write (dataOffs, buffer); - } else { - sset4 (dataOffs, buffer + offs, parent->getOrder()); - int linkOffs = dataOffs; - - for (int i = 0; directory[i]; i++) { - dataOffs += 4; - } - - for (int i = 0; directory[i]; i++) { - sset4 (dataOffs, buffer + linkOffs, parent->getOrder()); - linkOffs += 4; - dataOffs = directory[i]->write (dataOffs, buffer); - } - - return dataOffs; - } - } -} - -Tag::Tag (TagDirectory* p, const TagAttrib* attr) - : tag (attr ? attr->ID : -1), type (INVALID), count (0), value (nullptr), valuesize (0), keep (true), allocOwnMemory (true), attrib (attr), parent (p), directory (nullptr), makerNoteKind (NOMK) -{ -} - -Tag::Tag (TagDirectory* p, const TagAttrib* attr, int data, TagType t) - : tag (attr ? attr->ID : -1), type (t), count (1), value (nullptr), valuesize (0), keep (true), allocOwnMemory (true), attrib (attr), parent (p), directory (nullptr), makerNoteKind (NOMK) -{ - - initInt (data, t); -} - -Tag::Tag (TagDirectory* p, const TagAttrib* attr, unsigned char *data, TagType t) - : tag (attr ? attr->ID : -1), type (t), count (1), value (nullptr), valuesize (0), keep (true), allocOwnMemory (false), attrib (attr), parent (p), directory (nullptr), makerNoteKind (NOMK) -{ - - initType (data, t); -} - -Tag::Tag (TagDirectory* p, const TagAttrib* attr, const char* text) - : tag (attr ? attr->ID : -1), type (ASCII), count (1), value (nullptr), valuesize (0), keep (true), allocOwnMemory (true), attrib (attr), parent (p), directory (nullptr), makerNoteKind (NOMK) -{ - - initString (text); -} - -void Tag::initType (unsigned char *data, TagType type) -{ - valuesize = getTypeSize (type); - - if ( allocOwnMemory ) { - value = new unsigned char[valuesize]; - memcpy ((char*)value, data, valuesize); - } else { - value = data; - } -} - -void Tag::initInt (int data, TagType t, int cnt) -{ - - type = t; - - if (t == LONG) { - valuesize = 4; - } else if (t == SHORT) { - valuesize = 2; - } else if (t == BYTE) { - valuesize = 1; - } else if (t == RATIONAL) { - valuesize = 8; - } - - count = cnt; - valuesize *= count; - value = new unsigned char[valuesize]; - setInt (data, 0, t); -} - -void Tag::swapByteOrder2(unsigned char *buffer, int count) -{ - unsigned char* ptr = buffer; - for (int i = 0; i < count; i+=2) { - unsigned char c = ptr[0]; - ptr[0] = ptr[1]; - ptr[1] = c; - ptr += 2; - } -} -void Tag::initUserComment (const Glib::ustring &text) -{ - const bool useBOM = false; // set it to true if you want to output BOM in UCS-2/UTF-8 UserComments ; this could be turned to an options entry - type = UNDEFINED; - if (text.is_ascii()) { - valuesize = count = 8 + strlen (text.c_str()); - value = new unsigned char[valuesize]; - memcpy(value, "ASCII\0\0\0", 8); - memcpy(value + 8, text.c_str(), valuesize - 8); - } else { - glong wcStrSize = 0; - gunichar2 *commentStr = g_utf8_to_utf16 (text.c_str(), -1, nullptr, &wcStrSize, nullptr); - valuesize = count = wcStrSize * 2 + 8 + (useBOM ? 2 : 0); - value = new unsigned char[valuesize]; - memcpy(value, "UNICODE\0", 8); - - if (useBOM) { - if (getOrder() == INTEL) { //Little Endian - value[8] = 0xFF; - value[9] = 0xFE; - } else { - value[8] = 0xFE; - value[9] = 0xFF; - } - } - - // Swapping byte order to match the Exif's byte order - if (getOrder() != HOSTORDER) { - swapByteOrder2((unsigned char*)commentStr, wcStrSize * 2); - } - - memcpy(value + 8 + (useBOM ? 2 : 0), (char*)commentStr, wcStrSize * 2); - g_free(commentStr); - } -} - -void Tag::initString (const char* text) -{ - - type = ASCII; - count = strlen (text) + 1; - valuesize = count; - value = new unsigned char[valuesize]; - strcpy ((char*)value, text); -} - -void Tag::initSubDir () -{ - type = LONG; - valuesize = 4; - count = 1; - value = new unsigned char[4]; - setInt (0); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, attrib ? attrib->subdirAttribs : nullptr, parent->getOrder()); - directory[1] = nullptr; -} - -void Tag::initSubDir (TagDirectory* dir) -{ - type = LONG; - valuesize = 4; - count = 1; - value = new unsigned char[4]; - setInt (0); - directory = new TagDirectory*[2]; - directory[0] = dir; - directory[1] = nullptr; -} - -void Tag::initMakerNote (MNKind mnk, const TagAttrib* ta) -{ - type = UNDEFINED; - valuesize = 4; - count = 1; - value = new unsigned char[4]; - setInt (0); - directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, ta, parent->getOrder()); - directory[1] = nullptr; - makerNoteKind = mnk; -} - -void Tag::initUndefArray (const char* data, int len) -{ - type = UNDEFINED; - count = valuesize = len; - value = new unsigned char[valuesize]; - memcpy (value, data, len); -} - -void Tag::initLongArray (const char* data, int len) -{ - type = LONG; - count = (len + 3) / 4; - valuesize = count * 4; - value = new unsigned char[valuesize]; - memcpy (value, data, len); -} - -void Tag::initRational (int num, int den) -{ - count = 1; - valuesize = 8; - value = new unsigned char[8]; - type = RATIONAL; - setInt (num, 0); - setInt (den, 4); -} - -//--------------- class IFDParser --------------------------------------------- -// static functions to read tag directories from different kinds of files -//----------------------------------------------------------------------------- - - -const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field) -{ - - for (int i = 0; dir[i].ignore != -1; i++) - if (!strcmp (dir[i].name, field)) { - return &dir[i]; - } - - return nullptr; -} - -void ExifManager::setIFDOffset(unsigned int offset) -{ - IFDOffset = offset; -} - -void ExifManager::parseCIFF () -{ - - TagDirectory* root = new TagDirectory (nullptr, ifdAttribs, INTEL); - Tag* exif = new Tag (root, lookupAttrib (ifdAttribs, "Exif")); - exif->initSubDir (); - root->addTag (exif); - if (exif) { - Tag* mn = new Tag (exif->getDirectory(), lookupAttrib (exifAttribs, "MakerNote")); - mn->initMakerNote (IFD, canonAttribs); - exif->getDirectory()->addTag (mn); - } - parseCIFF (rml->ciffLength, root); - root->sort (); - parse(true); -} - -Tag* ExifManager::saveCIFFMNTag (TagDirectory* root, int len, const char* name) -{ - int s = ftell (f); - if(s >= 0) { - char* data = new char [len]; - fread (data, len, 1, f); - TagDirectory* mn = root->getTag ("Exif")->getDirectory()->getTag ("MakerNote")->getDirectory(); - Tag* cs = new Tag (mn, lookupAttrib (canonAttribs, name)); - cs->initUndefArray (data, len); - mn->addTag (cs); - fseek (f, s, SEEK_SET); - delete [] data; - return cs; - } else { - return nullptr; - } -} - -void ExifManager::parseCIFF (int length, TagDirectory* root) -{ - - if (!f) { - #ifndef NDEBUG - std::cerr << "ERROR : no file opened !" << std::endl; - #endif - return; - } - - char buffer[1024]; - Tag* t; - - if (fseek(f, rml->ciffBase + length - 4, SEEK_SET)) { - return; - } - - int dirStart = get4 (f, INTEL) + rml->ciffBase; - if (fseek(f, dirStart, SEEK_SET)) { - return; - } - - int numOfTags = get2 (f, INTEL); - - if (numOfTags > 100) { - return; - } - - float exptime, shutter, aperture, fnumber, ev; - exptime = fnumber = shutter = aperture = ev = -1000.f; - int focal_len, iso; - focal_len = iso = -1; - - TagDirectory* exif = root->getTag ("Exif")->getDirectory(); - - time_t timestamp = time (nullptr); - - for (int i = 0; i < numOfTags; i++) { - - int type = get2 (f, INTEL); - int len = get4 (f, INTEL); - int nextPos = ftell (f) + 4; - - // seek to the location of the value - fseek (f, rml->ciffBase + get4 (f, INTEL), SEEK_SET); - - if ((((type >> 8) + 8) | 8) == 0x38) { - ExifManager( - f, - std::unique_ptr( - new rtengine::RawMetaDataLocation( - ftell(f), - len - ) - ), - true - ).parseCIFF(len, root); // Parse a sub-table - } - - if (type == 0x0810) { - fread (buffer, 64, 1, f); - t = new Tag (root, lookupAttrib (ifdAttribs, "Artist")); - t->initString (buffer); - root->addTag (t); - } - - if (type == 0x080a) { - fread (buffer, 64, 1, f); - t = new Tag (root, lookupAttrib (ifdAttribs, "Make")); - t->initString (buffer); - root->addTag (t); - if (!fseek (f, strlen (buffer) - 63, SEEK_CUR)) { - if (fread (buffer, 64, 1, f) == 1) { - t = new Tag (root, lookupAttrib (ifdAttribs, "Model")); - t->initString (buffer); - root->addTag (t); - } - } - } - - if (type == 0x1818) { - ev = int_to_float (get4 (f, INTEL)); - shutter = int_to_float (get4 (f, INTEL)); - exptime = pow (2, -shutter); - aperture = int_to_float (get4 (f, INTEL)); - fnumber = pow (2, aperture / 2); - - } - - ExifManager exifManager(f, nullptr, true); - if (type == 0x102d) { - Tag* t = exifManager.saveCIFFMNTag (root, len, "CanonCameraSettings"); - int mm = t->toInt (34, SHORT); - Tag* nt = new Tag (exif, lookupAttrib (exifAttribs, "MeteringMode")); - - switch (mm) { - case 0: - nt->initInt (5, SHORT); - break; - - case 1: - nt->initInt (3, SHORT); - break; - - case 2: - nt->initInt (1, SHORT); - break; - - case 3: - nt->initInt (5, SHORT); - break; - - case 4: - nt->initInt (6, SHORT); - break; - - case 5: - nt->initInt (2, SHORT); - break; - } - - exif->addTag (nt); - nt = new Tag (exif, lookupAttrib (exifAttribs, "MaxApertureValue")); - nt->initRational (t->toInt (52, SHORT), 32); - exif->addTag (nt); - int em = t->toInt (40, SHORT); - nt = new Tag (exif, lookupAttrib (exifAttribs, "ExposureProgram")); - - switch (em) { - case 0: - nt->initInt (2, SHORT); - break; - - case 1: - nt->initInt (2, SHORT); - break; - - case 2: - nt->initInt (4, SHORT); - break; - - case 3: - nt->initInt (3, SHORT); - break; - - case 4: - nt->initInt (1, SHORT); - break; - - default: - nt->initInt (0, SHORT); - break; - } - - exif->addTag (nt); - nt = new Tag (exif, lookupAttrib (exifAttribs, "Flash")); - - if (t->toInt (8, SHORT) == 0) { - nt->initInt (0, SHORT); - } else { - nt->initInt (1, SHORT); - } - - exif->addTag (nt); - nt = new Tag (exif, lookupAttrib (exifAttribs, "MaxApertureValue")); - nt->initRational (t->toInt (52, SHORT), 32); - exif->addTag (nt); - } - - if (type == 0x1029) { - exifManager.saveCIFFMNTag (root, len, "CanonFocalLength"); - } - - if (type == 0x1031) { - exifManager.saveCIFFMNTag (root, len, "SensorInfo"); - } - - if (type == 0x1033) { - exifManager.saveCIFFMNTag (root, len, "CustomFunctions"); - } - - if (type == 0x1038) { - exifManager.saveCIFFMNTag (root, len, "CanonAFInfo"); - } - - if (type == 0x1093) { - exifManager.saveCIFFMNTag (root, len, "CanonFileInfo"); - } - - if (type == 0x10a9) { - exifManager.saveCIFFMNTag (root, len, "ColorBalance"); - } - - if (type == 0x102a) { - exifManager.saveCIFFMNTag (root, len, "CanonShotInfo"); - - iso = pow (2, (get4 (f, INTEL), get2 (f, INTEL)) / 32.0 - 4) * 50; - aperture = (get2 (f, INTEL), (short)get2 (f, INTEL)) / 32.0f; - fnumber = pow (2, aperture / 2); - shutter = ((short)get2 (f, INTEL)) / 32.0f; - ev = ((short)get2 (f, INTEL)) / 32.0f; - fseek (f, 34, SEEK_CUR); - - if (shutter > 1e6) { - shutter = get2 (f, INTEL) / 10.0f; - } - - exptime = pow (2, -shutter); - } - - if (type == 0x5029) { - focal_len = len >> 16; - - if ((len & 0xffff) == 2) { - focal_len /= 32; - } - } - -// if (type == 0x5813) flash_used = int_to_float(len); - if (type == 0x580e) { - timestamp = len; - } - - if (type == 0x180e) { - timestamp = get4 (f, INTEL); - } - - if ((type | 0x4000) == 0x580e) { - timestamp = mktime (gmtime (×tamp)); - } - - fseek (f, nextPos, SEEK_SET); - } - - if (shutter > -999) { - t = new Tag (exif, lookupAttrib (exifAttribs, "ShutterSpeedValue")); - t->initRational ((int) (shutter * 10000), 10000); - exif->addTag (t); - } - - if (exptime > -999) { - t = new Tag (exif, lookupAttrib (exifAttribs, "ExposureTime")); - t->initRational ((int) (exptime * 10000), 10000); - exif->addTag (t); - } - - if (aperture > -999) { - t = new Tag (exif, lookupAttrib (exifAttribs, "ApertureValue")); - t->initRational ((int) (aperture * 10), 10); - exif->addTag (t); - } - - if (fnumber > -999) { - t = new Tag (exif, lookupAttrib (exifAttribs, "FNumber")); - t->initRational ((int) (fnumber * 10), 10); - exif->addTag (t); - } - - if (ev > -999) { - t = new Tag (exif, lookupAttrib (exifAttribs, "ExposureBiasValue")); - t->initRational ((int) (ev * 1000), 1000); - exif->addTag (t); - } - - if (iso > 0) { - t = new Tag (exif, lookupAttrib (exifAttribs, "ISOSpeedRatings")); - t->initInt (iso, LONG); - exif->addTag (t); - } - - if (focal_len > 0) { - t = new Tag (exif, lookupAttrib (exifAttribs, "FocalLength")); - t->initRational (focal_len * 32, 32); - exif->addTag (t); - } - - if (timestamp != time (nullptr)) { - struct tm* tim = localtime (×tamp); - strftime (buffer, 20, "%Y:%m:%d %H:%M:%S", tim); - t = new Tag (exif, lookupAttrib (exifAttribs, "DateTimeOriginal")); - t->initString (buffer); - exif->addTag (t); - t = new Tag (exif, lookupAttrib (exifAttribs, "DateTimeDigitized")); - t->initString (buffer); - exif->addTag (t); - t = new Tag (root, lookupAttrib (ifdAttribs, "DateTime")); - t->initString (buffer); - root->addTag (t); - } - - roots.push_back(root); - -} - -static void -parse_leafdata (TagDirectory* root, ByteOrder order) -{ - - Tag *leafdata = root->getTag ("LeafData"); - - if (!leafdata) { - return; - } - - unsigned char *value = leafdata->getValue(); - int valuesize = leafdata->getValueSize(); - - // parse LeafData tag, a tag specific to Leaf digital backs, and has a custom - // format with 52 byte tag headers starting with "PKTS" - const char *PKTS_tag = (order == MOTOROLA) ? "PKTS" : "STKP"; - char *hdr; - int pos = 0; - - // There are lots of sub-tags in here, but for now we only care about those directly - // useful to RT, which is ISO and rotation. Shutter speed and aperture is not - // available here. - int iso_speed = 0; - int rotation_angle = 0; - int found_count = 0; - - while (pos + (int)sizeof (hdr) <= valuesize && found_count < 2) { - hdr = (char *)&value[pos]; - - if (strncmp (hdr, PKTS_tag, 4) != 0) { - // in a few cases the header can be offset a few bytes, don't know why - // it does not seem to be some sort of alignment, it appears random, - // this check takes care of it, restart if we find an offset match. - int offset = 1; - - for (; offset <= 3; offset++) { - if (strncmp (&hdr[offset], PKTS_tag, 4) == 0) { - pos += offset; - break; - } - } - - if (offset <= 3) { - continue; - } - - break; - } - - int size = sget4 ((unsigned char *)&hdr[48], order); - - if (pos + size > valuesize) { - break; - } - - pos += 52; - char *val = (char *)&value[pos]; - - if (strncmp (&hdr[8], "CameraObj_ISO_speed", 19) == 0) { - iso_speed = 25 * (1 << std::max((atoi (val) - 1), 0)); - found_count++; - } else if (strncmp (&hdr[8], "ImgProf_rotation_angle", 22) == 0) { - rotation_angle = atoi (val); - found_count++; - } else { - // check if this is a sub-directory, include test for that strange offset of next header - if (size >= 8 && - (strncmp (val, PKTS_tag, 4) == 0 || - strncmp (&val[1], PKTS_tag, 4) == 0 || - strncmp (&val[2], PKTS_tag, 4) == 0 || - strncmp (&val[3], PKTS_tag, 4) == 0)) { - // start of next hdr, this is a sub-directory, we skip those for now. - size = 0; - } - } - - pos += size; - } - - // create standard tags from the custom Leaf tags - Tag* exif = root->getTag ("Exif"); - - if (!exif) { - exif = new Tag (root, root->getAttrib ("Exif")); - exif->initSubDir(); - root->addTagFront (exif); - } - - if (exif && !exif->getDirectory()->getTag ("ISOSpeedRatings")) { - Tag *t = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - t->initInt (iso_speed, LONG); - exif->getDirectory()->addTagFront (t); - } - - if (!root->getTag ("Orientation")) { - int orientation; - - switch (rotation_angle) { - case 0: - orientation = 1; - break; - - case 90: - orientation = 6; - break; - - case 180: - orientation = 3; - break; - - case 270: - orientation = 8; - break; - - default: - orientation = 1; - break; - } - - Tag *t = new Tag (root, root->getAttrib ("Orientation")); - t->initInt (orientation, SHORT); - root->addTagFront (t); - } - - // now look in ApplicationNotes tag for additional information - Tag *appnotes = root->getTag ("ApplicationNotes"); - - if (!appnotes) { - return; - } - - char *xmp = (char *)appnotes->getValue(); - char *end, *p; - - // Quick-and-dirty value extractor, no real xml parsing. - // We could make it more generic, but we just get most important - // values we know use to be in there. - if ((p = strstr (xmp, "xmlns:tiff")) != nullptr && - (end = strstr (p, "")) != nullptr) { - *end = '\0'; - - while ((p = strstr (p, "')) == nullptr) { - break; - } - - *tagend = '\0'; - char *val = &tagend[1]; - - if ((p = strstr (val, "getAttrib (tag) && !root->getTag (tag)) { - Tag *t = new Tag (root, root->getAttrib (tag)); - - if (strcmp (tag, "Make") == 0 || - strcmp (tag, "Model") == 0) { - if (strcmp (tag, "Model") == 0) { - // Leaf adds back serial number and camera model to the 'Model' - // tag, we strip that away here so the back can be recognized - // and matched against DCP profile - char *p1 = strchr (val, '('); - - if (p1 != nullptr) { - *p1 = '\0'; - } - - // Model name also contains a leading "Leaf " which we already - // have in the Make name, remove that. - if (strstr (val, "Leaf ") == val) { - t->initString (&val[5]); - } else { - t->initString (val); - } - - if (p1 != nullptr) { - *p1 = '('; - } - } else { - t->initString (val); - } - - root->addTagFront (t); - } else { - delete t; - } - } - - *p = '<'; - *tagend = '>'; - } - - *end = '<'; - } - - if ((p = strstr (xmp, "xmlns:exif")) != nullptr && - (end = strstr (p, "")) != nullptr) { - *end = '\0'; - - while ((p = strstr (p, "')) == nullptr) { - break; - } - - *tagend = '\0'; - char *val = &tagend[1]; - - if ((p = strstr (val, "getDirectory()->getAttrib (tag) && !exif->getDirectory()->getTag (tag)) { - Tag *t = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib (tag)); - int num, denom; - struct tm tm; - - if (strcmp (tag, "ApertureValue") == 0 && sscanf (val, "%d/%d", &num, &denom) == 2) { - t->initRational (num, denom); - exif->getDirectory()->addTagFront (t); - // we also make an "FNumber" tag since many tools don't interpret ApertureValue - // according to Exif standard - t = new Tag (exif->getDirectory(), lookupAttrib (exifAttribs, "FNumber")); - double f = pow (sqrt (2.0), ((double)num / denom)); - - if (f > 10.0) { - t->initRational ((int)floor (f), 1); - } else { - t->initRational ((int)floor (f * 10.0), 10); - } - - exif->getDirectory()->addTagFront (t); - } else if (strcmp (tag, "ShutterSpeedValue") == 0 && sscanf (val, "%d/%d", &num, &denom) == 2) { - t->initRational (num, denom); - exif->getDirectory()->addTagFront (t); - // we also make an "ExposureTime" tag since many tools don't interpret ShutterSpeedValue - // according to Exif standard - t = new Tag (exif->getDirectory(), lookupAttrib (exifAttribs, "ExposureTime")); - double f = 1.0 / pow (2.0, ((double)num / denom)); - - if (f > 10.0) { - t->initRational ((int)floor (f), 1); - } else if (f > 1.0) { - t->initRational ((int)floor (f * 10.0), 10); - } else if (f == 1.0) { - t->initRational (1, 1); - } else { - f = 1.0 / f; - static const double etimes[] = { - 10000, 8000, 6400, 6000, 5000, - 4000, 3200, 3000, 2500, - 2000, 1600, 1500, 1250, - 1000, 800, 750, 640, - 500, 400, 350, 320, - 250, 200, 180, 160, - 125, 100, 90, 80, - 60, 50, 45, 40, - 30, 25, 22, 20, - 15, 13, 11, 10, - 8, 6, 5, - 4, 3, 2.5, - 2, 1.6, 1.5, 1.3, - 1, -1 - }; - double diff = etimes[0]; - int idx = -1; - - for (int i = 1; etimes[i] > 0; i++) { - if (abs (etimes[i] - f) < diff) { - idx = i; - diff = abs (etimes[i] - f); - } - } - - if (idx != -1 && f < etimes[0]) { - f = etimes[idx]; - } - - if (f < 2) { - t->initRational (10, (int) (10 * f)); - } else { - t->initRational (1, (int)f); - } - } - - exif->getDirectory()->addTagFront (t); - } else if (strcmp (tag, "FocalLength") == 0 && sscanf (val, "%d/%d", &num, &denom) == 2) { - t->initRational (num, denom); - exif->getDirectory()->addTagFront (t); - } else if (strcmp (tag, "ISOSpeedRatings") == 0) { - char *p1 = val; - - while (*p1 != '\0' && !isdigit (*p1)) { - p1++; - } - - if (*p1 != '\0') { - t->initInt (atoi (p1), LONG); - exif->getDirectory()->addTagFront (t); - } else { - delete t; - } - } else if (strcmp (tag, "DateTimeOriginal") == 0 && - sscanf (val, "%d-%d-%dT%d:%d:%dZ", - &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec) == 6) { - char tstr[64]; - sprintf (tstr, "%04d:%02d:%02d %02d:%02d:%02d", tm.tm_year, tm.tm_mon, - tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - t->initString (tstr); - exif->getDirectory()->addTagFront (t); - } else { - delete t; - } - } - - *p = '<'; - *tagend = '>'; - } - - *end = '<'; - } -} - -void ExifManager::parseRaw (bool skipIgnored) { - parse(true, skipIgnored); -} - -void ExifManager::parseStd (bool skipIgnored) { - parse(false, skipIgnored); -} - -void ExifManager::parse (bool isRaw, bool skipIgnored) -{ - int ifdOffset = IFDOffset; - - if (!f) { - #ifndef NDEBUG - std::cerr << "ERROR : no file opened !" << std::endl; - #endif - return; - } - setlocale (LC_NUMERIC, "C"); // to set decimal point in sscanf - - if (order == ByteOrder::UNKNOWN) { - // read tiff header - fseek (f, rml->exifBase, SEEK_SET); - unsigned short bo; - fread (&bo, 1, 2, f); - order = (ByteOrder) ((int)bo); - get2 (f, order); - if (!ifdOffset) { - ifdOffset = get4 (f, order); - } - } - - do { - // seek to IFD - fseek (f, rml->exifBase + ifdOffset, SEEK_SET); - - // first read the IFD directory - TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored); - - // fix ISO issue with nikon and panasonic cameras - Tag* make = root->getTag ("Make"); - Tag* exif = root->getTag ("Exif"); - - if (exif && !exif->getDirectory()->getTag ("ISOSpeedRatings")) { - if (make && !strncmp ((char*)make->getValue(), "NIKON", 5)) { - Tag* mn = exif->getDirectory()->getTag ("MakerNote"); - - if (mn) { - Tag* iso = mn->getDirectory()->getTag ("ISOSpeed"); - - if (iso) { - std::string isov = iso->valueToString (); - Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - niso->initInt (atoi (isov.c_str()), SHORT); - exif->getDirectory()->addTagFront (niso); - } - } - } else if (make && (!strncmp ((char*)make->getValue(), "Panasonic", 9) || !strncmp ((char*)make->getValue(), "LEICA", 5))) { - Tag* iso = root->getTag ("PanaISO"); - - if (iso) { - std::string isov = iso->valueToString (); - Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - niso->initInt (atoi (isov.c_str()), SHORT); - exif->getDirectory()->addTagFront (niso); - } - } - } - - if (make && !strncmp ((char*)make->getValue(), "Kodak", 5)) { - if (!exif) { - // old Kodak cameras may have exif tags in IFD0, reparse and create an exif subdir - fseek (f, rml->exifBase + ifdOffset, SEEK_SET); - TagDirectory* exifdir = new TagDirectory (nullptr, f, rml->exifBase, exifAttribs, order, true); - - exif = new Tag (root, root->getAttrib ("Exif")); - exif->initSubDir (exifdir); - root->addTagFront (exif); - - if (exif && !exif->getDirectory()->getTag ("ISOSpeedRatings") && exif->getDirectory()->getTag ("ExposureIndex")) { - Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - niso->initInt (exif->getDirectory()->getTag ("ExposureIndex")->toInt(), SHORT); - exif->getDirectory()->addTagFront (niso); - } - } - - Tag *kodakIFD = root->getTag ("KodakIFD"); - - if (kodakIFD && kodakIFD->getDirectory()->getTag ("TextualInfo")) { - parseKodakIfdTextualInfo (kodakIFD->getDirectory()->getTag ("TextualInfo"), exif); - } - } - - parse_leafdata (root, order); - - if (make && !strncmp ((char*)make->getValue(), "Hasselblad", 10)) { - /* - Figuring out the Hasselblad model is a mess. Hasselblad raw data comes in four slightly - different containers, 3FR (directly from CF card), FFF (same as 3FR but filtered through - Phocus, calibration data applied and a bit different tags), Adobe-generated DNGs and - Phocus-generated DNGs. - - FFF usually has a sane model name in Model (and is used as reference for what we shall - call the different Hasselblad models), but 3FR only says like "Hasselblad H3D" for - all H3D models, or "Flash Sync" if the back has been used on a mechanical camera body. - V-mount backs may have the model name of the V body instead of the back model. Etc... - as said it's a mess. - - This code is supposed to handle all raw containers and end up with the same model - regardless of container. - - We don't differ between single shot and multi-shot models, and probably there's no use - of doing so. You need Hasselblad's own software to shoot multi-shot and can only do that - tethered. In single-shot mode they should be exactly the same as the single-shot models. - */ - Tag *subd = root->getTag (0x14a); - Tag *iw = (subd) ? subd->getDirectory()->getTag ("ImageWidth") : nullptr; - int sensorWidth = (iw) ? iw->toInt() : 0; - Tag* tmodel = root->getTag ("Model"); - const char *model = (tmodel) ? (const char *)tmodel->getValue() : ""; - - if (strstr (model, "Hasselblad ") == model) { - model += 11; - } else { - // if HxD is used in flash sync mode for example, we need to fetch model from this tag - Tag* tmodel3 = root->getTag ("UniqueCameraModel"); - const char *model3 = (tmodel3) ? (const char *)tmodel3->getValue() : ""; - - if (strstr (model3, "Hasselblad ") == model3) { - model = model3 + 11; - } - } - - // FIXME: due to lack of test files this Hasselblad model identification is not 100% complete - // This needs checking out: CFV-39/CFV-50 3FR, H3DII vs H3D, old CF/CFH models - - if (!strcmp (model, "H3D")) { - // We can't differ between H3D and H3DII for the 22, 31 and 39 models. There's was no H3D-50 so we know that is a - // H3DII-50. At the time of writing I have no test files for the H3D vs H3DII models, so there still may be a chance - // to differ between them. AFAIK Adobe's DNG converter don't differ between them, and actually call the H3DII-50 - // H3D-50 although Hasselblad never released such a model. - switch (sensorWidth) { - case 4096: - tmodel->initString ("H3D-22"); - break; - - case 6542: - tmodel->initString ("H3D-31"); - break; - - case 7262: - tmodel->initString ("H3D-39"); - break; - - case 8282: - tmodel->initString ("H3DII-50"); - break; - } - } else if (!strcmp (model, "H4D")) { - switch (sensorWidth) { - case 6542: - tmodel->initString ("H4D-31"); - break; - - case 7410: - tmodel->initString ("H4D-40"); - break; - - case 8282: - tmodel->initString ("H4D-50"); - break; - - case 9044: - tmodel->initString ("H4D-60"); - break; - } - } else if (!strcmp (model, "H5D")) { - switch (sensorWidth) { - case 7410: - tmodel->initString ("H5D-40"); - break; - - case 8282: - tmodel->initString ("H5D-50"); - break; - - case 8374: - tmodel->initString ("H5D-50c"); - break; - - case 9044: - tmodel->initString ("H5D-60"); - break; - } - } else if (!strcmp (model, "CFV")) { - switch (sensorWidth) { - case 7262: - tmodel->initString ("CFV-39"); - break; - - case 8282: - tmodel->initString ("CFV-50"); - break; - - case 8374: - tmodel->initString ("CFV-50c"); - break; - } - } - - // and a few special cases - Tag* tmodel3 = root->getTag ("UniqueCameraModel"); - const char *model3 = (tmodel3) ? (const char *)tmodel3->getValue() : ""; - - if (strstr (model3, "Hasselblad ") == model3) { - model3 = model3 + 11; - } - - if (!strcmp (model3, "ixpressCF132")) { - tmodel->initString ("CF-22"); - } else if (!strcmp (model3, "Hasselblad96")) { - tmodel->initString ("CFV"); // popularly called CFV-16, but the official name is CFV - } else if (!strcmp (model3, "Hasselblad234")) { - tmodel->initString ("CFV-39"); - } else if (sensorWidth == 4090) { - tmodel->initString ("V96C"); - } - - // and yet some, this is for Adobe-generated DNG files - Tag* tmodel4 = root->getTag ("LocalizedCameraModel"); - - if (tmodel4) { - const char *model4 = (const char *)tmodel4->getValue(); - - if (strstr (model4, "Hasselblad ") == model4) { - model4 = model4 + 11; - } - - if (!strcmp (model4, "ixpressCF132-22")) { - tmodel->initString ("CF-22"); - } else if (!strcmp (model4, "Hasselblad96-16")) { - tmodel->initString ("CFV"); - } else if (!strcmp (model4, "Hasselblad234-39")) { - tmodel->initString ("CFV-39"); - } else if (!strcmp (model4, "H3D-50")) { - // Adobe names H3DII-50 incorrectly as H3D-50 - tmodel->initString ("H3DII-50"); - } else if (strstr (model4, "H3D-") == model4 || strstr (model4, "H4D-") == model4 || strstr (model4, "H5D-") == model4) { - tmodel->initString (model4); - } - } - } - - if (!root->getTag ("Orientation")) { - if (make && !strncmp ((char*)make->getValue(), "Phase One", 9)) { - int orientation = 0; - Tag *iw = root->getTag ("ImageWidth"); - - if (iw) { - // from dcraw, derive orientation from image width - orientation = "0653"[iw->toInt() & 3] - '0'; - } - - Tag *t = new Tag (root, root->getAttrib ("Orientation")); - t->initInt (orientation, SHORT); - root->addTagFront (t); - } - } - - // --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation - - bool frameRootDetected = false; - - if(!frameRootDetected) { - std::vector risTagList = root->findTags("RawImageSegmentation"); - if (!risTagList.empty()) { - for (auto ris : risTagList) { - frames.push_back(ris->getParent()); - frameRootDetected = true; - - #if PRINT_METADATA_TREE - printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); - ris->getParent()->printAll (); - #endif - } - } - } - - if(!frameRootDetected) { - std::vector sftTagList = root->findTags(TIFFTAG_SUBFILETYPE); - if (!sftTagList.empty()) { - for (auto sft : sftTagList) { - int sftVal = sft->toInt(); - if (sftVal == 0 || (!isRaw && sftVal == 2)) { - frames.push_back(sft->getParent()); - frameRootDetected = true; - -#if PRINT_METADATA_TREE - printf("\n--------------- FRAME (SUBFILETYPE) ---------------\n\n"); - sft->getParent()->printAll (); -#endif - } - } - } - } - - if(!frameRootDetected) { - std::vector sftTagList = root->findTags(TIFFTAG_OSUBFILETYPE); - if (!sftTagList.empty()) { - for (auto sft : sftTagList) { - int sftVal = sft->toInt(); - if (sftVal == OFILETYPE_IMAGE) { - frames.push_back(sft->getParent()); - frameRootDetected = true; - -#if PRINT_METADATA_TREE - printf("\n--------------- FRAME (OSUBFILETYPE) ---------------\n\n"); - sft->getParent()->printAll (); -#endif - } - } - } - } - - if(!frameRootDetected) { - std::vector piTagList = root->findTags("PhotometricInterpretation"); - if (!piTagList.empty()) { - for (auto pi : piTagList) { - int piVal = pi->toInt(); - if (piVal == (isRaw ? 32803 : 2)) { - frames.push_back(pi->getParent()); - //frameRootDetected = true; not used afterward - -#if PRINT_METADATA_TREE - printf("\n--------------- FRAME (PHOTOMETRIC) ---------------\n\n"); - pi->getParent()->printAll (); -#endif - } - } - } - } - - // --- getting next sibling root - - ifdOffset = get4 (f, order); - - roots.push_back(root); - -#if PRINT_METADATA_TREE - printf("\n~~~~~~~~~ ROOT ~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); - root->printAll (); -#endif - - } while (ifdOffset > 0 && !onlyFirst); - - // Security check : if there's at least one root, there must be at least one image. - // If the following occurs, then image detection above has failed or it's an unsupported file type. - // Yet the result of this should be valid. - if (!roots.empty() && frames.empty()) { - frames.push_back(roots.at(0)); - } -} - -void ExifManager::parseJPEG (int offset) -{ - if (!f) { - #ifndef NDEBUG - std::cerr << "ERROR : no file opened !" << std::endl; - #endif - return; - } - - if(!fseek (f, offset, SEEK_SET)) { - unsigned char c; - if(fread (&c, 1, 1, f) == 1) { - constexpr unsigned char markerl = 0xff; - const char exifid[] = "Exif\0\0"; - char idbuff[8]; - int tiffbase = -1; - - while (fread (&c, 1, 1, f)) { - if (c != markerl) { - continue; - } - - if (fread (&c, 1, 1, f) && c == 0xe1) { // APP1 marker found - if (fread (idbuff, 1, 8, f) < 8) { - return; - } - - if (!memcmp (idbuff + 2, exifid, 6)) { // Exif info found - tiffbase = ftell (f); - - // We need a RawMetaDataLocation to put the 'tiffbase' value - const bool rmlCreated = !rml; - if (rmlCreated) { - rml.reset(new rtengine::RawMetaDataLocation(0)); - } - rml->exifBase = tiffbase; - parse (false); - if (rmlCreated) { - rml.reset(); - } - return; - } - } - } - } - } -} - -void ExifManager::parseTIFF (bool skipIgnored) -{ - if (!rml) { - rml.reset(new rtengine::RawMetaDataLocation(0)); - parse(false, skipIgnored); - rml.reset(); - } else { - parse (false,skipIgnored); - } -} - -std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) -{ - - std::vector defTags; - - defTags.reserve (12); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "ImageWidth"), 0, LONG)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "ImageHeight"), 0, LONG)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "XResolution"), 300, RATIONAL)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "YResolution"), 300, RATIONAL)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "ResolutionUnit"), 2, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "Software"), "RawTherapee " RTVERSION)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "Orientation"), 1, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "SamplesPerPixel"), 3, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "BitsPerSample"), 8, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "PlanarConfiguration"), 1, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "PhotometricInterpretation"), 2, SHORT)); - defTags.push_back (new Tag (forthis, lookupAttrib (ifdAttribs, "Compression"), 1, SHORT)); - - return defTags; -} - - - -int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer) -{ - - // write tiff header - int offs = 6; - memcpy (buffer, "Exif\0\0", 6); - ByteOrder order = INTEL; - - if (root) { - order = root->getOrder (); - } - - sset2 ((unsigned short)order, buffer + offs, order); - offs += 2; - sset2 (42, buffer + offs, order); - offs += 2; - sset4 (8, buffer + offs, order); - - TagDirectory* cl; - - if (root) { - cl = (const_cast (root))->clone (nullptr); - } else { - cl = new TagDirectory (nullptr, ifdAttribs, INTEL); - } - - for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); ++i) { - cl->applyChange (i->first, i->second); - } - - const std::vector defTags = getDefaultTIFFTags (cl); - - defTags[0]->setInt (W, 0, LONG); - defTags[1]->setInt (H, 0, LONG); - defTags[8]->setInt (8, 0, SHORT); - - for (int i = defTags.size() - 1; i >= 0; i--) { - Tag* defTag = defTags[i]; - cl->replaceTag (defTag->clone (cl)); - delete defTag; - } - - cl->sort (); - int size = cl->write (8, buffer + 6); - - delete cl; - - return size + 6; -} - -int ExifManager::createPNGMarker(const TagDirectory* root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize) -{ -// write tiff header - int offs = 0; - ByteOrder order = HOSTORDER; - - if (root) { - order = root->getOrder (); - } - - TagDirectory* cl; - - if (root) { - cl = (const_cast (root))->clone (nullptr); - // remove some unknown top level tags which produce warnings when opening a tiff - Tag *removeTag = cl->getTag (0x9003); - - if (removeTag) { - removeTag->setKeep (false); - } - - removeTag = cl->getTag (0x9211); - - if (removeTag) { - removeTag->setKeep (false); - } - } else { - cl = new TagDirectory (nullptr, ifdAttribs, HOSTORDER); - } - - if (iptcdata) { - Tag* iptc = new Tag (cl, lookupAttrib (ifdAttribs, "IPTCData")); - iptc->initLongArray (iptcdata, iptclen); - cl->replaceTag (iptc); - } - -// apply list of changes - for (rtengine::procparams::ExifPairs::const_iterator i = changeList.begin(); i != changeList.end(); ++i) { - cl->applyChange (i->first, i->second); - } - - // append default properties - const std::vector defTags = getDefaultTIFFTags (cl); - - defTags[0]->setInt (W, 0, LONG); - defTags[1]->setInt (H, 0, LONG); - defTags[8]->initInt (0, SHORT, 3); - - for (int i = 0; i < 3; i++) { - defTags[8]->setInt (bps, i * 2, SHORT); - } - - for (int i = defTags.size() - 1; i >= 0; i--) { - Tag* defTag = defTags[i]; - cl->replaceTag (defTag->clone (cl)); - delete defTag; - } - - cl->sort (); - bufferSize = cl->calculateSize() + 8; - buffer = new unsigned char[bufferSize]; // this has to be deleted in caller - sset2 ((unsigned short)order, buffer + offs, order); - offs += 2; - sset2 (42, buffer + offs, order); - offs += 2; - sset4 (8, buffer + offs, order); - - int endOffs = cl->write (8, buffer); - -// cl->printAll(); - delete cl; - - return endOffs; -} - - -//----------------------------------------------------------------------------- -// global functions to read byteorder dependent data -//----------------------------------------------------------------------------- -unsigned short sget2 (unsigned char *s, rtexif::ByteOrder order) -{ - - if (order == rtexif::INTEL) { - return s[0] | s[1] << 8; - } else { - return s[0] << 8 | s[1]; - } -} - -int sget4 (unsigned char *s, rtexif::ByteOrder order) -{ - - if (order == rtexif::INTEL) { - return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; - } else { - return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; - } -} - -inline unsigned short get2 (FILE* f, rtexif::ByteOrder order) -{ - - unsigned char str[2] = { 0xff, 0xff }; - fread (str, 1, 2, f); - return rtexif::sget2 (str, order); -} - -int get4 (FILE* f, rtexif::ByteOrder order) -{ - - unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; - fread (str, 1, 4, f); - return rtexif::sget4 (str, order); -} - -void sset2 (unsigned short v, unsigned char *s, rtexif::ByteOrder order) -{ - - if (order == rtexif::INTEL) { - s[0] = v & 0xff; - v >>= 8; - s[1] = v; - } else { - s[1] = v & 0xff; - v >>= 8; - s[0] = v; - } -} - -void sset4 (int v, unsigned char *s, rtexif::ByteOrder order) -{ - - if (order == rtexif::INTEL) { - s[0] = v & 0xff; - v >>= 8; - s[1] = v & 0xff; - v >>= 8; - s[2] = v & 0xff; - v >>= 8; - s[3] = v; - } else { - s[3] = v & 0xff; - v >>= 8; - s[2] = v & 0xff; - v >>= 8; - s[1] = v & 0xff; - v >>= 8; - s[0] = v; - } -} - -float int_to_float (int i) -{ - union { - int i; - float f; - } u; - u.i = i; - return u.f; -} - -short int int2_to_signed (short unsigned int i) -{ - union { - short unsigned int i; - short int s; - } u; - u.i = i; - return u.s; -} - -/* Function to parse and extract focal length and aperture information from description - * @fullname must conform to the following formats - * mm f/ - * -mm f/ - * -mm f/- - * NB: no space between separator '-'; no space between focal length and 'mm' - */ -bool extractLensInfo (const std::string &fullname, double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal) -{ - minFocal = 0.0; - maxFocal = 0.0; - maxApertureAtMinFocal = 0.0; - maxApertureAtMaxFocal = 0.0; - char buffer[1025]; - strncpy (buffer, fullname.c_str(), 1024); - char *pF = strstr (buffer, "f/" ); - - if ( pF ) { - sscanf (pF + 2, "%lf-%lf", &maxApertureAtMinFocal, &maxApertureAtMaxFocal); - - if (maxApertureAtMinFocal > 0. && maxApertureAtMaxFocal == 0.) { - maxApertureAtMaxFocal = maxApertureAtMinFocal; - } - - char *pMM = pF - 3; - - while ( pMM[0] != 'm' && pMM[1] != 'm' && pMM > buffer) { - pMM--; - } - - if ( pMM[0] == 'm' && pMM[1] == 'm' ) { - char *sp = pMM; - - while ( *sp != ' ' && sp > buffer ) { - sp--; - } - - sscanf (sp + 1, "%lf-%lf", &minFocal, &maxFocal); - - if (maxFocal == 0.) { - maxFocal = minFocal; - } - - return true; - } - } - - return false; -} - -} diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h deleted file mode 100644 index 43b296746..000000000 --- a/rtexif/rtexif.h +++ /dev/null @@ -1,690 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _MEXIF3_ -#define _MEXIF3_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../rtengine/noncopyable.h" -#include "../rtengine/rawmetadatalocation.h" - -namespace rtengine -{ - -namespace procparams -{ - class ExifPairs; -} - -} - -class CacheImageData; - -namespace rtexif -{ - -enum TagType {INVALID = 0, BYTE = 1, ASCII = 2, SHORT = 3, LONG = 4, RATIONAL = 5, SBYTE = 6, UNDEFINED = 7, SSHORT = 8, SLONG = 9, SRATIONAL = 10, FLOAT = 11, DOUBLE = 12, OLYUNDEF = 13, AUTO = 98, SUBDIR = 99}; -enum ActionCode { - AC_DONTWRITE, // don't write it to the output - AC_WRITE, // write it to the output - AC_SYSTEM, // changed by RT (not editable/deletable) - don't write, don't show - AC_NEW, // new addition - write, don't show - - AC_INVALID = 100, // invalid state -}; -enum ByteOrder {UNKNOWN = 0, INTEL = 0x4949, MOTOROLA = 0x4D4D}; -#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -const ByteOrder HOSTORDER = INTEL; -#else -const enum ByteOrder HOSTORDER = MOTOROLA; -#endif -enum MNKind {NOMK, IFD, HEADERIFD, NIKON3, OLYMPUS2, FUJI, TABLESUBDIR}; - -bool extractLensInfo (const std::string &fullname, double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal); - -unsigned short sget2 (unsigned char *s, ByteOrder order); -int sget4 (unsigned char *s, ByteOrder order); -unsigned short get2 (FILE* f, ByteOrder order); -int get4 (FILE* f, ByteOrder order); -void sset2 (unsigned short v, unsigned char *s, ByteOrder order); -void sset4 (int v, unsigned char *s, ByteOrder order); -float int_to_float (int i); -short int int2_to_signed (short unsigned int i); - -struct TIFFHeader { - - unsigned short byteOrder; - unsigned short fixed; - unsigned int ifdOffset; -}; - -class Tag; -class Interpreter; - -/// Structure of information describing an Exif tag -struct TagAttrib { - int ignore; // =0: never ignore, =1: always ignore, =2: ignore if the subdir type is reduced image, =-1: end of table - ActionCode action; - int editable; - const TagAttrib* subdirAttribs; // !NULL if this tag points to a subdir - /** Numeric identifier of tag (or index inside DirectoryTable) - To avoid rewriting all the tables, and to address the problem of TagDirectoryTable with heterogeneous tag's type, - this parameter is now an unsigned int, where the leftmost 2 bytes represent the tag's type, which by default will be aqual - to 0 (INVALID). Only non null tag type will be used. See nikon attrib for an example - */ - unsigned short ID; - TagType type; - const char* name; - Interpreter* interpreter; // Call back hook -}; - -const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field); - -/// A directory of tags -class TagDirectory -{ - -protected: - std::vector tags; // tags in the directory - const TagAttrib* attribs; // descriptor table to decode the tags - ByteOrder order; // byte order - TagDirectory* parent; // parent directory (NULL if root) - static Glib::ustring getDumpKey (int tagID, const Glib::ustring &tagName); - -public: - TagDirectory (); - TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored = true); - TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border); - virtual ~TagDirectory (); - - inline ByteOrder getOrder () const - { - return order; - } - TagDirectory* getParent () - { - return parent; - } - TagDirectory* getRoot (); - inline int getCount () const - { - return tags.size (); - } - const TagAttrib* getAttrib (int id); - // Find a Tag by scanning the whole tag tree and stopping at the first occurrence - const TagAttrib* getAttrib (const char* name); - // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") - const TagAttrib* getAttribP (const char* name); - const TagAttrib* getAttribTable() - { - return attribs; - } - // Find a Tag by scanning the whole tag tree and stopping at the first occurrence - Tag* getTag (const char* name) const; - // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") - Tag* getTagP (const char* name) const; - Tag* getTag (int ID) const; - - // Try to get the Tag in the current directory and in subdirectories - // if lookUpward = true, it will scan the parents TagDirectory up to the root one, - // but w/o looking into their subdirs - virtual Tag* findTag (const char* name, bool lookUpward = false) const; - // Find a all Tags with the given name by scanning the whole tag tree - std::vector findTags (const char* name); - // Find a all Tags with the given ID by scanning the whole tag tree - std::vector findTags (int ID); - // Try to get the Tag in the current directory and in parent directories - // (won't look into subdirs) - virtual Tag* findTagUpward (const char* name) const; - bool getXMPTagValue (const char* name, char* value) const; - - void keepTag (int ID); - void addTag (Tag* &a); - void addTagFront (Tag* &a); - void replaceTag (Tag* a); - inline Tag* getTagByIndex (int ix) - { - return tags[ix]; - } - inline void setOrder (ByteOrder bo) - { - order = bo; - } - - virtual int calculateSize (); - virtual int write (int start, unsigned char* buffer); - virtual TagDirectory* clone (TagDirectory* parent); - void applyChange (const std::string &field, const Glib::ustring &value); - - virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call ! - virtual bool CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, - const CacheImageData* cfs, const bool flagMode, Glib::KeyFile *keyFile = nullptr, Glib::ustring tagDirName = "") const; - virtual void sort (); -}; - -// a table of tags: id are offset from beginning and not identifiers -class TagDirectoryTable: public TagDirectory -{ -protected: - unsigned char *values; // Tags values are saved internally here - long zeroOffset; // Offset 0 (index 0) could be at an offset from values - long valuesSize; // Size of allocated memory - TagType defaultType; // Default type of all tags in this directory -public: - TagDirectoryTable(); - TagDirectoryTable (TagDirectory* p, unsigned char *v, int memsize, int offs, TagType type, const TagAttrib* ta, ByteOrder border); - TagDirectoryTable (TagDirectory* p, FILE* f, int memsize, int offset, TagType type, const TagAttrib* ta, ByteOrder border); - ~TagDirectoryTable() override; - int calculateSize () override; - int write (int start, unsigned char* buffer) override; - TagDirectory* clone (TagDirectory* parent) override; -}; - -// a class representing a single tag -class Tag : - public rtengine::NonCopyable -{ - -protected: - unsigned short tag; - TagType type; - unsigned int count; - unsigned char* value; - int valuesize; - bool keep; - bool allocOwnMemory; - - const TagAttrib* attrib; - TagDirectory* parent; - TagDirectory** directory; - MNKind makerNoteKind; - bool parseMakerNote (FILE* f, int base, ByteOrder bom ); - -public: - Tag (TagDirectory* parent, FILE* f, int base); // parse next tag from the file - Tag (TagDirectory* parent, const TagAttrib* attr); - Tag (TagDirectory* parent, const TagAttrib* attr, unsigned char *data, TagType t); - Tag (TagDirectory* parent, const TagAttrib* attr, int data, TagType t); // create a new tag from array (used - Tag (TagDirectory* parent, const TagAttrib* attr, const char* data); // create a new tag from array (used - - ~Tag (); - void initType (unsigned char *data, TagType type); - void initInt (int data, TagType t, int count = 1); - void initUserComment (const Glib::ustring &text); - void initString (const char* text); - void initSubDir (); - void initSubDir (TagDirectory* dir); - void initMakerNote (MNKind mnk, const TagAttrib* ta); - void initUndefArray (const char* data, int len); - void initLongArray (const char* data, int len); - void initRational (int num, int den); - - static void swapByteOrder2 (unsigned char *buffer, int count); - - // get basic tag properties - int getID () const - { - return tag; - } - int getCount () const - { - return count; - } - TagType getType () const - { - return (attrib && attrib->type > INVALID && attrib->type < AUTO) ? attrib->type : type; - } - unsigned char* getValue () const - { - return value; - } - signed char* getSignedValue () const - { - return reinterpret_cast (value); - } - const TagAttrib* getAttrib () const - { - return attrib; - } - inline ByteOrder getOrder () const - { - return parent ? parent->getOrder() : HOSTORDER; - } - inline TagDirectory* getParent () const - { - return parent; - } - int getValueSize () const - { - return valuesize; - } - bool getOwnMemory () const - { - return allocOwnMemory; - } - - // read/write value - int toInt (int ofs = 0, TagType astype = INVALID) const; - void fromInt (int v); - double toDouble (int ofs = 0) const; - double* toDoubleArray (int ofs = 0) const; - void toRational (int& num, int& denom, int ofs = 0) const; - void toString (char* buffer, int ofs = 0) const; - void fromString (const char* v, int size = -1); - void setInt (int v, int ofs = 0, TagType astype = LONG); - int getDistanceFrom (const TagDirectory *root); - - // additional getter/setter for more comfortable use - std::string valueToString () const; - std::string nameToString (int i = 0); - void valueFromString (const std::string& value); - void userCommentFromString (const Glib::ustring& text); - - // functions for writing - int calculateSize (); - int write (int offs, int dataOffs, unsigned char* buffer); - Tag* clone (TagDirectory* parent); - - // to control if the tag shall be written - bool getKeep () - { - return keep; - } - void setKeep (bool k) - { - keep = k; - } - - // get subdirectory (there can be several, the last is NULL) - bool isDirectory () - { - return directory != nullptr; - } - TagDirectory* getDirectory (int i = 0) - { - return (directory) ? directory[i] : nullptr; - } - - MNKind getMakerNoteFormat () - { - return makerNoteKind; - } -}; - -class ExifManager -{ - - Tag* saveCIFFMNTag (TagDirectory* root, int len, const char* name); - void parseCIFF (int length, TagDirectory* root); - void parse (bool isRaw, bool skipIgnored = true); - -public: - FILE* f; - std::unique_ptr rml; - ByteOrder order; - bool onlyFirst; // Only first IFD - unsigned int IFDOffset; - std::vector roots; - std::vector frames; - - ExifManager (FILE* fHandle, std::unique_ptr _rml, bool onlyFirstIFD) - : f(fHandle), rml(std::move(_rml)), order(UNKNOWN), onlyFirst(onlyFirstIFD), - IFDOffset(0) {} - - void setIFDOffset(unsigned int offset); - - - void parseRaw (bool skipIgnored = true); - void parseStd (bool skipIgnored = true); - void parseJPEG (int offset = 0); // offset: to extract exif data from a embedded preview/thumbnail - void parseTIFF (bool skipIgnored = true); - void parseCIFF (); - - /// @brief Get default tag for TIFF - /// @param forthis The byte order will be taken from the given directory. - /// @return The ownership of the return tags is passed to the caller. - static std::vector getDefaultTIFFTags (TagDirectory* forthis); - static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer); - static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); - static int createPNGMarker(const TagDirectory *root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char *iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); -}; - -class Interpreter -{ -public: - Interpreter () {} - virtual ~Interpreter() {}; - virtual std::string toString (const Tag* t) const - { - char buffer[1024]; - t->toString (buffer); - std::string s (buffer); - std::string::size_type p1 = s.find_first_not_of (' '); - - if ( p1 == std::string::npos ) { - return s; - } else { - return s.substr (p1, s.find_last_not_of (' ') - p1 + 1); - } - } - virtual void fromString (Tag* t, const std::string& value) - { - if (t->getType() == SHORT || t->getType() == LONG) { - t->fromInt (atoi (value.c_str())); - } else { - t->fromString (value.c_str()); - } - } - // Get the value as a double - virtual double toDouble (const Tag* t, int ofs = 0) - { - double ud, dd; - - switch (t->getType()) { - case SBYTE: - return double (int (t->getSignedValue()[ofs])); - - case BYTE: - return (double) ((int)t->getValue()[ofs]); - - case ASCII: - return 0.0; - - case SSHORT: - return (double)int2_to_signed (sget2 (t->getValue() + ofs, t->getOrder())); - - case SHORT: - return (double) ((int)sget2 (t->getValue() + ofs, t->getOrder())); - - case SLONG: - case LONG: - return (double) ((int)sget4 (t->getValue() + ofs, t->getOrder())); - - case SRATIONAL: - case RATIONAL: - ud = (int)sget4 (t->getValue() + ofs, t->getOrder()); - dd = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); - return dd == 0. ? 0. : (double)ud / (double)dd; - - case FLOAT: - return double (sget4 (t->getValue() + ofs, t->getOrder())); - - case UNDEFINED: - return 0.; - - default: - return 0.; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) - } - } - // Get the value as an int - virtual int toInt (const Tag* t, int ofs = 0, TagType astype = INVALID) - { - int a; - - if (astype == INVALID || astype == AUTO) { - astype = t->getType(); - } - - switch (astype) { - case SBYTE: - return int (t->getSignedValue()[ofs]); - - case BYTE: - return t->getValue()[ofs]; - - case ASCII: - return 0; - - case SSHORT: - return (int)int2_to_signed (sget2 (t->getValue() + ofs, t->getOrder())); - - case SHORT: - return (int)sget2 (t->getValue() + ofs, t->getOrder()); - - case SLONG: - case LONG: - return (int)sget4 (t->getValue() + ofs, t->getOrder()); - - case SRATIONAL: - case RATIONAL: - a = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); - return a == 0 ? 0 : (int)sget4 (t->getValue() + ofs, t->getOrder()) / a; - - case FLOAT: - return (int)toDouble (t, ofs); - - case UNDEFINED: - return 0; - - default: - return 0; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) - } - - return 0; - } -}; - -extern Interpreter stdInterpreter; - -template -class ChoiceInterpreter : public Interpreter -{ -protected: - using Choices = std::map; - using ChoicesIterator = typename Choices::const_iterator; - Choices choices; -public: - ChoiceInterpreter () {}; - std::string toString (const Tag* t) const override - { - const typename std::map::const_iterator r = choices.find(t->toInt()); - - if (r != choices.end()) { - return r->second; - } else { - char buffer[1024]; - t->toString(buffer); - return buffer; - } - } -}; - -template< class T > -class IntLensInterpreter : public Interpreter -{ -protected: - typedef std::multimap< T, std::string> container_t; - typedef typename std::multimap< T, std::string>::const_iterator it_t; - typedef std::pair< T, std::string> p_t; - container_t choices; - - virtual std::string guess (const T lensID, double focalLength, double maxApertureAtFocal, double *lensInfoArray) const - { - it_t r; - size_t nFound = choices.count ( lensID ); - - switch ( nFound ) { - case 0: { // lens Unknown - std::ostringstream s; - s << lensID; - return s.str(); - } - - case 1: // lens found - r = choices.find ( lensID ); - return r->second; - - default: - // More than one hit: we must guess - break; - } - - std::string bestMatch ("Unknown"); - double a1, a2, f1, f2; - - /* FIRST TRY - * - * Get the lens info (min/man focal, min/max aperture) and compare them to the possible choice - */ - if (lensInfoArray) { - for ( r = choices.lower_bound ( lensID ); r != choices.upper_bound (lensID); ++r ) { - if ( !extractLensInfo ( r->second, f1, f2, a1, a2) ) { - continue; - } - - if (f1 == lensInfoArray[0] && f2 == lensInfoArray[1] && a1 == lensInfoArray[2] && a2 == lensInfoArray[3]) - // can't match better! we take this entry as being the one - { - return r->second; - } - } - - // No lens found, we update the "unknown" string with the lens info values - if (lensInfoArray[0] == lensInfoArray[1]) { - bestMatch += Glib::ustring::compose (" (%1mm", int (lensInfoArray[0])); - } else { - bestMatch += Glib::ustring::compose (" (%1-%2mm", int (lensInfoArray[0]), int (lensInfoArray[1])); - } - - if (lensInfoArray[2] == lensInfoArray[3]) { - bestMatch += Glib::ustring::compose (" f/%1)", Glib::ustring::format (std::fixed, std::setprecision (1), lensInfoArray[2])); - } else - bestMatch += Glib::ustring::compose (" f/%1-%2)", - Glib::ustring::format (std::fixed, std::setprecision (1), lensInfoArray[2]), - Glib::ustring::format (std::fixed, std::setprecision (1), lensInfoArray[3])); - } - - /* SECOND TRY - * - * Choose the best match: thanks to exiftool by Phil Harvey - * first throws for "out of focal range" and lower or upper aperture of the lens compared to MaxApertureAtFocal - * if the lens is not constant aperture, calculate aprox. aperture of the lens at focalLength - * and compare with actual aperture. - */ - std::ostringstream candidates; - double deltaMin = 1000.; - - for ( r = choices.lower_bound ( lensID ); r != choices.upper_bound (lensID); ++r ) { - double dif; - - if ( !extractLensInfo ( r->second, f1, f2, a1, a2) ) { - continue; - } - - if ( f1 == 0. || a1 == 0.) { - continue; - } - - if ( focalLength < f1 - .5 || focalLength > f2 + 0.5 ) { - continue; - } - - if ( maxApertureAtFocal > 0.1) { - double lensAperture; - - if ( maxApertureAtFocal < a1 - 0.15 || maxApertureAtFocal > a2 + 0.15) { - continue; - } - - if ( a1 == a2 || f1 == f2) { - lensAperture = a1; - } else { - lensAperture = exp ( log (a1) + (log (a2) - log (a1)) / (log (f2) - log (f1)) * (log (focalLength) - log (f1)) ); - } - - dif = std::abs (lensAperture - maxApertureAtFocal); - } else { - dif = 0; - } - - if ( dif < deltaMin ) { - deltaMin = dif; - bestMatch = r->second; - } - - if ( dif < 0.15) { - if ( candidates.tellp() ) { - candidates << "\n or " << r->second; - } else { - candidates << r->second; - } - } - } - - if ( !candidates.tellp() ) { - return bestMatch; - } else { - return candidates.str(); - } - } -}; - -inline static int getTypeSize ( TagType type ) -{ - return ("11124811248484"[type < 14 ? type : 0] - '0'); -} - -extern const TagAttrib exifAttribs[]; -extern const TagAttrib gpsAttribs[]; -extern const TagAttrib iopAttribs[]; -extern const TagAttrib ifdAttribs[]; -extern const TagAttrib nikon2Attribs[]; -extern const TagAttrib nikon3Attribs[]; -extern const TagAttrib canonAttribs[]; -extern const TagAttrib pentaxAttribs[]; -extern const TagAttrib pentaxLensDataAttribs[]; -extern const TagAttrib pentaxLensInfoQAttribs[]; -extern const TagAttrib pentaxLensCorrAttribs[]; -extern const TagAttrib pentaxAEInfoAttribs[]; -extern const TagAttrib pentaxAEInfo2Attribs[]; -extern const TagAttrib pentaxAEInfo3Attribs[]; -extern const TagAttrib pentaxCameraSettingsAttribs[]; -extern const TagAttrib pentaxFlashInfoAttribs[]; -extern const TagAttrib pentaxSRInfoAttribs[]; -extern const TagAttrib pentaxSRInfo2Attribs[]; -extern const TagAttrib pentaxBatteryInfoAttribs[]; -extern const TagAttrib pentaxCameraInfoAttribs[]; -extern const TagAttrib fujiAttribs[]; -extern const TagAttrib minoltaAttribs[]; -extern const TagAttrib sonyAttribs[]; -extern const TagAttrib sonyTag9405Attribs[]; -extern const TagAttrib sonyCameraInfoAttribs[]; -extern const TagAttrib sonyCameraInfo2Attribs[]; -extern const TagAttrib sonyCameraSettingsAttribs[]; -extern const TagAttrib sonyCameraSettingsAttribs2[]; -extern const TagAttrib sonyCameraSettingsAttribs3[]; -//extern const TagAttrib sonyDNGMakerNote[]; -extern const TagAttrib olympusAttribs[]; -extern const TagAttrib kodakIfdAttribs[]; -void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif); -extern const TagAttrib panasonicAttribs[]; -extern const TagAttrib panasonicRawAttribs[]; -} -#endif diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc deleted file mode 100644 index 0c6e433ff..000000000 --- a/rtexif/sonyminoltaattribs.cc +++ /dev/null @@ -1,2640 +0,0 @@ -/* - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _SONYMINOLTAATTRIBS_ -#define _SONYMINOLTAATTRIBS_ - -#include - -#include "rtexif.h" - -namespace rtexif -{ - -class SANoYesInterpreter : public ChoiceInterpreter<> -{ -public: - SANoYesInterpreter () - { - choices[1] = "No"; - choices[16] = "Yes"; - } -}; -SANoYesInterpreter saNoYesInterpreter; - -class SAOnOffInterpreter : public ChoiceInterpreter<> -{ -public: - SAOnOffInterpreter () - { - choices[0] = "Off"; - choices[1] = "On"; - choices[5] = "On"; - } -}; -SAOnOffInterpreter saOnOffInterpreter; - -class SAOnOffInterpreter2 : public ChoiceInterpreter<> -{ -public: - SAOnOffInterpreter2 () - { - choices[1] = "Off"; - choices[16] = "On"; - } -}; -SAOnOffInterpreter2 saOnOffInterpreter2; - -class SAOnOffInterpreter3 : public ChoiceInterpreter<> -{ -public: - SAOnOffInterpreter3 () - { - choices[1] = "Off"; - choices[16] = "On (Auto)"; - choices[17] = "On (Manual)"; - } -}; -SAOnOffInterpreter3 saOnOffInterpreter3; - -class SAOnOffInterpreter4 : public ChoiceInterpreter<> -{ -public: - SAOnOffInterpreter4 () - { - choices[0] = "n/a"; - choices[1] = "Off"; - choices[16] = "On"; - choices[255] = "None"; - } -}; -SAOnOffInterpreter4 saOnOffInterpreter4; - -class SAOnOffInterpreter5 : public ChoiceInterpreter<> -{ -public: - SAOnOffInterpreter5 () - { - choices[1] = "On"; - choices[2] = "Off"; - } -}; -SAOnOffInterpreter5 saOnOffInterpreter5; - -class SAHighISONoiseReduction : public ChoiceInterpreter<> -{ -public: - SAHighISONoiseReduction () - { - choices[0] = "Off"; - choices[1] = "Low"; - choices[2] = "Normal"; - choices[3] = "High"; - choices[256] = "Auto"; - choices[65535] = "n/a"; - } -}; -SAHighISONoiseReduction saHighISONoiseReduction; - -class SAHighISONoiseReduction2 : public ChoiceInterpreter<> -{ -public: - SAHighISONoiseReduction2 () - { - choices[0] = "Normal"; - choices[1] = "High"; - choices[2] = "Low"; - choices[3] = "Off"; - choices[65535] = "n/a"; - } -}; -SAHighISONoiseReduction2 saHighISONoiseReduction2; - -class SAHighISONoiseReduction3 : public ChoiceInterpreter<> -{ -public: - SAHighISONoiseReduction3 () - { - choices[0] = "Normal"; - choices[1] = "Low"; - choices[2] = "High"; - choices[3] = "Off"; - } -}; -SAHighISONoiseReduction3 saHighISONoiseReduction3; - -class SAHighISONoiseReduction4 : public ChoiceInterpreter<> -{ -public: - SAHighISONoiseReduction4 () - { - choices[0] = "Off"; - choices[1] = "Low"; - choices[2] = "Normal"; - choices[3] = "High"; - } -}; -SAHighISONoiseReduction4 saHighISONoiseReduction4; - -class SAHighISONoiseReduction5 : public ChoiceInterpreter<> -{ -public: - SAHighISONoiseReduction5 () - { - choices[16] = "Low"; - choices[19] = "Auto"; - } -}; -SAHighISONoiseReduction5 saHighISONoiseReduction5; - -class SASmileShutterMode : public ChoiceInterpreter<> -{ -public: - SASmileShutterMode () - { - choices[17] = "Slight smile"; - choices[18] = "Normal smile"; - choices[19] = "Big smile"; - } -}; -SASmileShutterMode saSmileShutterMode; - -class SAHDRLevel : public ChoiceInterpreter<> -{ -public: - SAHDRLevel () - { - choices[33] = "1 EV"; - choices[34] = "1.5 EV"; - choices[35] = "2 EV"; - choices[36] = "2.5 EV"; - choices[37] = "3 EV"; - choices[38] = "3.5 EV"; - choices[39] = "4 EV"; - choices[40] = "5 EV"; - choices[41] = "6 EV"; - } -}; -SAHDRLevel saHDRLevel; - -class SAViewingMode : public ChoiceInterpreter<> -{ -public: - SAViewingMode () - { - choices[0] = "n/a"; - choices[16] = "ViewFinder"; - choices[33] = "Focus Check Live View"; - choices[34] = "Quick AF Live View"; - } -}; -SAViewingMode saViewingMode; - -class SAFlashAction : public ChoiceInterpreter<> -{ -public: - SAFlashAction () - { - choices[1] = "Did not fire"; - choices[2] = "Fired"; - } -}; -SAFlashAction saFlashAction; - -class SALiveViewFocusMode : public ChoiceInterpreter<> -{ -public: - SALiveViewFocusMode () - { - choices[0] = "n/a"; - choices[1] = "AF"; - choices[16] = "Manual"; - } -}; -SALiveViewFocusMode saLiveViewFocusMode; - -class SALensMount : public ChoiceInterpreter<> -{ -public: - SALensMount () - { - choices[1] = "Unknown"; - choices[16] = "A-Mount"; - choices[17] = "E-Mount"; - } -}; -SALensMount saLensMount; - -class SASweepPanoramaSize : public ChoiceInterpreter<> -{ -public: - SASweepPanoramaSize () - { - choices[1] = "Standard"; - choices[2] = "Wide"; - } -}; -SASweepPanoramaSize saSweepPanoramaSize; - -class SASweepPanoramaDirection : public ChoiceInterpreter<> -{ -public: - SASweepPanoramaDirection () - { - choices[1] = "Right"; - choices[2] = "Left"; - choices[3] = "Up"; - choices[4] = "Down"; - } -}; -SASweepPanoramaDirection saSweepPanoramaDirection; - -class SALiveViewAFSetting : public ChoiceInterpreter<> -{ -public: - SALiveViewAFSetting () - { - choices[0] = "n/a"; - choices[1] = "Phase-detect AF"; - choices[2] = "Contrast AF"; - } -}; -SALiveViewAFSetting saLiveViewAFSetting; - -class SAPanoramaSize3D : public ChoiceInterpreter<> -{ -public: - SAPanoramaSize3D () - { - choices[0] = "n/a"; - choices[1] = "Standard"; - choices[2] = "Wide"; - choices[3] = "16:9"; - } -}; -SAPanoramaSize3D saPanoramaSize3D; - -class SALiveViewMetering : public ChoiceInterpreter<> -{ -public: - SALiveViewMetering () - { - choices[0] = "n/a"; - choices[16] = "40 segment"; - choices[32] = "1200-zone Evaluative"; - } -}; -SALiveViewMetering saLiveViewMetering; - -class SAWhiteBalanceInterpreter: public ChoiceInterpreter<> -{ -public: - SAWhiteBalanceInterpreter() - { - choices[ 0x0] = "Auto"; - choices[ 0x1] = "Color Temperature/Color Filter"; - choices[0x10] = "Daylight"; - choices[0x20] = "Cloudy"; - choices[0x30] = "Shade"; - choices[0x40] = "Tungsten"; - choices[0x50] = "Flash"; - choices[0x60] = "Fluorescent"; - choices[0x70] = "Custom"; - choices[0x80] = "Underwater"; - } -}; -SAWhiteBalanceInterpreter saWhiteBalanceInterpreter; - -class SAWhiteBalanceSettingInterpreter: public ChoiceInterpreter<> -{ -public: - SAWhiteBalanceSettingInterpreter() - { - choices[0x10] = "Auto (-3)"; - choices[0x11] = "Auto (-2)"; - choices[0x12] = "Auto (-1)"; - choices[0x13] = "Auto (0)"; - choices[0x14] = "Auto (+1)"; - choices[0x15] = "Auto (+2)"; - choices[0x16] = "Auto (+3)"; - choices[0x20] = "Daylight (-3)"; - choices[0x21] = "Daylight (-2)"; - choices[0x22] = "Daylight (-1)"; - choices[0x23] = "Daylight (0)"; - choices[0x24] = "Daylight (+1)"; - choices[0x25] = "Daylight (+2)"; - choices[0x26] = "Daylight (+3)"; - choices[0x30] = "Shade (-3)"; - choices[0x31] = "Shade (-2)"; - choices[0x32] = "Shade (-1)"; - choices[0x33] = "Shade (0)"; - choices[0x34] = "Shade (+1)"; - choices[0x35] = "Shade (+2)"; - choices[0x36] = "Shade (+3)"; - choices[0x40] = "Cloudy (-3)"; - choices[0x41] = "Cloudy (-2)"; - choices[0x42] = "Cloudy (-1)"; - choices[0x43] = "Cloudy (0)"; - choices[0x44] = "Cloudy (+1)"; - choices[0x45] = "Cloudy (+2)"; - choices[0x46] = "Cloudy (+3)"; - choices[0x50] = "Tungsten (-3)"; - choices[0x51] = "Tungsten (-2)"; - choices[0x52] = "Tungsten (-1)"; - choices[0x53] = "Tungsten (0)"; - choices[0x54] = "Tungsten (+1)"; - choices[0x55] = "Tungsten (+2)"; - choices[0x56] = "Tungsten (+3)"; - choices[0x60] = "Fluorescent (-3)"; - choices[0x61] = "Fluorescent (-2)"; - choices[0x62] = "Fluorescent (-1)"; - choices[0x63] = "Fluorescent (0)"; - choices[0x64] = "Fluorescent (+1)"; - choices[0x65] = "Fluorescent (+2)"; - choices[0x66] = "Fluorescent (+3)"; - choices[0x70] = "Flash (-3)"; - choices[0x71] = "Flash (-2)"; - choices[0x72] = "Flash (-1)"; - choices[0x73] = "Flash (0)"; - choices[0x74] = "Flash (+1)"; - choices[0x75] = "Flash (+2)"; - choices[0x76] = "Flash (+3)"; - choices[0xa3] = "Custom"; - choices[0xf3] = "Color Temperature/Color Filter"; - } -}; -SAWhiteBalanceSettingInterpreter saWhiteBalanceSettingInterpreter; - -class SASceneModeInterpreter : public ChoiceInterpreter<> -{ -public: - SASceneModeInterpreter () - { - choices[0] = "Standard"; - choices[1] = "Portrait"; - choices[2] = "Text"; - choices[3] = "Night Scene"; - choices[4] = "Sunset"; - choices[5] = "Sports"; - choices[6] = "Landscape"; - choices[7] = "Night Portrait"; - choices[8] = "Macro"; - choices[9] = "Super Macro"; - choices[16] = "Auto"; - choices[17] = "Night View/Portrait"; - choices[18] = "Sweep Panorama"; - choices[19] = "Handheld Night Shot"; - choices[20] = "Anti Motion Blur"; - choices[21] = "Cont. Priority AE"; - choices[22] = "Auto+"; - choices[23] = "3D Sweep Panorama"; - choices[24] = "Superior Auto"; - choices[25] = "High Sensitivity"; - choices[26] = "Fireworks"; - choices[27] = "Food"; - choices[28] = "Pet"; - choices[33] = "HDR"; - choices[65535] = "n/a"; - } -}; -SASceneModeInterpreter saSceneModeInterpreter; - -class SAZoneMatchingInterpreter : public ChoiceInterpreter<> -{ -public: - SAZoneMatchingInterpreter () - { - choices[0] = "ISO Setting Used"; - choices[1] = "High Key"; - choices[2] = "Low Key"; - } -}; -SAZoneMatchingInterpreter saZoneMatchingInterpreter; - -class SADynamicRangeOptimizerInterpreter : public ChoiceInterpreter<> -{ -public: - SADynamicRangeOptimizerInterpreter () - { - choices[0] = "Off"; - choices[1] = "Standard"; - choices[2] = "Advanced"; - choices[3] = "Auto"; - choices[8] = "Advanced Lv1"; - choices[9] = "Advanced Lv2"; - choices[10] = "Advanced Lv3"; - choices[11] = "Advanced Lv4"; - choices[12] = "Advanced Lv5"; - choices[16] = "Lv1"; - choices[17] = "Lv2"; - choices[18] = "Lv3"; - choices[19] = "Lv4"; - choices[20] = "Lv5"; - } -}; -SADynamicRangeOptimizerInterpreter saDynamicRangeOptimizerInterpreter; - -class SAColorModeInterpreter : public ChoiceInterpreter<> -{ -public: - SAColorModeInterpreter () - { - choices[0] = "Standard"; - choices[1] = "Vivid"; - choices[2] = "Portrait"; - choices[3] = "Landscape"; - choices[4] = "Sunset"; - choices[5] = "Night View/Portrait"; - choices[6] = "B&W"; - choices[7] = "Adobe RGB"; - choices[12] = "Neutral"; - choices[13] = "Clear"; - choices[14] = "Deep"; - choices[15] = "Light"; - choices[16] = "Autumn Leaves"; - choices[17] = "Sepia"; - choices[100] = "Neutral"; - choices[101] = "Clear"; - choices[102] = "Deep"; - choices[103] = "Light"; - choices[104] = "Night View"; - choices[105] = "Autumn Leaves"; - } -}; -SAColorModeInterpreter saColorModeInterpreter; - -class SAExposureModeInterpreter : public ChoiceInterpreter<> -{ -public: - SAExposureModeInterpreter () - { - choices[0] = "Program AE"; - choices[1] = "Portrait"; - choices[2] = "Beach"; - choices[3] = "Sports"; - choices[4] = "Snow"; - choices[5] = "Landscape"; - choices[6] = "Auto"; - choices[7] = "Aperture-priority AE"; - choices[8] = "Shutter speed priority AE"; - choices[9] = "Night Scene / Twilight"; - choices[10] = "Hi-Speed Shutter"; - choices[11] = "Twilight Portrait"; - choices[12] = "Soft Snap/Portrait"; - choices[13] = "Fireworks"; - choices[14] = "Smile Shutter"; - choices[15] = "Manual"; - choices[18] = "High Sensitivity"; - choices[19] = "Macro"; - choices[20] = "Advanced Sports Shooting"; - choices[29] = "Underwater"; - choices[33] = "Food"; - choices[34] = "Sweep Panorama"; - choices[35] = "Handheld Night Shot"; - choices[36] = "Anti Motion Blur"; - choices[37] = "Pet"; - choices[38] = "Backlight Correction HDR"; - choices[39] = "Superior Auto"; - choices[40] = "Background Defocus"; - choices[41] = "Soft Skin"; - choices[42] = "3D Image"; - choices[65535] = "n/a"; - } -}; -SAExposureModeInterpreter saExposureModeInterpreter; - -class SAQualityInterpreter : public ChoiceInterpreter<> -{ -public: - SAQualityInterpreter () - { - choices[0] = "Normal"; - choices[1] = "Fine"; - } -}; -SAQualityInterpreter saQualityInterpreter; - -class SAAntiBlurInterpreter : public ChoiceInterpreter<> -{ -public: - SAAntiBlurInterpreter () - { - choices[0] = "Off"; - choices[1] = "On (Continuous)"; - choices[2] = "On (Shooting)"; - choices[65535] = "n/a"; - } -}; -SAAntiBlurInterpreter saAntiBlurInterpreter; - -class SALensIDInterpreter : public IntLensInterpreter -{ -public: - SALensIDInterpreter () - { - choices = { - {0, "Minolta AF 28-85mm f/3.5-4.5 New"}, - {1, "Minolta AF 80-200mm f/2.8 HS-APO G"}, - {2, "Minolta AF 28-70mm f/2.8 G"}, - {3, "Minolta AF 28-80mm f/4-5.6"}, - {4, "Minolta AF 85mm f/1.4G"}, - {5, "Minolta AF 35-70mm f/3.5-4.5 [II]"}, - {6, "Minolta AF 24-85mm f/3.5-4.5 [New]"}, - {7, "Minolta AF 100-300mm f/4.5-5.6 APO [New] or 100-400mm or Sigma Lens"}, - {7, "Minolta AF 100-400mm f/4.5-6.7 APO"}, - {7, "Sigma AF 100-300mm f/4 EX DG IF"}, - {8, "Minolta AF 70-210mm f/4.5-5.6 [II]"}, - {9, "Minolta AF 50mm f/3.5 Macro"}, - {10, "Minolta AF 28-105mm f/3.5-4.5 [New]"}, - {11, "Minolta AF 300mm f/4 HS-APO G"}, - {12, "Minolta AF 100mm f/2.8 Soft Focus"}, - {13, "Minolta AF 75-300mm f/4.5-5.6 (New or II)"}, - {14, "Minolta AF 100-400mm f/4.5-6.7 APO"}, - {15, "Minolta AF 400mm f/4.5 HS-APO G"}, - {16, "Minolta AF 17-35mm f/3.5 G"}, - {17, "Minolta AF 20-35mm f/3.5-4.5"}, - {18, "Minolta AF 28-80mm f/3.5-5.6 II"}, - {19, "Minolta AF 35mm f/1.4 G"}, - {20, "Minolta/Sony 135mm f/2.8 [T4.5] STF"}, - {22, "Minolta AF 35-80mm f/4-5.6 II"}, - {23, "Minolta AF 200mm f/4 Macro APO G"}, - {24, "Minolta/Sony AF 24-105mm f/3.5-4.5 (D) or Sigma or Tamron Lens"}, - {24, "Sigma 18-50mm f/2.8"}, - {24, "Sigma 17-70mm f/2.8-4.5 (D)"}, - {24, "Sigma 20-40mm f/2.8 EX DG Aspherical IF"}, - {24, "Sigma 18-200mm f/3.5-6.3 DC"}, - {24, "Sigma DC 18-125mm f/4-5,6 D"}, - {24, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro"}, - {25, "Minolta AF 100-300mm f/4.5-5.6 APO (D) or Sigma Lens"}, - {25, "Sigma 100-300mm f/4 EX (APO (D) or D IF)"}, - {25, "Sigma 70mm f/2.8 EX DG Macro"}, - {25, "Sigma 20mm f/1.8 EX DG Aspherical RF"}, - {25, "Sigma 30mm f/1.4 EX DC"}, - {25, "Sigma 24mm f/1.8 EX DG ASP Macro"}, - {27, "Minolta AF 85mm f/1.4 G (D)"}, - {28, "Minolta/Sony AF 100mm f/2.8 Macro (D) or Tamron Lens"}, - {28, "Tamron SP AF 90mm f/2.8 Di Macro"}, - {28, "Tamron SP AF 180mm f/3.5 Di LD [IF] Macro"}, - {29, "Minolta/Sony AF 75-300mm f/4.5-5.6 (D)"}, - {30, "Minolta AF 28-80mm f/3.5-5.6 (D) or Sigma Lens"}, - {30, "Sigma AF 10-20mm f/4-5.6 EX DC"}, - {30, "Sigma AF 12-24mm f/4.5-5.6 EX DG"}, - {30, "Sigma 28-70mm EX DG f/2.8"}, - {30, "Sigma 55-200mm f/4-5.6 DC"}, - {31, "Minolta/Sony AF 50mm f/2.8 Macro (D) or f/3.5"}, - {31, "Minolta/Sony AF 50mm f/3.5 Macro"}, - {32, "Minolta/Sony AF 300mm f/2.8 G or 1.5x Teleconverter"}, - {33, "Minolta/Sony AF 70-200mm f/2.8 G"}, - {35, "Minolta AF 85mm f/1.4 G (D) Limited"}, - {36, "Minolta AF 28-100mm f/3.5-5.6 (D)"}, - {38, "Minolta AF 17-35mm f/2.8-4 (D)"}, - {39, "Minolta AF 28-75mm f/2.8 (D)"}, - {40, "Minolta/Sony AF DT 18-70mm f/3.5-5.6 (D)"}, - {41, "Minolta/Sony AF DT 11-18mm f/4.5-5.6 (D) or Tamron Lens"}, - {41, "Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical IF"}, - {42, "Minolta/Sony AF DT 18-200mm f/3.5-6.3 (D)"}, - {43, "Sony 35mm f/1.4 G (SAL35F14G)"}, - {44, "Sony 50mm f/1.4 (SAL50F14)"}, - {45, "Carl Zeiss Planar T* 85mm f/1.4 ZA (SAL85F14Z)"}, - {46, "Carl Zeiss Vario-Sonnar T* DT 16-80mm f/3.5-4.5 ZA (SAL1680Z)"}, - {47, "Carl Zeiss Sonnar T* 135mm f/1.8 ZA (SAL135F18Z)"}, - {48, "Carl Zeiss Vario-Sonnar T* 24-70mm f/2.8 ZA SSM (SAL2470Z) or ZA SSM II"}, - {48, "Carl Zeiss Vario-Sonnar T* 24-70mm f/2.8 ZA SSM II (SAL2470Z2)"}, - {49, "Sony DT 55-200mm f/4-5.6 (SAL55200)"}, - {50, "Sony DT 18-250mm f/3.5-6.3 (SAL18250)"}, - {51, "Sony DT 16-105mm f/3.5-5.6 (SAL16105)"}, - {52, "Sony 70-300mm f/4.5-5.6 G SSM (SAL70300G) or G SSM II or Tamron Lens"}, - {52, "Sony 70-300mm f/4.5-5.6 G SSM II (SAL70300G2)"}, - {52, "Tamron SP 70-300mm f/4-5.6 Di USD"}, - {53, "Sony 70-400mm f/4-5.6 G SSM (SAL70400G)"}, - {54, "Carl Zeiss Vario-Sonnar T* 16-35mm f/2.8 ZA SSM (SAL1635Z) or ZA SSM II"}, - {54, "Carl Zeiss Vario-Sonnar T* 16-35mm f/2.8 ZA SSM II (SAL1635Z2)"}, - {55, "Sony DT 18-55mm f/3.5-5.6 SAM (SAL1855) or SAM II"}, - {55, "Sony DT 18-55mm f/3.5-5.6 SAM II (SAL18552)"}, - {56, "Sony DT 55-200mm f/4-5.6 SAM (SAL55200-2)"}, - {57, "Sony DT 50mm f/1.8 SAM (SAL50F18) or Tamron Lens or Commlite CM-EF-NEX adapter"}, - {57, "Tamron SP AF 60mm f/2 Di II LD [IF] Macro 1:1"}, - {57, "Tamron 18-270mm f/3.5-6.3 Di II PZD"}, - {58, "Sony DT 30mm f/2.8 Macro SAM (SAL30M28)"}, - {59, "Sony 28-75mm f/2.8 SAM (SAL2875)"}, - {60, "Carl Zeiss Distagon T* 24mm f/2 ZA SSM (SAL24F20Z)"}, - {61, "Sony 85mm f/2.8 SAM (SAL85F28)"}, - {62, "Sony DT 35mm f/1.8 SAM (SAL35F18)"}, - {63, "Sony DT 16-50mm f/2.8 SSM (SAL1650)"}, - {64, "Sony 500mm f/4 G SSM (SAL500F40G)"}, - {65, "Sony DT 18-135mm f/3.5-5.6 SAM (SAL18135)"}, - {66, "Sony 300mm f/2.8 G SSM II (SAL300F28G2)"}, - {67, "Sony 70-200mm f/2.8 G SSM II (SAL70200G2)"}, - {68, "Sony DT 55-300mm f/4.5-5.6 SAM (SAL55300)"}, - {69, "Sony 70-400mm f/4-5.6 G SSM II (SAL70400G2)"}, - {70, "Carl Zeiss Planar T* 50mm f/1.4 ZA SSM (SAL50F14Z)"}, - {128, "Tamron or Sigma Lens (128)"}, - {128, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro"}, - {128, "Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical [IF] Macro"}, - {128, "Tamron 80-300mm f/3.5-6.3"}, - {128, "Tamron AF 28-200mm f/3.8-5.6 XR Di Aspherical [IF] Macro"}, - {128, "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF"}, - {128, "Sigma AF 50-150mm f/2.8 EX DC APO HSM II"}, - {128, "Sigma 10-20mm f/3.5 EX DC HSM"}, - {128, "Sigma 70-200mm f/2.8 II EX DG APO MACRO HSM"}, - {128, "Sigma 10mm f/2.8 EX DC HSM Fisheye"}, - {128, "Sigma 50mm f/1.4 EX DG HSM"}, - {128, "Sigma 85mm f/1.4 EX DG HSM"}, - {128, "Sigma 24-70mm f/2.8 IF EX DG HSM"}, - {128, "Sigma 18-250mm f/3.5-6.3 DC OS HSM"}, - {128, "Sigma 17-50mm f/2.8 EX DC HSM"}, - {128, "Sigma 17-70mm f/2.8-4 DC Macro HSM"}, - {128, "Sigma 150mm f/2.8 EX DG OS HSM APO Macro"}, - {128, "Sigma 150-500mm f/5-6.3 APO DG OS HSM"}, - {128, "Tamron AF 28-105mm f/4-5.6 [IF]"}, - {128, "Sigma 35mm f/1.4 DG HSM"}, - {128, "Sigma 18-35mm f/1.8 DC HSM"}, - {128, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM"}, - {128, "Sigma 24-105mm f/4 DG HSM | A"}, - {128, "Sigma 30mm f/1.4"}, - {128, "Sigma 35mm f/1.4 DG HSM | A"}, - {128, "Sigma 105mm f/2.8 EX DG OS HSM Macro"}, - {128, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro"}, - {128, "Sigma 18-300mm f/3.5-6.3 DC Macro HSM | C"}, - {128, "Sigma 18-50mm f/2.8-4.5 DC HSM"}, - {129, "Tamron Lens (129)"}, - {129, "Tamron 200-400mm f/5.6 LD"}, - {129, "Tamron 70-300mm f/4-5.6 LD"}, - {131, "Tamron 20-40mm f/2.7-3.5 SP Aspherical IF"}, - {135, "Vivitar 28-210mm f/3.5-5.6"}, - {136, "Tokina EMZ M100 AF 100mm f/3.5"}, - {137, "Cosina 70-210mm f/2.8-4 AF"}, - {138, "Soligor 19-35mm f/3.5-4.5"}, - {139, "Tokina AF 28-300mm f/4-6.3"}, - {142, "Voigtlander 70-300mm f/4.5-5.6"}, - {146, "Voigtlander Macro APO-Lanthar 125mm f/2.5 SL"}, - {194, "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical [IF]"}, - {202, "Tamron SP AF 70-200mm f/2.8 Di LD [IF] Macro"}, - {203, "Tamron SP 70-200mm f/2.8 Di USD"}, - {204, "Tamron SP 24-70mm f/2.8 Di USD"}, - {212, "Tamron 28-300mm f/3.5-6.3 Di PZD"}, - {213, "Tamron 16-300mm f/3.5-6.3 Di II PZD Macro"}, - {214, "Tamron SP 150-600mm f/5-6.3 Di USD"}, - {215, "Tamron SP 15-30mm f/2.8 Di USD"}, - {216, "Tamron SP 45mm f/1.8 Di USD"}, - {217, "Tamron SP 35mm f/1.8 Di USD"}, - {218, "Tamron SP 90mm f/2.8 Di Macro 1:1 USD (F017)"}, - {220, "Tamron SP 150-600mm f/5-6.3 Di USD G2"}, - {224, "Tamron SP 90mm f/2.8 Di Macro 1:1 USD (F004)"}, - {255, "Tamron Lens (255)"}, - {255, "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical"}, - {255, "Tamron AF 18-250mm f/3.5-6.3 XR Di II LD"}, - {255, "Tamron AF 55-200mm f/4-5.6 Di II LD Macro"}, - {255, "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2"}, - {255, "Tamron SP AF 200-500mm f/5.0-6.3 Di LD IF"}, - {255, "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical IF"}, - {255, "Tamron SP AF 70-200mm f/2.8 Di LD IF Macro"}, - {255, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical IF"}, - {255, "Tamron AF 90-300mm f/4.5-5.6 Telemacro"}, - {1868, "Sigma MC-11 SA-E Mount Converter with not-supported Sigma lens"}, - {2550, "Minolta AF 50mm f/1.7"}, - {2551, "Minolta AF 35-70mm f/4 or Other Lens"}, - {2551, "Sigma UC AF 28-70mm f/3.5-4.5"}, - {2551, "Sigma AF 28-70mm f/2.8"}, - {2551, "Sigma M-AF 70-200mm f/2.8 EX Aspherical"}, - {2551, "Quantaray M-AF 35-80mm f/4-5.6"}, - {2551, "Tokina 28-70mm f/2.8-4.5 AF"}, - {2552, "Minolta AF 28-85mm f/3.5-4.5 or Other Lens"}, - {2552, "Tokina 19-35mm f/3.5-4.5"}, - {2552, "Tokina 28-70mm f/2.8 AT-X"}, - {2552, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840"}, - {2552, "Tokina AF PRO 28-80mm f/2.8 AT-X 280"}, - {2552, "Tokina AT-X PRO [II] AF 28-70mm f/2.6-2.8 270"}, - {2552, "Tamron AF 19-35mm f/3.5-4.5"}, - {2552, "Angenieux AF 28-70mm f/2.6"}, - {2552, "Tokina AT-X 17 AF 17mm f/3.5"}, - {2552, "Tokina 20-35mm f/3.5-4.5 II AF"}, - {2553, "Minolta AF 28-135mm f/4-4.5 or Sigma Lens"}, - {2553, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5"}, - {2553, "Sigma 28-105mm f/2.8-4 Aspherical"}, - {2553, "Sigma 28-105mm f/4-5.6 UC"}, - {2554, "Minolta AF 35-105mm f/3.5-4.5"}, - {2555, "Minolta AF 70-210mm f/4 Macro or Sigma Lens"}, - {2555, "Sigma 70-210mm f/4-5.6 APO"}, - {2555, "Sigma M-AF 70-200mm f/2.8 EX APO"}, - {2555, "Sigma 75-200mm f/2.8-3.5"}, - {2556, "Minolta AF 135mm f/2.8"}, - {2557, "Minolta/Sony AF 28mm f/2.8"}, - {2558, "Minolta AF 24-50mm f/4"}, - {2560, "Minolta AF 100-200mm f/4.5"}, - {2561, "Minolta AF 75-300mm f/4.5-5.6 or Sigma Lens"}, - {2561, "Sigma 70-300mm f/4-5.6 DL Macro"}, - {2561, "Sigma 300mm f/4 APO Macro"}, - {2561, "Sigma AF 500mm f/4.5 APO"}, - {2561, "Sigma AF 170-500mm f/5-6.3 APO Aspherical"}, - {2561, "Tokina AT-X AF 300mm f/4"}, - {2561, "Tokina AT-X AF 400mm f/5.6 SD"}, - {2561, "Tokina AF 730 II 75-300mm f/4.5-5.6"}, - {2561, "Sigma 800mm f/5.6 APO"}, - {2561, "Sigma AF 400mm f/5.6 APO Macro"}, - {2561, "Sigma 1000mm f/8 APO"}, - {2562, "Minolta AF 50mm f/1.4 [New]"}, - {2563, "Minolta AF 300mm f/2.8 APO or Sigma Lens"}, - {2563, "Sigma AF 50-500mm f/4-6.3 EX DG APO"}, - {2563, "Sigma AF 170-500mm f/5-6.3 APO Aspherical"}, - {2563, "Sigma AF 500mm f/4.5 EX DG APO"}, - {2563, "Sigma 400mm f/5.6 APO"}, - {2564, "Minolta AF 50mm f/2.8 Macro or Sigma Lens"}, - {2564, "Sigma 50mm f/2.8 EX Macro"}, - {2565, "Minolta AF 600mm f/4 APO"}, - {2566, "Minolta AF 24mm f/2.8 or Sigma Lens"}, - {2566, "Sigma 17-35mm f/2.8-4 EX Aspherical"}, - {2572, "Minolta/Sony AF 500mm f/8 Reflex"}, - {2578, "Minolta/Sony AF 16mm f/2.8 Fisheye or Sigma Lens"}, - {2578, "Sigma 8mm f/4 EX [DG] Fisheye"}, - {2578, "Sigma 14mm f/3.5"}, - {2578, "Sigma 15mm f/2.8 Fisheye"}, - {2579, "Minolta/Sony AF 20mm f/2.8 or Tokina Lens"}, - {2579, "Tokina AT-X Pro DX 11-16mm f/2.8"}, - {2581, "Minolta AF 100mm f/2.8 Macro [New] or Sigma or Tamron Lens"}, - {2581, "Sigma AF 90mm f/2.8 Macro"}, - {2581, "Sigma AF 105mm f/2.8 EX [DG] Macro"}, - {2581, "Sigma 180mm f/5.6 Macro"}, - {2581, "Sigma 180mm f/3.5 EX DG Macro"}, - {2581, "Tamron 90mm f/2.8 Macro"}, - {2585, "Minolta AF 35-105mm f/3.5-4.5 New or Tamron Lens"}, - {2585, "Beroflex 35-135mm f/3.5-4.5"}, - {2585, "Tamron 24-135mm f/3.5-5.6"}, - {2588, "Minolta AF 70-210mm f/3.5-4.5"}, - {2589, "Minolta AF 80-200mm f/2.8 APO or Tokina Lens"}, - {2589, "Tokina 80-200mm f/2.8"}, - {2590, "Minolta AF 200mm f/2.8 G APO + Minolta AF 1.4x APO or Other Lens + 1.4x"}, - {2590, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 1.4x APO"}, - {2591, "Minolta AF 35mm f/1.4"}, - {2592, "Minolta AF 85mm f/1.4 G (D)"}, - {2593, "Minolta AF 200mm f/2.8 APO"}, - {2594, "Minolta AF 3x-1x f/1.7-2.8 Macro"}, - {2596, "Minolta AF 28mm f/2"}, - {2597, "Minolta AF 35mm f/2 [New]"}, - {2598, "Minolta AF 100mm f/2"}, - {2601, "Minolta AF 200mm f/2.8 G APO + Minolta AF 2x APO or Other Lens + 2x"}, - {2601, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 2x APO"}, - {2604, "Minolta AF 80-200mm f/4.5-5.6"}, - {2605, "Minolta AF 35-80mm f/4-5.6"}, - {2606, "Minolta AF 100-300mm f/4.5-5.6"}, - {2607, "Minolta AF 35-80mm f/4-5.6"}, - {2608, "Minolta AF 300mm f/2.8 HS-APO G"}, - {2609, "Minolta AF 600mm f/4 HS-APO G"}, - {2612, "Minolta AF 200mm f/2.8 HS-APO G"}, - {2613, "Minolta AF 50mm f/1.7 New"}, - {2615, "Minolta AF 28-105mm f/3.5-4.5 xi"}, - {2616, "Minolta AF 35-200mm f/4.5-5.6 xi"}, - {2618, "Minolta AF 28-80mm f/4-5.6 xi"}, - {2619, "Minolta AF 80-200mm f/4.5-5.6 xi"}, - {2620, "Minolta AF 28-70mm f/2.8 G"}, - {2621, "Minolta AF 100-300mm f/4.5-5.6 xi"}, - {2624, "Minolta AF 35-80mm f/4-5.6 Power Zoom"}, - {2628, "Minolta AF 80-200mm f/2.8 HS-APO G"}, - {2629, "Minolta AF 85mm f/1.4 New"}, - {2631, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO"}, - {2632, "Minolta AF 24-50mm f/4 New"}, - {2638, "Minolta AF 50mm f/2.8 Macro New"}, - {2639, "Minolta AF 100mm f/2.8 Macro"}, - {2641, "Minolta/Sony AF 20mm f/2.8 New"}, - {2642, "Minolta AF 24mm f/2.8 New"}, - {2644, "Minolta AF 100-400mm f/4.5-6.7 APO"}, - {2662, "Minolta AF 50mm f/1.4 New"}, - {2667, "Minolta AF 35mm f/2 New"}, - {2668, "Minolta AF 28mm f/2 New"}, - {2672, "Minolta AF 24-105mm f/3.5-4.5 (D)"}, - {3046, "Metabones Canon EF Speed Booster"}, - {4567, "Tokina 70-210mm f/4-5.6"}, - {4570, "Tamron AF 35-135mm f/3.5-4.5"}, - {4571, "Vivitar 70-210mm f/4.5-5.6"}, - {4574, "2x Teleconverter or Tamron or Tokina Lens"}, - {4574, "Tamron SP AF 90mm f/2.5"}, - {4574, "Tokina RF 500mm f/8.0 x2"}, - {4574, "Tokina 300mm f/2.8 x2"}, - {4575, "1.4x Teleconverter"}, - {4585, "Tamron SP AF 300mm f/2.8 LD IF"}, - {4586, "Tamron SP AF 35-105mm f/2.8 LD Aspherical IF"}, - {4587, "Tamron AF 70-210mm f/2.8 SP LD"}, - {4812, "Metabones Canon EF Speed Booster Ultra"}, - {6118, "Canon EF Adapter"}, - {6528, "Sigma 16mm f/2.8 Filtermatic Fisheye"}, - {6553, "E-Mount, T-Mount, Other Lens or no lens"}, - {6553, "Sony E 16mm f/2.8"}, - {6553, "Sony E 18-55mm f/3.5-5.6 OSS"}, - {6553, "Sony E 55-210mm f/4.5-6.3 OSS"}, - {6553, "Sony E 18-200mm f/3.5-6.3 OSS"}, - {6553, "Sony E 30mm f/3.5 Macro"}, - {6553, "Sony E 24mm f/1.8 ZA"}, - {6553, "Sony E 50mm f/1.8 OSS"}, - {6553, "Sony E 16-70mm f/4 ZA OSS"}, - {6553, "Sony E 10-18mm f/4 OSS"}, - {6553, "Sony E PZ 16-50mm f/3.5-5.6 OSS"}, - {6553, "Sony FE 35mm f/2.8 ZA"}, - {6553, "Sony FE 24-70mm f/4 ZA OSS"}, - {6553, "Sony FE 85mm f/1.8"}, - {6553, "Sony E 18-200mm f/3.5-6.3 OSS LE"}, - {6553, "Sony E 20mm f/2.8"}, - {6553, "Sony E 35mm f/1.8 OSS"}, - {6553, "Sony E PZ 18-105mm f/4 G OSS"}, - {6553, "Sony FE 12-24mm f/4 G"}, - {6553, "Sony FE 90mm f/2.8 Macro G OSS"}, - {6553, "Sony E 18-50mm f/4-5.6"}, - {6553, "Sony FE 24mm f/1.4 GM"}, - {6553, "Sony FE 24-105mm f/4 G OSS"}, - {6553, "Sony E PZ 18-200mm f/3.5-6.3 OSS"}, - {6553, "Sony FE 55mm f/1.8 ZA"}, - {6553, "Sony FE 70-200mm f/4 G OSS"}, - {6553, "Sony FE 16-35mm f/4 ZA OSS"}, - {6553, "Sony FE 50mm f/2.8 Macro"}, - {6553, "Sony FE 28-70mm f/3.5-5.6 OSS"}, - {6553, "Sony FE 35mm f/1.4 ZA"}, - {6553, "Sony FE 24-240mm f/3.5-6.3 OSS"}, - {6553, "Sony FE 28mm f/2"}, - {6553, "Sony FE PZ 28-135mm f/4 G OSS"}, - {6553, "Sony FE 100mm f/2.8 STF GM OSS"}, - {6553, "Sony E PZ 18-110mm f/4 G OSS"}, - {6553, "Sony FE 24-70mm f/2.8 GM"}, - {6553, "Sony FE 50mm f/1.4 ZA"}, - {6553, "Sony FE 85mm f/1.4 GM"}, - {6553, "Sony FE 50mm f/1.8"}, - {6553, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)"}, - {6553, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)"}, - {6553, "Sony FE 70-300mm f/4.5-5.6 G OSS"}, - {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS"}, - {6553, "Sony FE 70-200mm f/2.8 GM OSS"}, - {6553, "Sony FE 16-35mm f/2.8 GM"}, - {6553, "Sony FE 400mm f/2.8 GM OSS"}, - {6553, "Sony E 18-135mm f/3.5-5.6 OSS"}, - {6553, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter"}, - {6553, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter"}, - {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter"}, - {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter"}, - {6553, "Sony FE 400mm f/2.8 GM OSS + 1.4X Teleconverter"}, - {6553, "Sony FE 400mm f/2.8 GM OSS + 2X Teleconverter"}, - {6553, "Samyang AF 50mm f/1.4 FE"}, - {6553, "Samyang AF 14mm f/2.8 FE"}, - {6553, "Samyang AF 24mm f/2.8"}, - {6553, "Samyang AF 35mm f/2.8 FE"}, - {6553, "Samyang AF 35mm f/1.4"}, - {6553, "Sigma 19mm f/2.8 [EX] DN"}, - {6553, "Sigma 30mm f/2.8 [EX] DN"}, - {6553, "Sigma 60mm f/2.8 DN"}, - {6553, "Sigma 30mm f/1.4 DC DN | C"}, - {6553, "Sigma 85mm f/1.4 DG HSM | A"}, - {6553, "Sigma 16mm f/1.4 DC DN | C"}, - {6553, "Sigma 105mm f/1.4 DG HSM | A"}, - {6553, "Sigma 56mm f/1.4 DC DN | C"}, - {6553, "Sigma 70-200mm f/2.8 DG OS HSM | S"}, - {6553, "Sigma 70mm f/2.8 DG MACRO | A"}, - {6553, "Tamron 18-200mm f/3.5-6.3 Di III VC"}, - {6553, "Tamron 28-75mm f/2.8 Di III RXD"}, - {6553, "Tokina Firin 20mm f/2 FE MF"}, - {6553, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III"}, - {6553, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6"}, - {6553, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III"}, - {6553, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical"}, - {6553, "Voigtlander NOKTON 40mm f/1.2 Aspherical"}, - {6553, "Voigtlander NOKTON classic 35mm f/1.4"}, - {6553, "Voigtlander MACRO APO-LANTHAR 110mm f/2.5"}, - {6553, "Voigtlander COLOR-SKOPAR 21mm f/3.5 Aspherical"}, - {6553, "Zeiss Touit 12mm f/2.8"}, - {6553, "Zeiss Touit 32mm f/1.8"}, - {6553, "Zeiss Touit 50mm f/2.8 Macro"}, - {6553, "Zeiss Batis 25mm f/2"}, - {6553, "Zeiss Batis 85mm f/1.8"}, - {6553, "Zeiss Batis 18mm f/2.8"}, - {6553, "Zeiss Batis 135mm f/2.8"}, - {6553, "Zeiss Batis 40mm f/2 CF"}, - {6553, "Zeiss Loxia 50mm f/2"}, - {6553, "Zeiss Loxia 35mm f/2"}, - {6553, "Zeiss Loxia 21mm f/2.8"}, - {6553, "Zeiss Loxia 85mm f/2.4"}, - {6553, "Zeiss Loxia 25mm f/2.4"}, - {6553, "Arax MC 35mm f/2.8 Tilt+Shift"}, - {6553, "Arax MC 80mm f/2.8 Tilt+Shift"}, - {6553, "Zenitar MF 16mm f/2.8 Fisheye M42"}, - {6553, "Samyang 500mm Mirror f/8.0"}, - {6553, "Pentacon Auto 135mm f/2.8"}, - {6553, "Pentacon Auto 29mm f/2.8"}, - {6553, "Helios 44-2 58mm f/2.0"}, - {18688, "Sigma MC-11 SA-E Mount Converter with not-supported Sigma lens"}, - {25501, "Minolta AF 50mm f/1.7"}, - {25511, "Minolta AF 35-70mm f/4 or Other Lens"}, - {25511, "Sigma UC AF 28-70mm f/3.5-4.5"}, - {25511, "Sigma AF 28-70mm f/2.8"}, - {25511, "Sigma M-AF 70-200mm f/2.8 EX Aspherical"}, - {25511, "Quantaray M-AF 35-80mm f/4-5.6"}, - {25511, "Tokina 28-70mm f/2.8-4.5 AF"}, - {25521, "Minolta AF 28-85mm f/3.5-4.5 or Other Lens"}, - {25521, "Tokina 19-35mm f/3.5-4.5"}, - {25521, "Tokina 28-70mm f/2.8 AT-X"}, - {25521, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840"}, - {25521, "Tokina AF PRO 28-80mm f/2.8 AT-X 280"}, - {25521, "Tokina AT-X PRO [II] AF 28-70mm f/2.6-2.8 270"}, - {25521, "Tamron AF 19-35mm f/3.5-4.5"}, - {25521, "Angenieux AF 28-70mm f/2.6"}, - {25521, "Tokina AT-X 17 AF 17mm f/3.5"}, - {25521, "Tokina 20-35mm f/3.5-4.5 II AF"}, - {25531, "Minolta AF 28-135mm f/4-4.5 or Sigma Lens"}, - {25531, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5"}, - {25531, "Sigma 28-105mm f/2.8-4 Aspherical"}, - {25531, "Sigma 28-105mm f/4-5.6 UC"}, - {25541, "Minolta AF 35-105mm f/3.5-4.5"}, - {25551, "Minolta AF 70-210mm f/4 Macro or Sigma Lens"}, - {25551, "Sigma 70-210mm f/4-5.6 APO"}, - {25551, "Sigma M-AF 70-200mm f/2.8 EX APO"}, - {25551, "Sigma 75-200mm f/2.8-3.5"}, - {25561, "Minolta AF 135mm f/2.8"}, - {25571, "Minolta/Sony AF 28mm f/2.8"}, - {25581, "Minolta AF 24-50mm f/4"}, - {25601, "Minolta AF 100-200mm f/4.5"}, - {25611, "Minolta AF 75-300mm f/4.5-5.6 or Sigma Lens"}, - {25611, "Sigma 70-300mm f/4-5.6 DL Macro"}, - {25611, "Sigma 300mm f/4 APO Macro"}, - {25611, "Sigma AF 500mm f/4.5 APO"}, - {25611, "Sigma AF 170-500mm f/5-6.3 APO Aspherical"}, - {25611, "Tokina AT-X AF 300mm f/4"}, - {25611, "Tokina AT-X AF 400mm f/5.6 SD"}, - {25611, "Tokina AF 730 II 75-300mm f/4.5-5.6"}, - {25611, "Sigma 800mm f/5.6 APO"}, - {25611, "Sigma AF 400mm f/5.6 APO Macro"}, - {25611, "Sigma 1000mm f/8 APO"}, - {25621, "Minolta AF 50mm f/1.4 [New]"}, - {25631, "Minolta AF 300mm f/2.8 APO or Sigma Lens"}, - {25631, "Sigma AF 50-500mm f/4-6.3 EX DG APO"}, - {25631, "Sigma AF 170-500mm f/5-6.3 APO Aspherical"}, - {25631, "Sigma AF 500mm f/4.5 EX DG APO"}, - {25631, "Sigma 400mm f/5.6 APO"}, - {25641, "Minolta AF 50mm f/2.8 Macro or Sigma Lens"}, - {25641, "Sigma 50mm f/2.8 EX Macro"}, - {25651, "Minolta AF 600mm f/4 APO"}, - {25661, "Minolta AF 24mm f/2.8 or Sigma Lens"}, - {25661, "Sigma 17-35mm f/2.8-4 EX Aspherical"}, - {25721, "Minolta/Sony AF 500mm f/8 Reflex"}, - {25781, "Minolta/Sony AF 16mm f/2.8 Fisheye or Sigma Lens"}, - {25781, "Sigma 8mm f/4 EX [DG] Fisheye"}, - {25781, "Sigma 14mm f/3.5"}, - {25781, "Sigma 15mm f/2.8 Fisheye"}, - {25791, "Minolta/Sony AF 20mm f/2.8 or Tokina Lens"}, - {25791, "Tokina AT-X Pro DX 11-16mm f/2.8"}, - {25811, "Minolta AF 100mm f/2.8 Macro [New] or Sigma or Tamron Lens"}, - {25811, "Sigma AF 90mm f/2.8 Macro"}, - {25811, "Sigma AF 105mm f/2.8 EX [DG] Macro"}, - {25811, "Sigma 180mm f/5.6 Macro"}, - {25811, "Sigma 180mm f/3.5 EX DG Macro"}, - {25811, "Tamron 90mm f/2.8 Macro"}, - {25851, "Beroflex 35-135mm f/3.5-4.5"}, - {25858, "Minolta AF 35-105mm f/3.5-4.5 New or Tamron Lens"}, - {25858, "Tamron 24-135mm f/3.5-5.6"}, - {25881, "Minolta AF 70-210mm f/3.5-4.5"}, - {25891, "Minolta AF 80-200mm f/2.8 APO or Tokina Lens"}, - {25891, "Tokina 80-200mm f/2.8"}, - {25901, "Minolta AF 200mm f/2.8 G APO + Minolta AF 1.4x APO or Other Lens + 1.4x"}, - {25901, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 1.4x APO"}, - {25911, "Minolta AF 35mm f/1.4"}, - {25921, "Minolta AF 85mm f/1.4 G (D)"}, - {25931, "Minolta AF 200mm f/2.8 APO"}, - {25941, "Minolta AF 3x-1x f/1.7-2.8 Macro"}, - {25961, "Minolta AF 28mm f/2"}, - {25971, "Minolta AF 35mm f/2 [New]"}, - {25981, "Minolta AF 100mm f/2"}, - {26011, "Minolta AF 200mm f/2.8 G APO + Minolta AF 2x APO or Other Lens + 2x"}, - {26011, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 2x APO"}, - {26041, "Minolta AF 80-200mm f/4.5-5.6"}, - {26051, "Minolta AF 35-80mm f/4-5.6"}, - {26061, "Minolta AF 100-300mm f/4.5-5.6"}, - {26071, "Minolta AF 35-80mm f/4-5.6"}, - {26081, "Minolta AF 300mm f/2.8 HS-APO G"}, - {26091, "Minolta AF 600mm f/4 HS-APO G"}, - {26121, "Minolta AF 200mm f/2.8 HS-APO G"}, - {26131, "Minolta AF 50mm f/1.7 New"}, - {26151, "Minolta AF 28-105mm f/3.5-4.5 xi"}, - {26161, "Minolta AF 35-200mm f/4.5-5.6 xi"}, - {26181, "Minolta AF 28-80mm f/4-5.6 xi"}, - {26191, "Minolta AF 80-200mm f/4.5-5.6 xi"}, - {26201, "Minolta AF 28-70mm f/2.8 G"}, - {26211, "Minolta AF 100-300mm f/4.5-5.6 xi"}, - {26241, "Minolta AF 35-80mm f/4-5.6 Power Zoom"}, - {26281, "Minolta AF 80-200mm f/2.8 HS-APO G"}, - {26291, "Minolta AF 85mm f/1.4 New"}, - {26311, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO"}, - {26321, "Minolta AF 24-50mm f/4 New"}, - {26381, "Minolta AF 50mm f/2.8 Macro New"}, - {26391, "Minolta AF 100mm f/2.8 Macro"}, - {26411, "Minolta/Sony AF 20mm f/2.8 New"}, - {26421, "Minolta AF 24mm f/2.8 New"}, - {26441, "Minolta AF 100-400mm f/4.5-6.7 APO"}, - {26621, "Minolta AF 50mm f/1.4 New"}, - {26671, "Minolta AF 35mm f/2 New"}, - {26681, "Minolta AF 28mm f/2 New"}, - {26721, "Minolta AF 24-105mm f/3.5-4.5 (D)"}, - {30464, "Metabones Canon EF Speed Booster"}, - {45671, "Tokina 70-210mm f/4-5.6"}, - {45701, "Tamron AF 35-135mm f/3.5-4.5"}, - {45711, "Vivitar 70-210mm f/4.5-5.6"}, - {45741, "2x Teleconverter or Tamron or Tokina Lens"}, - {45741, "Tamron SP AF 90mm f/2.5"}, - {45741, "Tokina RF 500mm f/8.0 x2"}, - {45741, "Tokina 300mm f/2.8 x2"}, - {45751, "1.4x Teleconverter"}, - {45851, "Tamron SP AF 300mm f/2.8 LD IF"}, - {45861, "Tamron SP AF 35-105mm f/2.8 LD Aspherical IF"}, - {45871, "Tamron AF 70-210mm f/2.8 SP LD"}, - {48128, "Metabones Canon EF Speed Booster Ultra"}, - {61184, "Canon EF Adapter"}, - {65280, "Sigma 16mm f/2.8 Filtermatic Fisheye"}, - {65535, "E-Mount, T-Mount, Other Lens or no lens"}, - {65535, "Sony E 16mm f/2.8"}, - {65535, "Sony E 18-55mm f/3.5-5.6 OSS"}, - {65535, "Sony E 55-210mm f/4.5-6.3 OSS"}, - {65535, "Sony E 18-200mm f/3.5-6.3 OSS"}, - {65535, "Sony E 30mm f/3.5 Macro"}, - {65535, "Sony E 24mm f/1.8 ZA"}, - {65535, "Sony E 50mm f/1.8 OSS"}, - {65535, "Sony E 16-70mm f/4 ZA OSS"}, - {65535, "Sony E 10-18mm f/4 OSS"}, - {65535, "Sony E PZ 16-50mm f/3.5-5.6 OSS"}, - {65535, "Sony FE 35mm f/2.8 ZA"}, - {65535, "Sony FE 24-70mm f/4 ZA OSS"}, - {65535, "Sony FE 85mm f/1.8"}, - {65535, "Sony E 18-200mm f/3.5-6.3 OSS LE"}, - {65535, "Sony E 20mm f/2.8"}, - {65535, "Sony E 35mm f/1.8 OSS"}, - {65535, "Sony E PZ 18-105mm f/4 G OSS"}, - {65535, "Sony FE 12-24mm f/4 G"}, - {65535, "Sony FE 90mm f/2.8 Macro G OSS"}, - {65535, "Sony E 18-50mm f/4-5.6"}, - {65535, "Sony FE 24mm f/1.4 GM"}, - {65535, "Sony FE 24-105mm f/4 G OSS"}, - {65535, "Sony E PZ 18-200mm f/3.5-6.3 OSS"}, - {65535, "Sony FE 55mm f/1.8 ZA"}, - {65535, "Sony FE 70-200mm f/4 G OSS"}, - {65535, "Sony FE 16-35mm f/4 ZA OSS"}, - {65535, "Sony FE 50mm f/2.8 Macro"}, - {65535, "Sony FE 28-70mm f/3.5-5.6 OSS"}, - {65535, "Sony FE 35mm f/1.4 ZA"}, - {65535, "Sony FE 24-240mm f/3.5-6.3 OSS"}, - {65535, "Sony FE 28mm f/2"}, - {65535, "Sony FE PZ 28-135mm f/4 G OSS"}, - {65535, "Sony FE 100mm f/2.8 STF GM OSS"}, - {65535, "Sony E PZ 18-110mm f/4 G OSS"}, - {65535, "Sony FE 24-70mm f/2.8 GM"}, - {65535, "Sony FE 50mm f/1.4 ZA"}, - {65535, "Sony FE 85mm f/1.4 GM"}, - {65535, "Sony FE 50mm f/1.8"}, - {65535, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)"}, - {65535, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)"}, - {65535, "Sony FE 70-300mm f/4.5-5.6 G OSS"}, - {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS"}, - {65535, "Sony FE 70-200mm f/2.8 GM OSS"}, - {65535, "Sony FE 16-35mm f/2.8 GM"}, - {65535, "Sony FE 400mm f/2.8 GM OSS"}, - {65535, "Sony E 18-135mm f/3.5-5.6 OSS"}, - {65535, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter"}, - {65535, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter"}, - {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter"}, - {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter"}, - {65535, "Sony FE 400mm f/2.8 GM OSS + 1.4X Teleconverter"}, - {65535, "Sony FE 400mm f/2.8 GM OSS + 2X Teleconverter"}, - {65535, "Samyang AF 50mm f/1.4 FE"}, - {65535, "Samyang AF 14mm f/2.8 FE"}, - {65535, "Samyang AF 24mm f/2.8"}, - {65535, "Samyang AF 35mm f/2.8 FE"}, - {65535, "Samyang AF 35mm f/1.4"}, - {65535, "Sigma 19mm f/2.8 [EX] DN"}, - {65535, "Sigma 30mm f/2.8 [EX] DN"}, - {65535, "Sigma 60mm f/2.8 DN"}, - {65535, "Sigma 30mm f/1.4 DC DN | C"}, - {65535, "Sigma 85mm f/1.4 DG HSM | A"}, - {65535, "Sigma 16mm f/1.4 DC DN | C"}, - {65535, "Sigma 105mm f/1.4 DG HSM | A"}, - {65535, "Sigma 56mm f/1.4 DC DN | C"}, - {65535, "Sigma 70-200mm f/2.8 DG OS HSM | S"}, - {65535, "Sigma 70mm f/2.8 DG MACRO | A"}, - {65535, "Tamron 18-200mm f/3.5-6.3 Di III VC"}, - {65535, "Tamron 28-75mm f/2.8 Di III RXD"}, - {65535, "Tokina Firin 20mm f/2 FE MF"}, - {65535, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III"}, - {65535, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6"}, - {65535, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III"}, - {65535, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical"}, - {65535, "Voigtlander NOKTON 40mm f/1.2 Aspherical"}, - {65535, "Voigtlander NOKTON classic 35mm f/1.4"}, - {65535, "Voigtlander MACRO APO-LANTHAR 110mm f/2.5"}, - {65535, "Voigtlander COLOR-SKOPAR 21mm f/3.5 Aspherical"}, - {65535, "Zeiss Touit 12mm f/2.8"}, - {65535, "Zeiss Touit 32mm f/1.8"}, - {65535, "Zeiss Touit 50mm f/2.8 Macro"}, - {65535, "Zeiss Batis 25mm f/2"}, - {65535, "Zeiss Batis 85mm f/1.8"}, - {65535, "Zeiss Batis 18mm f/2.8"}, - {65535, "Zeiss Batis 135mm f/2.8"}, - {65535, "Zeiss Batis 40mm f/2 CF"}, - {65535, "Zeiss Loxia 50mm f/2"}, - {65535, "Zeiss Loxia 35mm f/2"}, - {65535, "Zeiss Loxia 21mm f/2.8"}, - {65535, "Zeiss Loxia 85mm f/2.4"}, - {65535, "Zeiss Loxia 25mm f/2.4"}, - {65535, "Arax MC 35mm f/2.8 Tilt+Shift"}, - {65535, "Arax MC 80mm f/2.8 Tilt+Shift"}, - {65535, "Zenitar MF 16mm f/2.8 Fisheye M42"}, - {65535, "Samyang 500mm Mirror f/8.0"}, - {65535, "Pentacon Auto 135mm f/2.8"}, - {65535, "Pentacon Auto 29mm f/2.8"}, - {65535, "Helios 44-2 58mm f/2.0"}, - }; - } - - std::string toString (const Tag* t) const override - { - int lensID = t->toInt(); - Tag *lensInfoTag = t->getParent()->getRoot()->findTag ("LensInfo"); - Tag *apertureTag = t->getParent()->getRoot()->findTag ("MaxApertureValue"); - Tag *focalLengthTag = t->getParent()->getRoot()->findTag ("FocalLength"); - double maxApertureAtFocal = 0.; - double focalLength = 0.; - - if ( apertureTag ) { - maxApertureAtFocal = pow (2.0, apertureTag->toDouble() / 2.0); - } - - if ( focalLengthTag ) { - focalLength = focalLengthTag->toDouble(); - } - - double *liArray = nullptr; - - if (lensInfoTag) { - liArray = lensInfoTag->toDoubleArray(); - } - - std::string retval = guess ( lensID, focalLength, maxApertureAtFocal, liArray); - - if (liArray) { - delete [] liArray; - } - - return retval; - } -}; -SALensIDInterpreter saLensIDInterpreter; - -class SALensID2Interpreter : public IntLensInterpreter< int > -{ -public: - SALensID2Interpreter () - { - choices.insert (p_t (0, "Unknown E-mount lens or other lens")); - choices.insert (p_t (1, "Sony LA-EA1 or Sigma MC-11 Adapter")); - choices.insert (p_t (2, "Sony LA-EA2 Adapter")); - choices.insert (p_t (3, "Sony LA-EA3 Adapter")); - choices.insert (p_t (6, "Sony LA-EA4 Adapter")); - choices.insert (p_t (44, "Metabones Canon EF Smart Adapter")); - choices.insert (p_t (78, "Metabones Canon EF Smart Adapter Mark III or Other Adapter")); - choices.insert (p_t (234, "Metabones Canon EF Smart Adapter Mark IV")); - choices.insert (p_t (239, "Metabones Canon EF Speed Booster")); - choices.insert (p_t (32784, "Sony E 16mm f/2.8")); - choices.insert (p_t (32785, "Sony E 18-55mm f/3.5-5.6 OSS")); - choices.insert (p_t (32786, "Sony E 55-210mm f/4.5-6.3 OSS")); - choices.insert (p_t (32787, "Sony E 18-200mm f/3.5-6.3 OSS")); - choices.insert (p_t (32788, "Sony E 30mm f/3.5 Macro")); - choices.insert (p_t (32789, "Sony E 24mm f/1.8 ZA or Samyang AF 50mm f/1.4 FE")); - choices.insert (p_t (32789, "Samyang AF 50mm f/1.4 FE")); - choices.insert (p_t (32790, "Sony E 50mm f/1.8 OSS or Samyang AF 14mm f/2.8 FE")); - choices.insert (p_t (32790, "Samyang AF 14mm f/2.8 FE")); - choices.insert (p_t (32791, "Sony E 16-70mm f/4 ZA OSS")); - choices.insert (p_t (32792, "Sony E 10-18mm f/4 OSS")); - choices.insert (p_t (32793, "Sony E PZ 16-50mm f/3.5-5.6 OSS")); - choices.insert (p_t (32794, "Sony FE 35mm f/2.8 ZA or Samyang AF 24mm f/2.8 FE")); - choices.insert (p_t (32794, "Samyang AF 24mm f/2.8 FE")); - choices.insert (p_t (32795, "Sony FE 24-70mm f/4 ZA OSS")); - choices.insert (p_t (32796, "Sony FE 85mm f/1.8")); - choices.insert (p_t (32797, "Sony E 18-200mm f/3.5-6.3 OSS LE")); - choices.insert (p_t (32798, "Sony E 20mm f/2.8")); - choices.insert (p_t (32799, "Sony E 35mm f/1.8 OSS")); - choices.insert (p_t (32800, "Sony E PZ 18-105mm f/4 G OSS")); - choices.insert (p_t (32801, "Sony FE 12-24mm f/4 G")); - choices.insert (p_t (32802, "Sony FE 90mm f/2.8 Macro G OSS")); - choices.insert (p_t (32803, "Sony E 18-50mm f/4-5.6")); - choices.insert (p_t (32804, "Sony FE 24mm f/1.4 GM")); - choices.insert (p_t (32805, "Sony FE 24-105mm f/4 G OSS")); - choices.insert (p_t (32807, "Sony E PZ 18-200mm f/3.5-6.3 OSS")); - choices.insert (p_t (32808, "Sony FE 55mm f/1.8 ZA")); - choices.insert (p_t (32810, "Sony FE 70-200mm f/4 G OSS")); - choices.insert (p_t (32811, "Sony FE 16-35mm f/4 ZA OSS")); - choices.insert (p_t (32812, "Sony FE 50mm f/2.8 Macro")); - choices.insert (p_t (32813, "Sony FE 28-70mm f/3.5-5.6 OSS")); - choices.insert (p_t (32814, "Sony FE 35mm f/1.4 ZA")); - choices.insert (p_t (32815, "Sony FE 24-240mm f/3.5-6.3 OSS")); - choices.insert (p_t (32816, "Sony FE 28mm f/2")); - choices.insert (p_t (32817, "Sony FE PZ 28-135mm f/4 G OSS")); - choices.insert (p_t (32819, "Sony FE 100mm f/2.8 STF GM OSS")); - choices.insert (p_t (32820, "Sony E PZ 18-110mm f/4 G OSS")); - choices.insert (p_t (32821, "Sony FE 24-70mm f/2.8 GM")); - choices.insert (p_t (32822, "Sony FE 50mm f/1.4 ZA")); - choices.insert (p_t (32823, "Sony FE 85mm f/1.4 GM")); - choices.insert (p_t (32824, "Sony FE 50mm f/1.8")); - choices.insert (p_t (32826, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)")); - choices.insert (p_t (32827, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)")); - choices.insert (p_t (32828, "Sony FE 70-300mm f/4.5-5.6 G OSS")); - choices.insert (p_t (32829, "Sony FE 100-400mm f/4.5-5.6 GM OSS")); - choices.insert (p_t (32830, "Sony FE 70-200mm f/2.8 GM OSS")); - choices.insert (p_t (32831, "Sony FE 16-35mm f/2.8 GM")); - choices.insert (p_t (32848, "Sony FE 400mm f/2.8 GM OSS")); - choices.insert (p_t (32849, "Sony E 18-135mm f/3.5-5.6 OSS")); - choices.insert (p_t (33072, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter")); - choices.insert (p_t (33073, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter")); - choices.insert (p_t (33076, "Sony FE 100mm f/2.8 STF GM OSS (macro mode)")); - choices.insert (p_t (33077, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter")); - choices.insert (p_t (33078, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter")); - choices.insert (p_t (33079, "Sony FE 400mm f/2.8 GM OSS + 1.4X Teleconverter")); - choices.insert (p_t (33080, "Sony FE 400mm f/2.8 GM OSS + 2X Teleconverter")); - choices.insert (p_t (49201, "Zeiss Touit 12mm f/2.8")); - choices.insert (p_t (49202, "Zeiss Touit 32mm f/1.8")); - choices.insert (p_t (49203, "Zeiss Touit 50mm f/2.8 Macro")); - choices.insert (p_t (49216, "Zeiss Batis 25mm f/2")); - choices.insert (p_t (49217, "Zeiss Batis 85mm f/1.8")); - choices.insert (p_t (49218, "Zeiss Batis 18mm f/2.8")); - choices.insert (p_t (49219, "Zeiss Batis 135mm f/2.8")); - choices.insert (p_t (49220, "Zeiss Batis 40mm f/2 CF")); - choices.insert (p_t (49232, "Zeiss Loxia 50mm f/2")); - choices.insert (p_t (49233, "Zeiss Loxia 35mm f/2")); - choices.insert (p_t (49234, "Zeiss Loxia 21mm f/2.8")); - choices.insert (p_t (49235, "Zeiss Loxia 85mm f/2.4")); - choices.insert (p_t (49236, "Zeiss Loxia 25mm f/2.4")); - choices.insert (p_t (49457, "Tamron 28-75mm f/2.8 Di III RXD")); - choices.insert (p_t (50480, "Sigma 30mm f/1.4 DC DN | C")); - choices.insert (p_t (50481, "Sigma 50mm f/1.4 DG HSM | A")); - choices.insert (p_t (50482, "Sigma 18-300mm f/3.5-6.3 DC MACRO OS HSM | C + MC-11")); - choices.insert (p_t (50483, "Sigma 18-35mm f/1.8 DC HSM | A + MC-11")); - choices.insert (p_t (50484, "Sigma 24-35mm f/2 DG HSM | A + MC-11")); - choices.insert (p_t (50486, "Sigma 150-600mm f/5-6.3 DG OS HSM | C + MC-11")); - choices.insert (p_t (50487, "Sigma 20mm f/1.4 DG HSM | A + MC-11")); - choices.insert (p_t (50488, "Sigma 35mm f/1.4 DG HSM | A")); - choices.insert (p_t (50489, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + MC-11")); - choices.insert (p_t (50490, "Sigma 120-300mm f/2.8 DG OS HSM | S + MC-11")); - choices.insert (p_t (50492, "Sigma 24-105mm f/4 DG OS HSM | A + MC-11")); - choices.insert (p_t (50493, "Sigma 17-70mm f/2.8-4 DC MACRO OS HSM | C + MC-11")); - choices.insert (p_t (50495, "Sigma 50-100mm f/1.8 DC HSM | A + MC-11")); - choices.insert (p_t (50499, "Sigma 85mm f/1.4 DG HSM | A")); - choices.insert (p_t (50501, "Sigma 100-400mm f/5-6.3 DG OS HSM | C + MC-11")); - choices.insert (p_t (50503, "Sigma 16mm f/1.4 DC DN | C")); - choices.insert (p_t (50507, "Sigma 105mm f/1.4 DG HSM | A")); - choices.insert (p_t (50508, "Sigma 56mm f/1.4 DC DN | C")); - choices.insert (p_t (50512, "Sigma 70-200mm f/2.8 DG OS HSM | S")); - choices.insert (p_t (50513, "Sigma 70mm f/2.8 DG MACRO | A")); - choices.insert (p_t (50992, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III")); - choices.insert (p_t (50993, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6")); - choices.insert (p_t (50994, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III")); - choices.insert (p_t (50995, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical")); - choices.insert (p_t (50996, "Voigtlander NOKTON 40mm f/1.2 Aspherical")); - choices.insert (p_t (50997, "Voigtlander NOKTON classic 35mm f/1.4")); - choices.insert (p_t (50998, "Voigtlander MACRO APO-LANTHAR 110mm f/2.5")); - choices.insert (p_t (50999, "Voigtlander COLOR-SKOPAR 21mm f/3.5 Aspherical")); - choices.insert (p_t (51505, "Samyang AF 14mm f/2.8 FE or Samyang AF 35mm f/2.8 FE")); - choices.insert (p_t (51505, "Samyang AF 35mm f/2.8 FE")); - choices.insert (p_t (51507, "Samyang AF 35mm f/1.4")); - } - - std::string toString (const Tag* t) const override - { - int lensID = t->toInt(); - Tag *lensInfoTag = t->getParent()->getRoot()->findTag ("LensInfo"); - Tag *apertureTag = t->getParent()->getRoot()->findTag ("MaxApertureValue"); - Tag *focalLengthTag = t->getParent()->getRoot()->findTag ("FocalLength"); - double maxApertureAtFocal = 0.; - double focalLength = 0.; - - if ( apertureTag ) { - maxApertureAtFocal = pow (2.0, apertureTag->toDouble() / 2.0); - } - - if ( focalLengthTag ) { - focalLength = focalLengthTag->toDouble(); - } - - double *liArray = nullptr; - - if (lensInfoTag) { - liArray = lensInfoTag->toDoubleArray(); - } - - std::string retval = guess ( lensID, focalLength, maxApertureAtFocal, liArray); - - if (liArray) { - delete [] liArray; - } - - return retval; - } -}; -SALensID2Interpreter saLensID2Interpreter; - -class MATeleconverterInterpreter : public ChoiceInterpreter<> -{ -public: - MATeleconverterInterpreter () - { - choices[0x0] = "None"; - choices[0x4] = "Minolta/Sony AF 1.4x APO (D) (0x04)"; - choices[0x5] = "Minolta/Sony AF 2x APO (D) (0x05)"; - choices[0x48] = "Minolta/Sony AF 2x APO (D)"; - choices[0x50] = "Minolta AF 2x APO II"; - choices[0x60] = "Minolta AF 2x APO"; - choices[0x88] = "Minolta/Sony AF 1.4x APO (D)"; - choices[0x90] = "Minolta AF 1.4x APO II"; - choices[0xa0] = "Minolta AF 1.4x APO"; - } -}; -MATeleconverterInterpreter maTeleconverterInterpreter; - -class MAQualityInterpreter : public ChoiceInterpreter<> -{ -public: - MAQualityInterpreter () - { - choices[0] = "RAW"; - choices[1] = "Super Fine"; - choices[2] = "Fine"; - choices[3] = "Standard"; - choices[4] = "Economy"; - choices[5] = "Extra Fine"; - choices[6] = "RAW + JPEG"; - choices[7] = "Compressed RAW"; - choices[8] = "Compressed RAW + JPEG"; - } -}; -MAQualityInterpreter maQualityInterpreter; - -class MAImageSizeInterpreter : public ChoiceInterpreter<> -{ -public: - MAImageSizeInterpreter () - { - choices[1] = "1600x1200"; - choices[2] = "1280x960"; - choices[3] = "640x480"; - choices[5] = "2560x1920"; - choices[6] = "2272x1704"; - choices[7] = "2048x1536"; - } -}; -MAImageSizeInterpreter maImageSizeInterpreter; - -class SAQualityInterpreter2 : public ChoiceInterpreter<> -{ -public: - SAQualityInterpreter2 () - { - choices[0] = "Raw"; - choices[2] = "cRAW"; - choices[16] = "Extra fine"; - choices[32] = "Fine"; - choices[34] = "RAW + JPEG"; - choices[35] = "cRAW + JPEG"; - choices[48] = "Standard"; - } -}; -SAQualityInterpreter2 saQualityInterpreter2; - -class SAQualityInterpreter3 : public ChoiceInterpreter<> -{ -public: - SAQualityInterpreter3 () - { - choices[2] = "RAW"; - choices[4] = "RAW + JPEG"; - choices[6] = "Fine"; - choices[7] = "Standard"; - } -}; -SAQualityInterpreter3 saQualityInterpreter3; - -class SADriveMode : public ChoiceInterpreter<> -{ -public: - SADriveMode () - { - choices[1] = "Single Frame"; - choices[2] = "Continuous High"; - choices[4] = "Self-timer 10 sec"; - choices[5] = "Self-timer 2 sec, Mirror Lock-up"; - choices[6] = "Single-frame Bracketing"; - choices[7] = "Continuous Bracketing"; - choices[10] = "Remote Commander"; - choices[11] = "Mirror Lock-up"; - choices[18] = "Continuous Low"; - choices[24] = "White Balance Bracketing Low"; - choices[25] = "D-Range Optimizer Bracketing Low"; - choices[40] = "White Balance Bracketing High"; - choices[41] = "D-Range Optimizer Bracketing High"; - } -}; -SADriveMode saDriveMode; - -class SADriveMode2 : public ChoiceInterpreter<> -{ -public: - SADriveMode2 () - { - choices[1] = "Single Frame"; - choices[2] = "Continuous High"; - choices[4] = "Self-timer 10 sec"; - choices[5] = "Self-timer 2 sec, Mirror Lock-up"; - choices[7] = "Continuous Bracketing"; - choices[10] = "Remote Commander"; - choices[11] = "Continuous Self-timer"; - } -}; -SADriveMode2 saDriveMode2; - -class SADriveMode3 : public ChoiceInterpreter<> -{ -public: - SADriveMode3 () - { - choices[16] = "Single Frame"; - choices[33] = "Continuous High"; - choices[34] = "Continuous Low"; - choices[48] = "Speed Priority Continuous"; - choices[81] = "Self-timer 10 sec"; - choices[82] = "Self-timer 2 sec, Mirror Lock-up"; - choices[113] = "Continuous Bracketing 0.3 EV"; - choices[117] = "Continuous Bracketing 0.7 EV"; - choices[145] = "White Balance Bracketing Low"; - choices[146] = "White Balance Bracketing High"; - choices[192] = "Remote Commander"; - choices[209] = "Continuous - HDR"; - choices[210] = "Continuous - Multi Frame NR"; - choices[211] = "Continuous - Handheld Night Shot"; - choices[212] = "Continuous - Anti Motion Blur"; - choices[213] = "Continuous - Sweep Panorama"; - choices[214] = "Continuous - 3D Sweep Panorama"; - } -}; -SADriveMode3 saDriveMode3; - -class SAFocusMode: public ChoiceInterpreter<> -{ -public: - SAFocusMode () - { - choices[0] = "Manual"; - choices[1] = "AF-S"; - choices[2] = "AF-C"; - choices[3] = "AF-A"; - choices[4] = "Permanent-AF"; - choices[65535] = "n/a"; - } -}; -SAFocusMode saFocusMode; - -class SAFocusMode2: public ChoiceInterpreter<> -{ -public: - SAFocusMode2 () - { - choices[0] = "Manual"; - choices[1] = "AF-S"; - choices[2] = "AF-C"; - choices[3] = "AF-A"; - choices[65535] = "n/a"; - } -}; -SAFocusMode2 saFocusMode2; - -class SAFocusModeSetting3: public ChoiceInterpreter<> -{ -public: - SAFocusModeSetting3 () - { - choices[17] = "AF-S"; - choices[18] = "AF-C"; - choices[19] = "AF-A"; - choices[32] = "Manual"; - choices[48] = "DMF"; - choices[65535] = "n/a"; - } -}; -SAFocusModeSetting3 saFocusModeSetting3; - -class SAAFMode: public ChoiceInterpreter<> -{ -public: - SAAFMode() - { - choices[0] = "Default"; - choices[1] = "Multi AF"; - choices[2] = "Center AF"; - choices[3] = "Spot AF"; - choices[4] = "Flexible Spot AF"; - choices[6] = "Touch AF"; - choices[14] = "Tracking"; - choices[15] = "Face Tracking"; - choices[65535] = "n/a"; - } -}; -SAAFMode saAFMode; - -class SAAFAreaMode: public ChoiceInterpreter<> -{ -public: - SAAFAreaMode () - { - choices[0] = "Wide"; - choices[1] = "Local"; - choices[2] = "Spot"; - } -}; -SAAFAreaMode saAFAreaMode; - -class SAAFAreaMode2: public ChoiceInterpreter<> -{ -public: - SAAFAreaMode2 () - { - choices[1] = "Wide"; - choices[2] = "Spot"; - choices[3] = "Local"; - choices[4] = "Flexible"; - } -}; -SAAFAreaMode2 saAFAreaMode2; - -class SAAFPointSelected: public ChoiceInterpreter<> -{ -public: - SAAFPointSelected () - { - choices[1] = "Center"; - choices[2] = "Top"; - choices[3] = "Top-Right"; - choices[4] = "Right"; - choices[5] = "Bottom-Right"; - choices[6] = "Bottom"; - choices[7] = "Bottom-Left"; - choices[8] = "Left"; - choices[9] = "Top-Left"; - choices[10] = "Far Right"; - choices[11] = "Far Left"; - } -}; -SAAFPointSelected saAFPointSelected; - -class SACameraInfoAFPointSelected: public ChoiceInterpreter<> -{ -public: - SACameraInfoAFPointSelected () - { - choices[0] = "Auto"; - choices[1] = "Center"; - choices[2] = "Top"; - choices[3] = "Upper-Right"; - choices[4] = "Right"; - choices[5] = "Lower-Right"; - choices[6] = "Bottom"; - choices[7] = "Lower-Left"; - choices[8] = "Left"; - choices[9] = "Upper-Left"; - choices[10] = "Far Right"; - choices[11] = "Far Left"; - choices[12] = "Upper-middle"; - choices[13] = "Near Right"; - choices[14] = "Lower-middle"; - choices[15] = "Near Left"; - } -}; -SACameraInfoAFPointSelected saCameraInfoAFPointSelected; - -class SACameraInfoAFPoint: public ChoiceInterpreter<> -{ -public: - SACameraInfoAFPoint () - { - choices[0] = "Upper-Left"; - choices[1] = "Left"; - choices[2] = "Lower-Left"; - choices[3] = "Far Left"; - choices[4] = "Top (horizontal)"; - choices[5] = "Near Right"; - choices[6] = "Center (horizontal)"; - choices[7] = "Near Left"; - choices[8] = "Bottom (horizontal)"; - choices[9] = "Top (vertical)"; - choices[10] = "Center (vertical)"; - choices[11] = "Bottom (vertical)"; - choices[12] = "Far Right"; - choices[13] = "Upper-Right"; - choices[14] = "Right"; - choices[15] = "Lower-Right"; - choices[16] = "Upper-middle"; - choices[17] = "Lower-middle"; - choices[255] = "(none)"; - } -}; -SACameraInfoAFPoint saCameraInfoAFPoint; - -class SAAFPointSelected2: public ChoiceInterpreter<> -{ -public: - SAAFPointSelected2 () - { - choices[1] = "Center"; - choices[2] = "Top"; - choices[3] = "Top-Right"; - choices[4] = "Right"; - choices[5] = "Bottom-Right"; - choices[6] = "Bottom"; - choices[7] = "Bottom-Left"; - choices[8] = "Left"; - choices[9] = "Top-Left"; - } -}; -SAAFPointSelected2 saAFPointSelected2; - -class SAMeteringMode0_3: public ChoiceInterpreter<> -{ -public: - SAMeteringMode0_3 () - { - choices[0] = "Multi-segment"; - choices[2] = "Center-weighted Average"; - choices[3] = "Spot"; - } -}; -SAMeteringMode0_3 saMeteringMode0_3; - -class SAMeteringMode1_3: public ChoiceInterpreter<> -{ -public: - SAMeteringMode1_3 () - { - choices[1] = "Multi-segment"; - choices[2] = "Center-weighted Average"; - choices[3] = "Spot"; - } -}; -SAMeteringMode1_3 saMeteringMode1_3; - -class SAMeteringMode1_4: public ChoiceInterpreter<> -{ -public: - SAMeteringMode1_4 () - { - choices[1] = "Multi-segment"; - choices[2] = "Center-weighted Average"; - choices[4] = "Spot"; - } -}; -SAMeteringMode1_4 saMeteringMode1_4; - -class SADynamicRangeOptimizerMode: public ChoiceInterpreter<> -{ -public: - SADynamicRangeOptimizerMode () - { - choices[0] = "Off"; - choices[1] = "Standard"; - choices[2] = "Advanced Auto"; - choices[3] = "Advanced Level"; - choices[4097] = "Auto"; - } -}; -SADynamicRangeOptimizerMode saDynamicRangeOptimizerMode; - -class SADynamicRangeOptimizerSetting: public ChoiceInterpreter<> -{ -public: - SADynamicRangeOptimizerSetting () - { - choices[1] = "Off"; - choices[2] = "On (Auto)"; - choices[3] = "On (Manual)"; - } -}; -SADynamicRangeOptimizerSetting saDynamicRangeOptimizerSetting; - -class SACreativeStyle: public ChoiceInterpreter<> -{ -public: - SACreativeStyle () - { - choices[1] = "Standard"; - choices[2] = "Vivid"; - choices[3] = "Portrait"; - choices[4] = "Landscape"; - choices[5] = "Sunset"; - choices[6] = "Night View/Portrait"; - choices[8] = "B&W"; - choices[9] = "Adobe RGB"; - choices[11] = "Neutral"; - choices[12] = "Clear"; - choices[13] = "Deep"; - choices[14] = "Light"; - choices[15] = "Autumn Leaves"; - choices[16] = "Sepia"; - } -}; -SACreativeStyle saCreativeStyle; - -class SACreativeStyle2: public ChoiceInterpreter<> -{ -public: - SACreativeStyle2 () - { - choices[1] = "Standard"; - choices[2] = "Vivid"; - choices[3] = "Portrait"; - choices[4] = "Landscape"; - choices[5] = "Sunset"; - choices[6] = "Night View/Portrait"; - choices[8] = "B&W"; - } -}; -SACreativeStyle2 saCreativeStyle2; - -class SACreativeStyleSetting: public ChoiceInterpreter<> -{ -public: - SACreativeStyleSetting () - { - choices[16] = "Standard"; - choices[32] = "Vivid"; - choices[64] = "Portrait"; - choices[80] = "Landscape"; - choices[96] = "B&W"; - choices[160] = "Sunset"; - } -}; -SACreativeStyleSetting saCreativeStyleSetting; - -class SAFlashControl: public ChoiceInterpreter<> -{ -public: - SAFlashControl () - { - choices[1] = "ADI Flash"; - choices[2] = "Pre-flash TTL"; - } -}; -SAFlashControl saFlashControl; - -class SAFlashMode: public ChoiceInterpreter<> -{ -public: - SAFlashMode () - { - choices[0] = "ADI"; - choices[1] = "TTL"; - } -}; -SAFlashMode saFlashMode; - -class SAFlashMode2: public ChoiceInterpreter<> -{ -public: - SAFlashMode2 () - { - choices[1] = "Flash Off"; - choices[16] = "Autoflash"; - choices[17] = "Fill-flash"; - choices[18] = "Slow Sync"; - choices[19] = "Rear Sync"; - choices[20] = "Wireless"; - } -}; -SAFlashMode2 saFlashMode2; - -class SAExposureProgram: public ChoiceInterpreter<> -{ -public: - SAExposureProgram () - { - choices[0] = "Auto"; - choices[1] = "Manual"; - choices[2] = "Program AE"; - choices[3] = "Aperture-priority AE"; - choices[4] = "Shutter speed priority AE"; - choices[8] = "Program Shift A"; - choices[9] = "Program Shift S"; - choices[16] = "Portrait"; - choices[17] = "Sports"; - choices[18] = "Sunset"; - choices[19] = "Night Portrait"; - choices[20] = "Landscape"; - choices[21] = "Macro"; - choices[35] = "Auto No Flash"; - } -}; -SAExposureProgram saExposureProgram; - -class SAExposureProgram2: public ChoiceInterpreter<> -{ -public: - SAExposureProgram2 () - { - choices[1] = "Program AE"; - choices[2] = "Aperture-priority AE"; - choices[3] = "Shutter speed priority AE"; - choices[4] = "Manual"; - choices[5] = "Cont. Priority AE"; - choices[16] = "Auto"; - choices[17] = "Auto (no flash)"; - choices[18] = "Auto+"; - choices[49] = "Portrait"; - choices[50] = "Landscape"; - choices[51] = "Macro"; - choices[52] = "Sports"; - choices[53] = "Sunset"; - choices[54] = "Night view"; - choices[55] = "Night view/portrait"; - choices[56] = "Handheld Night Shot"; - choices[57] = "3D Sweep Panorama"; - choices[64] = "Auto 2"; - choices[65] = "Auto 2 (no flash)"; - choices[80] = "Sweep Panorama"; - choices[96] = "Anti Motion Blur"; - choices[128] = "Toy Camera"; - choices[129] = "Pop Color"; - choices[130] = "Posterization"; - choices[131] = "Posterization B/W"; - choices[132] = "Retro Photo"; - choices[133] = "High-key"; - choices[134] = "Partial Color Red"; - choices[135] = "Partial Color Green"; - choices[136] = "Partial Color Blue"; - choices[137] = "Partial Color Yellow"; - choices[138] = "High Contrast Monochrome"; - } -}; -SAExposureProgram2 saExposureProgram2; - -class SARotation: public ChoiceInterpreter<> -{ -public: - SARotation () - { - choices[0] = "Horizontal"; - choices[1] = "Rotate 90 CW"; - choices[2] = "Rotate 270 CW"; - choices[3] = "None"; - } -}; -SARotation saRotation; - -class SASonyImageSize: public ChoiceInterpreter<> -{ -public: - SASonyImageSize () - { - choices[1] = "Large"; - choices[2] = "Medium"; - choices[3] = "Small"; - } -}; -SASonyImageSize saSonyImageSize; - -class SASonyImageSize3: public ChoiceInterpreter<> -{ -public: - SASonyImageSize3 () - { - choices[21] = "Large (3:2)"; - choices[22] = "Medium (3:2)"; - choices[23] = "Small (3:2)"; - choices[25] = "Large (16:9)"; - choices[26] = "Medium (16:9) "; - choices[27] = "Small (16:9)"; - } -}; -SASonyImageSize3 saSonyImageSize3; - -class SAAspectRatio: public ChoiceInterpreter<> -{ -public: - SAAspectRatio () - { - choices[1] = "3:2"; - choices[2] = "16:9"; - } -}; -SAAspectRatio saAspectRatio; - -class SAAspectRatio2: public ChoiceInterpreter<> -{ -public: - SAAspectRatio2 () - { - choices[4] = "3:2"; - choices[8] = "16:9"; - } -}; -SAAspectRatio2 saAspectRatio2; - -class SAExposureLevelIncrements: public ChoiceInterpreter<> -{ -public: - SAExposureLevelIncrements () - { - choices[33] = "1/3 EV"; - choices[50] = "1/2 EV"; - } -}; -SAExposureLevelIncrements saExposureLevelIncrements; - -class SAAFIlluminator: public ChoiceInterpreter<> -{ -public: - SAAFIlluminator () - { - choices[0] = "Off"; - choices[1] = "Auto"; - choices[65535] = "n/a"; - } -}; -SAAFIlluminator saAFIlluminator; - -class SAColorSpace1_2: public ChoiceInterpreter<> -{ -public: - SAColorSpace1_2 () - { - choices[1] = "sRGB"; - choices[2] = "AdobeRGB"; - } -}; -SAColorSpace1_2 saColorSpace1_2; - -class SAColorSpace0_5: public ChoiceInterpreter<> -{ -public: - SAColorSpace0_5 () - { - choices[0] = "sRGB"; - choices[1] = "AdobeRGB"; - choices[5] = "AdobeRGB"; - } -}; -SAColorSpace0_5 saColorSpace0_5; - -class SAColorSpace5_6: public ChoiceInterpreter<> -{ -public: - SAColorSpace5_6 () - { - choices[5] = "AdobeRGB"; - choices[6] = "sRGB"; - } -}; -SAColorSpace5_6 saColorSpace5_6; - -class SAReleaseModeInterpreter: public ChoiceInterpreter<> -{ -public: - SAReleaseModeInterpreter () - { - choices[0] = "Normal"; - choices[2] = "Continuous"; - choices[5] = "Exposure Bracketing"; - choices[6] = "White Balance Bracketing"; - choices[8] = "DRO Bracketing"; - choices[65535] = "n/a"; - } -}; -SAReleaseModeInterpreter saReleaseModeInterpreter; - -class SAImageStyleInterpreter: public ChoiceInterpreter<> -{ -public: - SAImageStyleInterpreter () - { - choices[1] = "Standard"; - choices[2] = "Vivid"; - choices[3] = "Portrait"; - choices[4] = "Landscape"; - choices[5] = "Sunset"; - choices[7] = "Night View/Portrait"; - choices[8] = "B&W"; - choices[9] = "Adobe RGB"; - choices[11] = "Neutral"; - choices[129] = "StyleBox1"; - choices[130] = "StyleBox2"; - choices[131] = "StyleBox3"; - choices[132] = "StyleBox4"; - choices[133] = "StyleBox5"; - choices[134] = "StyleBox6"; - } -}; -SAImageStyleInterpreter saImageStyleInterpreter; - -class SAPictureEffectInterpreter: public ChoiceInterpreter<> -{ -public: - SAPictureEffectInterpreter() - { - choices[0] = "Off"; - choices[1] = "Toy Camera"; - choices[2] = "Pop Color"; - choices[3] = "Posterization"; - choices[4] = "Posterization B/W"; - choices[5] = "Retro Photo"; - choices[6] = "Soft High Key"; - choices[7] = "Partial Color (red)"; - choices[8] = "Partial Color (green)"; - choices[9] = "Partial Color (blue)"; - choices[10] = "Partial Color (yellow)"; - choices[13] = "High Contrast Monochrome"; - choices[16] = "Toy Camera (normal)"; - choices[17] = "Toy Camera (cool)"; - choices[18] = "Toy Camera (warm)"; - choices[19] = "Toy Camera (green)"; - choices[20] = "Toy Camera (magenta)"; - choices[32] = "Soft Focus (low)"; - choices[33] = "Soft Focus"; - choices[34] = "Soft Focus (high)"; - choices[48] = "Miniature (auto)"; - choices[49] = "Miniature (top)"; - choices[50] = "Miniature (middle horizontal)"; - choices[51] = "Miniature (bottom)"; - choices[52] = "Miniature (left)"; - choices[53] = "Miniature (middle vertical)"; - choices[54] = "Miniature (right)"; - choices[64] = "HDR Painting (low)"; - choices[65] = "HDR Painting"; - choices[66] = "HDR Painting (high)"; - choices[80] = "Rich-tone Monochrome"; - choices[97] = "Water Color"; - choices[98] = "Water Color 2"; - choices[112] = "Illustration (low)"; - choices[113] = "Illustration"; - choices[114] = "Illustration (high)"; - } -}; -SAPictureEffectInterpreter saPictureEffectInterpreter; - -class SACameraInfoFocusStatusInterpreter : public ChoiceInterpreter<> -{ -public: - SACameraInfoFocusStatusInterpreter() - { - choices[0] = "Manual - Not confirmed (0)"; - choices[4] = "Manual - Not confirmed (4)"; - choices[16] = "AF-C - Confirmed"; - choices[24] = "AF-C - Not Confirmed"; - choices[64] = "AF-S - Confirmed"; - } -}; -SACameraInfoFocusStatusInterpreter saCameraInfoFocusStatusInterpreter; - -class SAExposureTimeInterpreter : public Interpreter -{ -public: - SAExposureTimeInterpreter () {} - std::string toString (const Tag* t) const override - { - double a = t->toDouble(); - - if (a > 0) { - char buffer[32]; - sprintf (buffer, "%.4f", a); - return buffer; - } else { - return "n/a"; - } - } - double toDouble (const Tag* t, int ofs) override - { - // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT - TagType astype = t->getType(); - int a = 0; - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - // Decode the value - if (a > 0) { - return pow (2., 6. - (double (a) / 8.)); - } else { - return 0.; - } - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT - int a = 0; - - if (astype == INVALID || astype == AUTO) { - astype = t->getType(); - } - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - // Decode the value - if (a) { - return int (powf (2.f, 6.f - (float (a) / 8.f)) + 0.5f); - } else { - return 0; - } - } -}; -SAExposureTimeInterpreter saExposureTimeInterpreter; - -class SAFNumberInterpreter : public Interpreter -{ -public: - SAFNumberInterpreter () {} - std::string toString (const Tag* t) const override - { - double a = double (t->toDouble()); - - if (a) { - char buffer[32]; - sprintf (buffer, "%.1f", a / 100. ); - return buffer; - } else { - return "n/a"; - } - } - double toDouble (const Tag* t, int ofs) override - { - // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT - TagType astype = t->getType(); - int a = 0; - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - // Decode the value - if (a > 0) { - return pow (2., (double (a) / 8. - 1.) / 2.); - } else { - return 0.; - } - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT - int a = 0; - - if (astype == INVALID || astype == AUTO) { - astype = t->getType(); - } - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - // Decode the value - if (a) { - return int (powf (2.f, (float (a) / 8.f - 1.f) / 2.f) + 0.5f); - } else { - return 0; - } - } -}; -SAFNumberInterpreter saFNumberInterpreter; - -class SAISOSettingInterpreter : public Interpreter -{ -public: - SAISOSettingInterpreter () {} - std::string toString (const Tag* t) const override - { - int a = t->toInt(); - - if (a) { - char buffer[32]; - sprintf (buffer, "%d", a ); - return buffer; - } else { - return "Auto"; - } - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT - int a = 0; - - if (astype == INVALID || astype == AUTO) { - astype = t->getType(); - } - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - // Decode the value - if (a && a != 254) { // 254 = 'Auto' for CameraSettings3, but we might say the same for CameraSettings & CameraSettings2 (?) - return int (expf ((double (a) / 8.f - 6.f) * logf (2.f)) * 100.f + 0.5f); - } else { - return 0; - } - } -}; -SAISOSettingInterpreter saISOSettingInterpreter; - -class SAExposureCompSetInterpreter : public Interpreter -{ -public: - SAExposureCompSetInterpreter () {} - std::string toString (const Tag* t) const override - { - double a = t->toDouble(); - char buffer[32]; - sprintf (buffer, "%.2f", a ); - return buffer; - } - double toDouble (const Tag* t, int ofs) override - { - // Get the value - int a = t->getValue()[ofs]; - // Decode the value - return (double (a) - 128.) / 24.; - } -}; -SAExposureCompSetInterpreter saExposureCompSetInterpreter; - -class SAAFMicroAdjValueInterpreter : public Interpreter -{ -public: - SAAFMicroAdjValueInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%d", t->getValue()[0] - 20); - return buffer; - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - return t->getValue()[0] - 20; - } -}; -SAAFMicroAdjValueInterpreter saAFMicroAdjValueInterpreter; - -class SAAFMicroAdjModeInterpreter : public Interpreter -{ -public: - SAAFMicroAdjModeInterpreter() {} - std::string toString (const Tag* t) const override - { - int a = t->getValue()[0] & 0x80; - - if (a == 0x80) { - return "On"; - } - - return "Off"; - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - return (t->getValue()[0] & 0x80) == 0x80 ? 1 : 0; - } -}; - -SAAFMicroAdjModeInterpreter saAFMicroAdjModeInterpreter; - -class SAAFMicroAdjRegisteredLensesInterpreter : public Interpreter -{ -public: - SAAFMicroAdjRegisteredLensesInterpreter() {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%d", t->getValue()[0] & 0x7f); - return buffer; - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - return t->getValue()[0] & 0x7f; - } -}; -SAAFMicroAdjRegisteredLensesInterpreter saAFMicroAdjRegisteredLensesInterpreter; - -class SAFocusStatusInterpreter : public Interpreter -{ -public: - SAFocusStatusInterpreter () {} - std::string toString (const Tag* t) const override - { - std::string retval; - int a = t->toInt(); - - if (a == 0) { - retval = "Not confirmed"; - } else if (a == 4) { - retval = "Not confirmed, Tracking"; - } else { - if (a & 1) { - retval = "Confirmed"; - } - - if (a & 2) { - if (!retval.empty()) { - retval += ", "; - } - - retval += "Failed"; - } - - if (a & 4) - if (!retval.empty()) { - retval += ", "; - } - - retval += "Tracking"; - } - - return retval; - } -}; -SAFocusStatusInterpreter saFocusStatusInterpreter; - -class SAColorTemperatureSettingInterpreter : public Interpreter -{ -public: - SAColorTemperatureSettingInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - sprintf (buffer, "%d", t->toInt()); - return buffer; - } - int toInt (const Tag* t, int ofs, TagType astype) override - { - int a = 0; - - if (astype == INVALID || astype == AUTO) { - astype = t->getType(); - } - - if (astype == BYTE) { - a = t->getValue()[ofs]; - } else if (astype == SHORT) { - a = (int)sget2 (t->getValue() + ofs, t->getOrder()); - } - - return a * 100; - } -}; -SAColorTemperatureSettingInterpreter saColorTemperatureSettingInterpreter; - -const TagAttrib minoltaAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "MakerNoteVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "MinoltaCameraSettingsOld", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "MinoltaCameraSettings", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "MinoltaCameraSettings7D", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0018, AUTO, "ImageStabilization", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0040, AUTO, "CompressedImageSize", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0081, AUTO, "PreviewImage", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0088, AUTO, "PreviewImageStart", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0089, AUTO, "PreviewImageLength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0100, AUTO, "SceneMode", &saSceneModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0101, AUTO, "ColorMode", &saColorModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "MinoltaQuality", &maQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0103, AUTO, "MinoltaImageSize", &maImageSizeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0105, AUTO, "Teleconverter", &maTeleconverterInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0107, AUTO, "ImageStabilization", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010a, AUTO, "ZoneMatching", &saZoneMatchingInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010b, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010c, AUTO, "LensID", &saLensIDInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0113, AUTO, "ImageStabilization", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0114, AUTO, "MinoltaCameraSettings", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0f00, AUTO, "MinoltaCameraSettings2", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyAttribs[] = { - {0, AC_WRITE, 0, sonyCameraInfoAttribs, 0x0010, AUTO, "CameraInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0102, AUTO, "Quality", &maQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0104, AUTO, "FlashExposureComp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0106, AUTO, "TeleConverter", &maTeleconverterInterpreter}, - {0, AC_WRITE, 0, sonyCameraSettingsAttribs, 0x0114, AUTO, "SonyCameraSettings", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0115, AUTO, "WhiteBalance", &saWhiteBalanceInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, - {1, AC_WRITE, 0, nullptr, 0x2001, AUTO, "PreviewImage", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x2009, AUTO, "HighISONoiseReduction", &saHighISONoiseReduction}, - {0, AC_WRITE, 0, nullptr, 0x200a, AUTO, "AutoHDR", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x200b, AUTO, "MultiFrameNoiseReduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x200e, AUTO, "PictureEffect", &saPictureEffectInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x2011, AUTO, "VignettingCorrection", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x2012, AUTO, "LateralChromaticAberration", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x2013, AUTO, "DistortionCorrection", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb020, AUTO, "ColorReproduction", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb021, AUTO, "ColorTemperature", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb022, AUTO, "ColorCompensationFilter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb023, AUTO, "SceneMode", &saSceneModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb024, AUTO, "ZoneMatching", &saZoneMatchingInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb025, AUTO, "DynamicRangeOptimizer", &saDynamicRangeOptimizerInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb026, AUTO, "ImageStabilization", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb027, AUTO, "LensID", &saLensIDInterpreter}, - {0, AC_WRITE, 0, minoltaAttribs, 0xb028, AUTO, "MinoltaMakerNote", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb029, AUTO, "ColorMode", &saColorModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb040, AUTO, "Macro", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb041, AUTO, "ExposureMode", &saExposureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb042, AUTO, "FocusMode", &saFocusMode}, - {0, AC_WRITE, 0, nullptr, 0xb043, AUTO, "AFMode", &saAFMode}, - {0, AC_WRITE, 0, nullptr, 0xb044, AUTO, "AFIlluminator", &saAFIlluminator}, - {0, AC_WRITE, 0, nullptr, 0xb047, AUTO, "Quality", &saQualityInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb048, AUTO, "FlashLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb049, AUTO, "ReleaseMode", &saReleaseModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb04a, AUTO, "SequenceNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb04b, AUTO, "AntiBlur", &saAntiBlurInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb04e, AUTO, "LongExposureNoiseReduction", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb04f, AUTO, "DynamicRangeOptimizer", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xb050, AUTO, "HighISONoiseReduction2", &saHighISONoiseReduction2}, - {0, AC_WRITE, 0, nullptr, 0xb052, AUTO, "IntelligentAuto", &stdInterpreter}, - {0, AC_WRITE, 0, sonyTag9405Attribs, 0x9405, AUTO, "Tag9405", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyTag9405Attribs[] = { - {0, AC_WRITE, 0, nullptr, 0x005d, AUTO, "LensFormat", &stdInterpreter}, // 9405b start here - {0, AC_WRITE, 0, nullptr, 0x005e, AUTO, "LensMount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0060, SHORT, "LensType2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0062, SHORT, "LensType", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0603, AUTO, "LensFormat", &stdInterpreter}, // 9405a start here - {0, AC_WRITE, 0, nullptr, 0x0604, AUTO, "LensMount", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0605, SHORT, "LensType2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0608, SHORT, "LensType", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyCameraInfoAttribs[] = { - {0, AC_WRITE, 0, nullptr, 14, SHORT, "FocalLength", &saExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 16, SHORT, "FocalLengthTeleZoom", &saExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "FocusStatus", &saCameraInfoFocusStatusInterpreter}, - {0, AC_WRITE, 0, nullptr, 28, AUTO, "AFPointSelected", &saCameraInfoAFPointSelected}, - {0, AC_WRITE, 0, nullptr, 29, AUTO, "FocusMode", &saFocusMode2}, - {0, AC_WRITE, 0, nullptr, 32, AUTO, "AFPoint", &saCameraInfoAFPoint}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyCameraInfo2Attribs[] = { - {0, AC_WRITE, 0, nullptr, 304, AUTO, "AFMicroAdjValue", &saAFMicroAdjValueInterpreter}, - {0, AC_WRITE, 0, nullptr, 305, AUTO, "AFMicroAdjMode", &saAFMicroAdjModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 305, AUTO, "AFMicroAdjRegisteredLenses", &saAFMicroAdjRegisteredLensesInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyCameraSettingsAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "ExposureTime", &saExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "FNumber", &saFNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 4, AUTO, "DriveMode", &saDriveMode}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "WhiteBalanceFineTune", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "FocusModeSetting", &saFocusMode}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "AFAreaMode", &saAFAreaMode}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "AFPointSelected", &saAFPointSelected}, - {0, AC_WRITE, 0, nullptr, 21, AUTO, "MeteringMode", &saMeteringMode1_4}, - {0, AC_WRITE, 0, nullptr, 22, AUTO, "ISOSetting", &saISOSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 24, AUTO, "DynamicRangeOptimizerMode", &saDynamicRangeOptimizerMode}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "DynamicRangeOptimizerLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 26, AUTO, "CreativeStyle", &saCreativeStyle}, - {0, AC_WRITE, 0, nullptr, 28, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 29, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 30, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 31, AUTO, "ZoneMatchingValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 34, AUTO, "Brightness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 35, AUTO, "FlashMode", &saFlashMode}, - {0, AC_WRITE, 0, nullptr, 40, AUTO, "PrioritySetupShutterRelease", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 41, AUTO, "AFIlluminator", &saAFIlluminator}, - {0, AC_WRITE, 0, nullptr, 42, AUTO, "AFWithShutter", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 43, AUTO, "LongExposureNoiseReduction", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 44, AUTO, "HighISONoiseReduction", &saHighISONoiseReduction3}, - {0, AC_WRITE, 0, nullptr, 45, AUTO, "ImageStyle", &saImageStyleInterpreter}, - {0, AC_WRITE, 0, nullptr, 60, AUTO, "ExposureProgram", &saExposureProgram}, - {0, AC_WRITE, 0, nullptr, 61, AUTO, "ImageStabilization", &saOnOffInterpreter}, - {0, AC_WRITE, 0, nullptr, 63, AUTO, "Rotation", &saRotation}, - {0, AC_WRITE, 0, nullptr, 77, AUTO, "FocusMode", &saFocusMode}, - {0, AC_WRITE, 0, nullptr, 83, AUTO, "FocusStatus", &saFocusStatusInterpreter}, - {0, AC_WRITE, 0, nullptr, 84, AUTO, "SonyImageSize", &saSonyImageSize}, - {0, AC_WRITE, 0, nullptr, 85, AUTO, "AspectRatio", &saAspectRatio}, - {0, AC_WRITE, 0, nullptr, 86, AUTO, "Quality", &saQualityInterpreter2}, - {0, AC_WRITE, 0, nullptr, 88, AUTO, "ExposureLevelIncrements", &saExposureLevelIncrements}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyCameraSettingsAttribs2[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "ExposureTime", &saExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "FNumber", &saFNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 11, AUTO, "ColorTemperatureSetting", &saColorTemperatureSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "FocusMode", &saFocusMode2}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "AFAreaMode", &saAFAreaMode}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "AFPointSelected", &saAFPointSelected2}, - {0, AC_WRITE, 0, nullptr, 19, AUTO, "MeteringMode", &saMeteringMode1_4}, - {0, AC_WRITE, 0, nullptr, 20, AUTO, "ISOSetting", &saISOSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 22, AUTO, "DynamicRangeOptimizerMode", &saDynamicRangeOptimizerMode}, - {0, AC_WRITE, 0, nullptr, 23, AUTO, "DynamicRangeOptimizerLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 24, AUTO, "CreativeStyle", &saCreativeStyle2}, - {0, AC_WRITE, 0, nullptr, 25, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 26, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 27, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 35, AUTO, "FlashMode", &saFlashMode}, - {0, AC_WRITE, 0, nullptr, 38, AUTO, "HighISONoiseReduction", &saHighISONoiseReduction4}, - {0, AC_WRITE, 0, nullptr, 60, AUTO, "ExposureProgram", &saExposureProgram}, - {0, AC_WRITE, 0, nullptr, 63, AUTO, "Rotation", &saRotation}, - {0, AC_WRITE, 0, nullptr, 83, AUTO, "FocusStatus", &saFocusStatusInterpreter}, - {0, AC_WRITE, 0, nullptr, 84, AUTO, "SonyImageSize", &saSonyImageSize}, - {0, AC_WRITE, 0, nullptr, 85, AUTO, "AspectRatio", &saAspectRatio}, - {0, AC_WRITE, 0, nullptr, 86, AUTO, "Quality", &saQualityInterpreter2}, - {0, AC_WRITE, 0, nullptr, 88, AUTO, "ExposureLevelIncrements", &saExposureLevelIncrements}, - {0, AC_WRITE, 0, nullptr, 126, AUTO, "DriveMode", &saDriveMode2}, - {0, AC_WRITE, 0, nullptr, 131, AUTO, "ColorSpace", &saColorSpace5_6}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -const TagAttrib sonyCameraSettingsAttribs3[] = { - {0, AC_WRITE, 0, nullptr, 0, AUTO, "ShutterSpeedSetting", &saExposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 1, AUTO, "ApertureSetting", &saFNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 2, AUTO, "ISOSetting", &saISOSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "ExposureCompensationSet", &saExposureCompSetInterpreter}, - {0, AC_WRITE, 0, nullptr, 3, AUTO, "DriveModeSetting", &saDriveMode3}, - {0, AC_WRITE, 0, nullptr, 5, AUTO, "ExposureProgram", &saExposureProgram2}, - {0, AC_WRITE, 0, nullptr, 6, AUTO, "FocusModeSetting", &saFocusModeSetting3}, - {0, AC_WRITE, 0, nullptr, 7, AUTO, "MeteringMode", &saMeteringMode1_3}, - {0, AC_WRITE, 0, nullptr, 9, AUTO, "SonyImageSize", &saSonyImageSize3}, - {0, AC_WRITE, 0, nullptr, 10, AUTO, "AspectRatio", &saAspectRatio2}, - {0, AC_WRITE, 0, nullptr, 11, AUTO, "Quality", &saQualityInterpreter3}, - {0, AC_WRITE, 0, nullptr, 12, AUTO, "DynamicRangeOptimizerSetting", &saDynamicRangeOptimizerSetting}, - {0, AC_WRITE, 0, nullptr, 14, AUTO, "ColorSpace", &saColorSpace1_2}, - {0, AC_WRITE, 0, nullptr, 15, AUTO, "CreativeStyleSetting", &saCreativeStyleSetting}, - {0, AC_WRITE, 0, nullptr, 16, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 17, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 18, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 22, AUTO, "WhiteBalance", &saWhiteBalanceSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 23, AUTO, "ColorTemperatureSetting", &saColorTemperatureSettingInterpreter}, - {0, AC_WRITE, 0, nullptr, 23, AUTO, "ColorCompensationFilterSet", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 32, AUTO, "FlashMode", &saFlashMode2}, - {0, AC_WRITE, 0, nullptr, 33, AUTO, "FlashControl", &saFlashControl}, - {0, AC_WRITE, 0, nullptr, 35, AUTO, "FlashExposureCompSet", &saExposureCompSetInterpreter}, - {0, AC_WRITE, 0, nullptr, 36, AUTO, "AFAreaMode", &saAFAreaMode2}, - {0, AC_WRITE, 0, nullptr, 37, AUTO, "LongExposureNoiseReduction", &saOnOffInterpreter2}, - {0, AC_WRITE, 0, nullptr, 38, AUTO, "HighISONoiseReduction", &saHighISONoiseReduction5}, - {0, AC_WRITE, 0, nullptr, 39, AUTO, "SmileShutterMode", &saSmileShutterMode}, - {0, AC_WRITE, 0, nullptr, 40, AUTO, "RedEyeReduction", &saOnOffInterpreter2}, - {0, AC_WRITE, 0, nullptr, 45, AUTO, "HDRSetting", &saOnOffInterpreter3}, - {0, AC_WRITE, 0, nullptr, 46, AUTO, "HDRLevel", &saHDRLevel}, - {0, AC_WRITE, 0, nullptr, 47, AUTO, "ViewingMode", &saViewingMode}, - {0, AC_WRITE, 0, nullptr, 48, AUTO, "FaceDetection", &saOnOffInterpreter2}, - {0, AC_WRITE, 0, nullptr, 49, AUTO, "SmileShutter", &saOnOffInterpreter2}, - {0, AC_WRITE, 0, nullptr, 50, AUTO, "SweepPanoramaSize", &saSweepPanoramaSize}, - {0, AC_WRITE, 0, nullptr, 51, AUTO, "SweepPanoramaDirection", &saSweepPanoramaDirection}, - {0, AC_WRITE, 0, nullptr, 52, AUTO, "DriveMode", &saDriveMode3}, - {0, AC_WRITE, 0, nullptr, 53, AUTO, "MultiFrameNoiseReduction", &saOnOffInterpreter4}, - {0, AC_WRITE, 0, nullptr, 54, AUTO, "LiveViewAFSetting", &saLiveViewAFSetting}, - {0, AC_WRITE, 0, nullptr, 56, AUTO, "PanoramaSize3D", &saPanoramaSize3D}, - {0, AC_WRITE, 0, nullptr, 131, AUTO, "AFButtonPressed", &saNoYesInterpreter}, - {0, AC_WRITE, 0, nullptr, 132, AUTO, "LiveViewMetering", &saLiveViewMetering}, - {0, AC_WRITE, 0, nullptr, 133, AUTO, "ViewingMode2", &saViewingMode}, - {0, AC_WRITE, 0, nullptr, 134, AUTO, "AELock", &saOnOffInterpreter5}, - {0, AC_WRITE, 0, nullptr, 135, AUTO, "FlashAction", &saFlashAction}, - {0, AC_WRITE, 0, nullptr, 139, AUTO, "LiveViewFocusMode", &saLiveViewFocusMode}, - {0, AC_WRITE, 0, nullptr, 153, AUTO, "LensMount", &saLensMount}, - {0, AC_WRITE, 0, nullptr, 643, AUTO, "AFButtonPressed", &saNoYesInterpreter}, - {0, AC_WRITE, 0, nullptr, 644, AUTO, "LiveViewMetering", &saLiveViewMetering}, - {0, AC_WRITE, 0, nullptr, 645, AUTO, "ViewingMode2", &saViewingMode}, - {0, AC_WRITE, 0, nullptr, 646, AUTO, "AELock", &saOnOffInterpreter5}, - {0, AC_WRITE, 0, nullptr, 647, AUTO, "FlashAction", &saFlashAction}, - {0, AC_WRITE, 0, nullptr, 651, AUTO, "LiveViewFocusMode", &saLiveViewFocusMode}, - {0, AC_WRITE, 0, nullptr, 1015, SHORT, "LensType2", &saLensID2Interpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; - -/*const TagAttrib sonyDNGMakerNote[]={ - {0, AC_WRITE, 0, 0, 0x7200, AUTO, "SonyOffset", &stdInterpreter}, - {0, AC_WRITE, 0, 0, 0x7201, AUTO, "SonyLength", &stdInterpreter}, - {0, AC_WRITE, 0, 0, 0x7221, AUTO, "SonyKey", &stdInterpreter}, - {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}};*/ - -} -#endif - - diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc deleted file mode 100644 index ec5534381..000000000 --- a/rtexif/stdattribs.cc +++ /dev/null @@ -1,931 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * Copyright (c) 2010 Oliver Duis - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _STDATTRIBS_ -#define _STDATTRIBS_ - -#include -#include - -#include "rtexif.h" - -namespace rtexif -{ - -class ColorSpaceInterpreter : public ChoiceInterpreter<> -{ - -public: - ColorSpaceInterpreter () - { - choices[1] = "sRGB"; - choices[2] = "Adobe RGB"; - choices[0xffff] = "Uncalibrated"; - } -}; -ColorSpaceInterpreter colorSpaceInterpreter; - -class PreviewColorSpaceInterpreter : public ChoiceInterpreter<> -{ - -public: - PreviewColorSpaceInterpreter () - { - choices[0] = "Unknown"; - choices[1] = "Gray Gamma 2.2"; - choices[2] = "sRGB"; - choices[3] = "Adobe RGB"; - choices[4] = "ProPhoto RGB"; - } -}; -PreviewColorSpaceInterpreter previewColorSpaceInterpreter; - -class LinearSRGBInterpreter : public ChoiceInterpreter<> -{ - -public: - LinearSRGBInterpreter () - { - choices[0] = "Linear"; - choices[1] = "sRGB"; - } -}; -LinearSRGBInterpreter linearSRGBInterpreter; - -class DefaultBlackRenderInterpreter : public ChoiceInterpreter<> -{ - -public: - DefaultBlackRenderInterpreter () - { - choices[0] = "Auto"; - choices[1] = "None"; - } -}; -DefaultBlackRenderInterpreter defaultBlackRenderInterpreter; - -class ExposureProgramInterpreter : public ChoiceInterpreter<> -{ - -public: - ExposureProgramInterpreter () - { - choices[0] = "Not defined"; - choices[1] = "Manual"; - choices[2] = "Normal program"; - choices[3] = "Aperture priority"; - choices[4] = "Shutter priority"; - choices[5] = "Creative program"; - choices[6] = "Action program"; - choices[7] = "Portrait mode"; - choices[8] = "Landscape mode"; - } -}; -ExposureProgramInterpreter exposureProgramInterpreter; - -class MeteringModeInterpreter : public ChoiceInterpreter<> -{ - -public: - MeteringModeInterpreter () - { - choices[0] = "Unknown"; - choices[1] = "Average"; - choices[2] = "Center weighted"; - choices[3] = "Spot"; - choices[4] = "Multispot"; - choices[5] = "Pattern"; - choices[6] = "Partial"; - choices[255] = "Other"; - } -}; -MeteringModeInterpreter meteringModeInterpreter; - -class ExposureModeInterpreter : public ChoiceInterpreter<> -{ - -public: - ExposureModeInterpreter () - { - choices[0] = "Auto exposure"; - choices[1] = "Manual exposure"; - choices[2] = "Auto bracket"; - } -}; -ExposureModeInterpreter exposureModeInterpreter; - -class WhiteBalanceInterpreter : public ChoiceInterpreter<> -{ - -public: - WhiteBalanceInterpreter () - { - choices[0] = "Auto white balance"; - choices[1] = "Manual white balance"; - } -}; -WhiteBalanceInterpreter whiteBalanceInterpreter; - -class SceneCaptureInterpreter : public ChoiceInterpreter<> -{ - -public: - SceneCaptureInterpreter () - { - choices[0] = "Standard"; - choices[1] = "Landscape"; - choices[2] = "Portrait"; - choices[3] = "Night scene"; - } -}; -SceneCaptureInterpreter sceneCaptureInterpreter; - -class GainControlInterpreter : public ChoiceInterpreter<> -{ - -public: - GainControlInterpreter () - { - choices[0] = "None"; - choices[1] = "Low gain up"; - choices[2] = "High gain up"; - choices[3] = "Low gain down"; - choices[4] = "High gain down"; - } -}; -GainControlInterpreter gainControlInterpreter; - -class ContrastInterpreter : public ChoiceInterpreter<> -{ - -public: - ContrastInterpreter () - { - choices[0] = "Normal"; - choices[1] = "Soft"; - choices[2] = "Hard"; - } -}; -ContrastInterpreter contrastInterpreter; - -class SharpnessInterpreter : public ChoiceInterpreter<> -{ - -public: - SharpnessInterpreter () - { - choices[0] = "Normal"; - choices[1] = "Soft"; - choices[2] = "Hard"; - } -}; -SharpnessInterpreter sharpnessInterpreter; - -class SaturationInterpreter : public ChoiceInterpreter<> -{ - -public: - SaturationInterpreter () - { - choices[0] = "Normal"; - choices[1] = "Low saturation"; - choices[2] = "High saturation"; - } -}; -SaturationInterpreter saturationInterpreter; - -class FlashInterpreter : public ChoiceInterpreter<> -{ - -public: - FlashInterpreter () - { - choices[0x0000] = "Flash did not fire"; - choices[0x0001] = "Flash fired"; - choices[0x0005] = "Strobe return light not detected"; - choices[0x0007] = "Strobe return light detected"; - choices[0x0009] = "Flash fired, compulsory flash mode"; - choices[0x000D] = "Flash fired, compulsory flash mode, return light not detected"; - choices[0x000F] = "Flash fired, compulsory flash mode, return light detected"; - choices[0x0010] = "Flash did not fire, compulsory flash mode"; - choices[0x0018] = "Flash did not fire, auto mode"; - choices[0x0019] = "Flash fired, auto mode"; - choices[0x001D] = "Flash fired, auto mode, return light not detected"; - choices[0x001F] = "Flash fired, auto mode, return light detected"; - choices[0x0020] = "No flash function"; - choices[0x0041] = "Flash fired, red-eye reduction mode"; - choices[0x0045] = "Flash fired, red-eye reduction mode, return light not detected"; - choices[0x0047] = "Flash fired, red-eye reduction mode, return light detected"; - choices[0x0049] = "Flash fired, compulsory flash mode, red-eye reduction mode"; - choices[0x004D] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"; - choices[0x004F] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"; - choices[0x0059] = "Flash fired, auto mode, red-eye reduction mode"; - choices[0x005D] = "Flash fired, auto mode, return light not detected, red-eye reduction mode"; - choices[0x005F] = "Flash fired, auto mode, return light detected, red-eye reduction mode"; - } -}; -FlashInterpreter flashInterpreter; - -class LightSourceInterpreter : public ChoiceInterpreter<> -{ - -public: - LightSourceInterpreter () - { - choices[0] = "Unknown"; - choices[1] = "Daylight"; - choices[2] = "Fluorescent"; - choices[3] = "Tungsten"; - choices[4] = "Flash"; - choices[9] = "Fine weather"; - choices[10] = "Cloudy weather"; - choices[11] = "Shade"; - choices[12] = "Daylight fluorescent"; - choices[13] = "Day white fluorescent"; - choices[14] = "Cool white fluorescent"; - choices[15] = "White fluorescent"; - choices[17] = "Standard light A"; - choices[18] = "Standard light B"; - choices[19] = "Standard light C"; - choices[20] = "D55"; - choices[21] = "D65"; - choices[22] = "D75"; - choices[23] = "D50"; - choices[24] = "ISO studio tungsten"; - choices[255] = "Other light source"; - } -}; -LightSourceInterpreter lightSourceInterpreter; - -class CompressionInterpreter : public ChoiceInterpreter<> -{ - -public: - CompressionInterpreter () - { - choices[1] = "Uncompressed"; - choices[6] = "JPEG Compression"; - } -}; -CompressionInterpreter compressionInterpreter; - -class PhotometricInterpreter : public ChoiceInterpreter<> -{ - -public: - PhotometricInterpreter () - { - choices[2] = "RGB"; - choices[6] = "YCbCr"; - } -}; -PhotometricInterpreter photometricInterpreter; - -class ProfileEmbedPolicyInterpreter : public ChoiceInterpreter<> -{ - -public: - ProfileEmbedPolicyInterpreter () - { - choices[0] = "Allow Copying"; - choices[1] = "Embed if Used"; - choices[2] = "Never Embed"; - choices[3] = "No Restrictions"; - } -}; -ProfileEmbedPolicyInterpreter profileEmbedPolicyInterpreter; - -class PlanarConfigInterpreter : public ChoiceInterpreter<> -{ - -public: - PlanarConfigInterpreter () - { - choices[1] = "Chunky format"; - choices[2] = "Planar format"; - } -}; -PlanarConfigInterpreter planarConfigInterpreter; - -class FNumberInterpreter : public Interpreter -{ -public: - FNumberInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = t->toDouble(); - - if ( v < 0. || v > 1000. ) { - return "undef"; - } - - sprintf (buffer, "%0.1f", v); - return buffer; - } -}; -FNumberInterpreter fNumberInterpreter; - -class ApertureInterpreter : public Interpreter -{ -public: - ApertureInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = pow (2.0, t->toDouble() / 2.0); - - if ( v < 0. || v > 1000. ) { - return "undef"; - } - - sprintf (buffer, "%.1f", v ); - return buffer; - } -}; -ApertureInterpreter apertureInterpreter; - -class ExposureBiasInterpreter : public Interpreter -{ -public: - ExposureBiasInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = t->toDouble(); - - if ( v < -1000. || v > 1000. ) { - return "undef"; - } - - sprintf (buffer, "%+0.2f", v ); - return buffer; - } -}; -ExposureBiasInterpreter exposureBiasInterpreter; - -class ShutterSpeedInterpreter : public Interpreter -{ -public: - ShutterSpeedInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double d = pow (2.0, -t->toDouble()); - - if (d > 0.0 && d <= 0.5) { - sprintf (buffer, "1/%.0f", 1.0 / d); - } else { - sprintf (buffer, "%.1f", d); - } - - return buffer; - } -}; -ShutterSpeedInterpreter shutterSpeedInterpreter; - -class ExposureTimeInterpreter : public Interpreter -{ -public: - ExposureTimeInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double d = t->toDouble(); - - if (d > 0.0 && d <= 0.5) { - sprintf (buffer, "1/%.0f", 1.0 / d); - } else { - sprintf (buffer, "%.1f", d); - } - - return buffer; - } -}; -ExposureTimeInterpreter exposureTimeInterpreter; - -class FocalLengthInterpreter : public Interpreter -{ -public: - FocalLengthInterpreter () {} - std::string toString (const Tag* t) const override - { - char buffer[32]; - double v = t->toDouble(); - - if ( v > 1000000. || v < 0 ) { - return "undef"; - } - - sprintf (buffer, "%.1f", v ); - return buffer; - } -}; -FocalLengthInterpreter focalLengthInterpreter; - -class UserCommentInterpreter : public Interpreter -{ -public: - UserCommentInterpreter () {} - std::string toString (const Tag* t) const override - { - int count = t->getCount(); - - if (count <= 8) { - return std::string(); - } - - count = std::min (count, 65535); // limit to 65535 chars to avoid crashes in case of corrupted metadata - unsigned char *buffer = new unsigned char[count - 6]; // include 2 ending null chars for UCS-2 string (possibly) - unsigned char *value = t->getValue(); - - if (!memcmp(value, "ASCII\0\0\0", 8)) { - memcpy(buffer, value + 8, count - 8); - buffer[count - 8] = '\0'; - } else if (!memcmp(value, "UNICODE\0", 8)) { - memcpy(buffer, value + 8, count - 8); - buffer[count - 7] = buffer[count - 8] = '\0'; - Glib::ustring tmp1((char*)buffer); - - - bool hasBOM = false; - enum ByteOrder bo = UNKNOWN; - if (count % 2 || (count >= 11 && (buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF))) { - // odd string length can only be UTF-8, don't change anything - std::string retVal ((char*)buffer + 3); - delete [] buffer; - return retVal; - } else if (count >= 10) { - if (buffer[0] == 0xFF && buffer[1] == 0xFE) { - bo = INTEL; // little endian - hasBOM = true; - } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) { - bo = MOTOROLA; // big endian - hasBOM = true; - } - } - if (bo == UNKNOWN) { - // auto-detecting byte order; we still don't know if it's UCS-2 or UTF-8 - int a = 0, b = 0, c = 0, d = 0; - for (int j = 8; j < count; j++) { - unsigned char cc = value[j]; - if (!(j%2)) { - // counting zeros for first byte - if (!cc) { - ++a; - } - } else { - // counting zeros for second byte - if (!cc) { - ++b; - } - } - if (!(cc & 0x80) || ((cc & 0xC0) == 0xC0) || ((cc & 0xC0) == 0x80)) { - ++c; - } - if ((cc & 0xC0) == 0x80) { - ++d; - } - } - if (c == (count - 8) && d) { - // this is an UTF-8 string - std::string retVal ((char*)buffer); - delete [] buffer; - return retVal; - } - if ((a || b) && a != b) { - bo = a > b ? MOTOROLA : INTEL; - } - } - if (bo == UNKNOWN) { - // assuming platform's byte order -#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - bo = INTEL; -#else - bo = MOTOROLA; -#endif - } - - // now swapping if necessary - if (!hasBOM && bo != HOSTORDER) { - if (t->getOrder() != HOSTORDER) { - Tag::swapByteOrder2(buffer, count - 8); - } - } - - glong written; - char* utf8Str = g_utf16_to_utf8((unsigned short int*)buffer, -1, nullptr, &written, nullptr); - delete [] buffer; - buffer = new unsigned char[written + 1]; - memcpy(buffer, utf8Str, written); - buffer[written] = 0; - g_free(utf8Str); - } else if (!memcmp(value, "\0\0\0\0\0\0\0\0", 8)) { - // local charset string, whatever it is - memcpy(buffer, value + 8, count - 8); - buffer[count - 7] = buffer[count - 8] = '\0'; - - gsize written = 0; - char *utf8Str = g_locale_to_utf8((char*)buffer, count - 8, nullptr, &written, nullptr); - if (utf8Str && written) { - delete [] buffer; - size_t length = strlen(utf8Str); - buffer = new unsigned char[length + 1]; - strcpy((char*)buffer, utf8Str); - } else { - buffer[0] = 0; - } - if (utf8Str) { - g_free(utf8Str); - } - } else { - // JIS: unsupported - buffer[0] = 0; - } - - std::string retVal ((char*)buffer); - delete [] buffer; - return retVal; - } - void fromString (Tag* t, const std::string& value) override - { - Glib::ustring tmpStr(value); - t->userCommentFromString (tmpStr); - } -}; -UserCommentInterpreter userCommentInterpreter; - -class CFAInterpreter : public Interpreter -{ -public: - CFAInterpreter() {} - std::string toString (const Tag* t) const override - { - char colors[] = "RGB"; - char buffer[1024]; - - for ( int i = 0; i < t->getCount(); i++) { - unsigned char c = t->toInt (i, BYTE); - buffer[i] = c < 3 ? colors[c] : ' '; - } - - buffer[t->getCount()] = 0; - return buffer; - } -}; -CFAInterpreter cfaInterpreter; - -class OrientationInterpreter : public ChoiceInterpreter<> -{ -public: - OrientationInterpreter () - { - choices[1] = "Horizontal (normal)"; - choices[2] = "Mirror horizontal "; - choices[3] = "Rotate 180"; - choices[4] = "Mirror vertical"; - choices[5] = "Mirror horizontal and rotate 270 CW"; - choices[6] = "Rotate 90 CW"; - choices[7] = "Mirror horizontal and rotate 90 CW"; - choices[8] = "Rotate 270 CW"; - // '9' is an "unofficial" value for Orientation but used by some older cameras that lacks orientation sensor, such as Kodak DCS - choices[9] = "Unknown"; - } -}; -OrientationInterpreter orientationInterpreter; - -class UnitsInterpreter : public ChoiceInterpreter<> -{ -public: - UnitsInterpreter() - { - choices[0] = "Unknown"; - choices[1] = "inches"; - choices[2] = "cm"; - } -}; -UnitsInterpreter unitsInterpreter; - -class UTF8BinInterpreter : public Interpreter -{ -public: - UTF8BinInterpreter () {} -}; -UTF8BinInterpreter utf8BinInterpreter; - -class RawImageSegmentationInterpreter : public Interpreter -{ -public: - std::string toString (const Tag* t) const override - { - int segmentNumber = t->toInt(0, SHORT); - int segmentWidth = t->toInt(2, SHORT); - int lastSegmentWidth = t->toInt(4, SHORT); - - char buffer[32]; - sprintf (buffer, "%d %d %d", segmentNumber, segmentWidth, lastSegmentWidth); - return buffer; - } -}; -RawImageSegmentationInterpreter rawImageSegmentationInterpreter; - -const TagAttrib exifAttribs[] = { - {0, AC_SYSTEM, 0, nullptr, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0103, AUTO, "Compression", &compressionInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0153, AUTO, "SampleFormat", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x829A, AUTO, "ExposureTime", &exposureTimeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x829D, AUTO, "FNumber", &fNumberInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8822, AUTO, "ExposureProgram", &exposureProgramInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8824, AUTO, "SpectralSensitivity", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8827, AUTO, "ISOSpeedRatings", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8828, AUTO, "OECF", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x8832, AUTO, "RecommendedExposureIndex", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9000, AUTO, "ExifVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9003, AUTO, "DateTimeOriginal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9004, AUTO, "DateTimeDigitized", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x9101, AUTO, "ComponentsConfiguration", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x9102, AUTO, "CompressedBitsPerPixel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9201, AUTO, "ShutterSpeedValue", &shutterSpeedInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9202, AUTO, "ApertureValue", &apertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9203, AUTO, "BrightnessValue", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9204, AUTO, "ExposureBiasValue", &exposureBiasInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9205, AUTO, "MaxApertureValue", &apertureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9206, AUTO, "SubjectDistance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9207, AUTO, "MeteringMode", &meteringModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9208, AUTO, "LightSource", &lightSourceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9209, AUTO, "Flash", &flashInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x920A, AUTO, "FocalLength", &focalLengthInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9214, AUTO, "SubjectArea", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9215, AUTO, "ExposureIndex", &stdInterpreter}, // Note: exists as 0xA215 too, it should be that way - {0, AC_DONTWRITE, 0, nullptr, 0x9216, AUTO, "TIFFEPSStandardID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9217, AUTO, "SensingMethod", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x927C, AUTO, "MakerNote", &stdInterpreter}, - {0, AC_WRITE, 1, nullptr, 0x9286, AUTO, "UserComment", &userCommentInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9290, AUTO, "SubSecTime", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9291, AUTO, "SubSecTimeOriginal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9292, AUTO, "SubSecTimeDigitized", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0xA000, AUTO, "FlashpixVersion", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xA001, AUTO, "ColorSpace", &colorSpaceInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0xA002, AUTO, "PixelXDimension", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0xA003, AUTO, "PixelYDimension", &stdInterpreter}, - {1, AC_DONTWRITE, 0, nullptr, 0xA004, AUTO, "RelatedSoundFile", &stdInterpreter}, - {0, AC_SYSTEM, 0, iopAttribs, 0xA005, AUTO, "Interoperability", &stdInterpreter}, // do not enable, as it causes trouble with FUJI files - {0, AC_WRITE, 0, nullptr, 0xA20B, AUTO, "FlashEnergy", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA20C, AUTO, "SpatialFrequencyResponse", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA20E, AUTO, "FocalPlaneXResolution", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA20F, AUTO, "FocalPlaneYResolution", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA210, AUTO, "FocalPlaneResolutionUnit", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA214, AUTO, "SubjectLocation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA215, AUTO, "ExposureIndex", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA217, AUTO, "SensingMethod", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA300, AUTO, "FileSource", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA301, AUTO, "SceneType", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xA302, AUTO, "CFAPattern", &cfaInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA401, AUTO, "CustomRendered", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA402, AUTO, "ExposureMode", &exposureModeInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA403, AUTO, "WhiteBalance", &whiteBalanceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA404, AUTO, "DigitalZoomRatio", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA405, AUTO, "FocalLengthIn35mmFilm", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA406, AUTO, "SceneCaptureType", &sceneCaptureInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA407, AUTO, "GainControl", &gainControlInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA408, AUTO, "Contrast", &contrastInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA409, AUTO, "Saturation", &saturationInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA40A, AUTO, "Sharpness", &sharpnessInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA40B, AUTO, "DeviceSettingDescription", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA40C, AUTO, "SubjectDistanceRange", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA420, AUTO, "ImageUniqueID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA431, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA432, AUTO, "LensInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA433, AUTO, "LensMake", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA434, AUTO, "LensModel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA435, AUTO, "LensSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xA500, AUTO, "Gamma", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC618, AUTO, "LinearizationTable", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC619, AUTO, "BlackLevelRepeatDim", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61A, AUTO, "BlackLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61B, AUTO, "BlackLevelDeltaH", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61C, AUTO, "BlackLevelDeltaV", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61D, AUTO, "WhiteLevel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61E, AUTO, "DefaultScale", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC61F, AUTO, "DefaultCropOrigin", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC620, AUTO, "DefaultCropSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC621, AUTO, "ColorMatrix1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC622, AUTO, "ColorMatrix2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC623, AUTO, "CameraCalibration1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC624, AUTO, "CameraCalibration2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC625, AUTO, "ReductionMatrix1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC626, AUTO, "ReductionMatrix2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC627, AUTO, "AnalogBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC628, AUTO, "AsShotNeutral", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC629, AUTO, "AsShotWhiteXY", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62A, AUTO, "BaselineExposure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62B, AUTO, "BaselineNoise", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62C, AUTO, "BaselineSharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62D, AUTO, "BayerGreenSplit", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62E, AUTO, "LinearResponseLimit", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC62F, AUTO, "CameraSerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC630, AUTO, "DNGLensInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC631, AUTO, "ChromaBlurRadius", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC632, AUTO, "AntiAliasStrength", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC633, AUTO, "ShadowScale", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC65A, AUTO, "CalibrationIlluminant1", &lightSourceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC65B, AUTO, "CalibrationIlluminant2", &lightSourceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC65C, AUTO, "BestQualityScale", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC65D, AUTO, "RawDataUniqueID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC68B, AUTO, "OriginalRawFileName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC68D, AUTO, "ActiveArea", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC68E, AUTO, "MaskedAreas", &stdInterpreter}, -// {0, AC_WRITE, 0, nullptr, 0xC68F, AUTO, "AsShotICCProfile", & ???}, - {0, AC_WRITE, 0, nullptr, 0xC690, AUTO, "AsShotPreProfileMatrix", &stdInterpreter}, -// {0, AC_WRITE, 0, nullptr, 0xC691, AUTO, "CurrentICCProfile", & ???}, - {0, AC_WRITE, 0, nullptr, 0xC692, AUTO, "CurrentPreProfileMatrix", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6BF, AUTO, "ColorimetricReference", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F3, AUTO, "CameraCalibrationSig", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F4, AUTO, "ProfileCalibrationSig", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F5, AUTO, "ProfileIFD", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F6, AUTO, "AsShotProfileName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F7, AUTO, "NoiseReductionApplied", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F8, AUTO, "ProfileName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6F9, AUTO, "ProfileHueSatMapDims", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6FA, AUTO, "ProfileHueSatMapData1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6FB, AUTO, "ProfileHueSatMapData2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6FC, AUTO, "ProfileToneCurve", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6FD, AUTO, "ProfileEmbedPolicy", &profileEmbedPolicyInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC6FE, AUTO, "ProfileCopyright", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC714, AUTO, "ForwardMatrix1", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC715, AUTO, "ForwardMatrix2", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC716, AUTO, "PreviewApplicationName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC717, AUTO, "PreviewApplicationVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC718, AUTO, "PreviewSettingsName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC719, AUTO, "PreviewSettingsDigest", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC71A, AUTO, "PreviewColorSpace", &previewColorSpaceInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC71B, AUTO, "PreviewDateTime", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC71C, AUTO, "RawImageDigest", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC71D, AUTO, "OriginalRawFileDigest", &stdInterpreter}, -// {0, AC_WRITE, 0, nullptr, 0xC71E, AUTO, "SubTileBlockSize", & ???}, -// {0, AC_WRITE, 0, nullptr, 0xC71F, AUTO, "RowInterleaveFactor", & ???}, - {0, AC_WRITE, 0, nullptr, 0xC725, AUTO, "ProfileLookTableDims", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC726, AUTO, "ProfileLookTableData", &stdInterpreter}, -// {0, AC_WRITE, 0, nullptr, 0xC740, AUTO, "OpcodeList1", & ???}, -// {0, AC_WRITE, 0, nullptr, 0xC741, AUTO, "OpcodeList2", & ???}, -// {0, AC_WRITE, 0, nullptr, 0xC74E, AUTO, "OpcodeList3", & ???}, - {0, AC_WRITE, 0, nullptr, 0xC761, AUTO, "NoiseProfile", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC763, AUTO, "TimeCodes", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC764, AUTO, "FrameRate", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC772, AUTO, "TStop", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC789, AUTO, "ReelName", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC791, AUTO, "OriginalDefaultFinalSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC792, AUTO, "OriginalBestQualitySize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC793, AUTO, "OriginalDefaultCropSize", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A1, AUTO, "CameraLabel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A3, AUTO, "ProfileHueSatMapEncoding", &linearSRGBInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A4, AUTO, "ProfileLookTableEncoding", &linearSRGBInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A5, AUTO, "BaselineExposureOffset", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A6, AUTO, "DefaultBlackRender", &defaultBlackRenderInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A7, AUTO, "NewRawImageDigest", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7A8, AUTO, "RawToPreviewGain", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC7B5, AUTO, "DefaultUserCrop", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFDE9, AUTO, "SerialNumber", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFDEA, AUTO, "Lens", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE4C, AUTO, "RawFile", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE4D, AUTO, "Converter", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE4E, AUTO, "WhiteBalance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE51, AUTO, "Exposure", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE52, AUTO, "Shadows", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE53, AUTO, "Brightness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE54, AUTO, "Contrast", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE55, AUTO, "Saturation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE56, AUTO, "Sharpness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE57, AUTO, "Smoothness", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xFE58, AUTO, "MoireFilter", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - - -const TagAttrib gpsAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0000, AUTO, "GPSVersionID", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "GPSLatitudeRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "GPSLatitude", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "GPSLongitudeRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "GPSLongitude", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "GPSAltitudeRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "GPSAltitude", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "GPSTimeStamp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0008, AUTO, "GPSSatelites", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0009, AUTO, "GPSStatus", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000a, AUTO, "GPSMeasureMode", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000b, AUTO, "GPSDOP", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000c, AUTO, "GPSSpeedRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000d, AUTO, "GPSSpeed", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000e, AUTO, "GPSTrackRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "GPSTrack", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0010, AUTO, "GPSImgDirectionRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0011, AUTO, "GPSImgDirection", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "GPSMapDatum", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0013, AUTO, "GPSDestLatitudeRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0014, AUTO, "GPSDestLatitude", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0015, AUTO, "GPSDestLongitudeRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0016, AUTO, "GPSDestLongitude", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0017, AUTO, "GPSDestBearingRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0018, AUTO, "GPSDestBearing", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0019, AUTO, "GPSDestDistanceRef", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001a, AUTO, "GPSDestDistance", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001b, AUTO, "GPSProcessingMethod", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001c, AUTO, "GPSAreaInformation", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001d, AUTO, "GPSDateStamp", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x001e, AUTO, "GPSDifferential", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - -const TagAttrib iopAttribs[] = { - {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "InteroperabilityIndex", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "InteroperabilityVersion", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } -}; - -const TagAttrib ifdAttribs[] = { - {0, AC_SYSTEM, 0, nullptr, 0x0017, AUTO, "PanaISO", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x00fe, AUTO, "NewSubFileType", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0103, AUTO, "Compression", &compressionInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0106, AUTO, "PhotometricInterpretation", &photometricInterpreter}, - {0, AC_WRITE, 1, nullptr, 0x010E, AUTO, "ImageDescription", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x010F, AUTO, "Make", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0110, AUTO, "Model", &stdInterpreter}, - {1, AC_DONTWRITE, 0, nullptr, 0x0111, AUTO, "StripOffsets", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0112, AUTO, "Orientation", &orientationInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0115, AUTO, "SamplesPerPixel", &stdInterpreter}, - {1, AC_DONTWRITE, 0, nullptr, 0x0116, AUTO, "RowsPerStrip", &stdInterpreter}, - {1, AC_DONTWRITE, 0, nullptr, 0x0117, AUTO, "StripByteCounts", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x011A, AUTO, "XResolution", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x011B, AUTO, "YResolution", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x011C, AUTO, "PlanarConfiguration", &planarConfigInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0128, AUTO, "ResolutionUnit", &unitsInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x012D, AUTO, "TransferFunction", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0131, AUTO, "Software", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x0132, AUTO, "DateTime", &stdInterpreter}, - {0, AC_WRITE, 1, nullptr, 0x013B, AUTO, "Artist", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x013E, AUTO, "WhitePoint", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x013F, AUTO, "PriomaryChromaticities", &stdInterpreter}, - {0, AC_WRITE, 0, ifdAttribs, 0x014A, AUTO, "SubIFD", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0153, AUTO, "SampleFormat", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0201, AUTO, "JPEGInterchangeFormat", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0202, AUTO, "JPEGInterchangeFormatLength", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0211, AUTO, "YCbCrCoefficients", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0212, AUTO, "YCbCrSubSampling", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0213, AUTO, "YCbCrPositioning", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x0214, AUTO, "ReferenceBlackWhite", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x02bc, AUTO, "ApplicationNotes", &utf8BinInterpreter}, // XMP - {0, AC_WRITE, 0, nullptr, 0x4746, AUTO, "Rating", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x4749, AUTO, "RatingPercent", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, - {0, AC_WRITE, 0, kodakIfdAttribs, 0x8290, AUTO, "KodakIFD", &stdInterpreter}, - {0, AC_WRITE, 1, nullptr, 0x8298, AUTO, "Copyright", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x83BB, AUTO, "IPTCData", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0x8606, AUTO, "LeafData", &stdInterpreter}, // is actually a subdir, but a proprietary format - {0, AC_WRITE, 0, exifAttribs, 0x8769, AUTO, "Exif", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x8773, AUTO, "ICCProfile", &stdInterpreter}, - {0, AC_WRITE, 0, gpsAttribs, 0x8825, AUTO, "GPSInfo", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9003, AUTO, "DateTimeOriginal", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9004, AUTO, "DateTimeDigitized", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0x9211, AUTO, "ImageNumber", &stdInterpreter}, - {0, AC_WRITE, 0, iopAttribs, 0xA005, AUTO, "Interoperability", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xC4A5, AUTO, "PrintIMInformation", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xC612, AUTO, "DNGVersion", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xC613, AUTO, "DNGBackwardVersion", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC614, AUTO, "UniqueCameraModel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xC615, AUTO, "LocalizedCameraModel", &stdInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xc62f, AUTO, "CameraSerialNumber", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0xc630, AUTO, "DNGLensInfo", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xC634, AUTO, "MakerNote", &stdInterpreter}, //DNGPrivateData - {0, AC_SYSTEM, 0, nullptr, 0xC640, AUTO, "RawImageSegmentation", &rawImageSegmentationInterpreter}, - {0, AC_WRITE, 0, nullptr, 0xc65d, AUTO, "RawDataUniqueID", &stdInterpreter}, - {0, AC_DONTWRITE, 0, nullptr, 0xc761, AUTO, "NoiseProfile", &stdInterpreter}, - { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} -}; -} - -#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 3af955be8..ab58a73f9 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -186,7 +186,7 @@ if(WIN32) ${LENSFUN_INCLUDE_DIRS} ${RSVG_INCLUDE_DIRS} ) - link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" + link_directories(. ${EXTRA_LIBDIR} ${GIOMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 35aeb6c91..032a3a4f0 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -303,7 +303,3 @@ int CacheImageData::save (const Glib::ustring& fname) } } -rtengine::procparams::IPTCPairs CacheImageData::getIPTCData(unsigned int frame) const -{ - return {}; -} diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index d3aea803b..397bc1c48 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -87,30 +87,26 @@ public: // FramesMetaData interface //------------------------------------------------------------------------- - unsigned int getRootCount () const override { return -1; } + /* unsigned int getRootCount () const override { return -1; } */ unsigned int getFrameCount () const override { return frameCount; } - bool hasExif (unsigned int frame = 0) const override { return false; } - rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const override { return nullptr; } - rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const override { return nullptr; } - rtexif::TagDirectory* getBestExifData (rtengine::ImageSource *imgSource, rtengine::procparams::RAWParams *rawParams) const override { return nullptr; } - bool hasIPTC (unsigned int frame = 0) const override { return false; } - rtengine::procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const override; - tm getDateTime (unsigned int frame = 0) const override { return tm{}; } - time_t getDateTimeAsTS(unsigned int frame = 0) const override { return time_t(-1); } - int getISOSpeed (unsigned int frame = 0) const override { return iso; } - double getFNumber (unsigned int frame = 0) const override { return fnumber; } - double getFocalLen (unsigned int frame = 0) const override { return focalLen; } - double getFocalLen35mm (unsigned int frame = 0) const override { return focalLen35mm; } - float getFocusDist (unsigned int frame = 0) const override { return focusDist; } - double getShutterSpeed (unsigned int frame = 0) const override { return shutter; } - double getExpComp (unsigned int frame = 0) const override { return atof(expcomp.c_str()); } - std::string getMake (unsigned int frame = 0) const override { return camMake; } - std::string getModel (unsigned int frame = 0) const override { return camModel; } - std::string getLens (unsigned int frame = 0) const override { return lens; } - std::string getOrientation (unsigned int frame = 0) const override { return ""; } // TODO + bool hasExif() const override { return false; } + tm getDateTime() const override { return tm{}; } + time_t getDateTimeAsTS() const override { return time_t(-1); } + int getISOSpeed() const override { return iso; } + double getFNumber() const override { return fnumber; } + double getFocalLen() const override { return focalLen; } + double getFocalLen35mm() const override { return focalLen35mm; } + float getFocusDist() const override { return focusDist; } + double getShutterSpeed() const override { return shutter; } + double getExpComp() const override { return atof(expcomp.c_str()); } + std::string getMake() const override { return camMake; } + std::string getModel() const override { return camModel; } + std::string getLens() const override { return lens; } + std::string getOrientation() const override { return ""; } // TODO + Glib::ustring getFileName() const override { return ""; } bool getPixelShift () const override { return isPixelShift; } - bool getHDR (unsigned int frame = 0) const override { return isHDR; } - std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } - rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const override { return sampleFormat; } + bool getHDR() const override { return isHDR; } + std::string getImageType() const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } + rtengine::IIOSampleFormat getSampleFormat() const override { return sampleFormat; } }; #endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index a58e28bef..30c9d7e27 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1329,16 +1329,16 @@ void EditorPanel::info_toggled () const rtengine::FramesMetaData* idata = ipc->getInitialImage()->getMetaData(); - if (idata && idata->hasExif(selectedFrame)) { + if (idata && idata->hasExif()) { infoString = Glib::ustring::compose ("%1 + %2\nf/%3 %4s %5%6 %7mm", Glib::ustring (idata->getMake() + " " + idata->getModel()), Glib::ustring (idata->getLens()), - Glib::ustring (idata->apertureToString (idata->getFNumber(selectedFrame))), - Glib::ustring (idata->shutterToString (idata->getShutterSpeed(selectedFrame))), - M ("QINFO_ISO"), idata->getISOSpeed(selectedFrame), - Glib::ustring::format (std::setw (3), std::fixed, std::setprecision (2), idata->getFocalLen(selectedFrame))); + Glib::ustring (idata->apertureToString (idata->getFNumber())), + Glib::ustring (idata->shutterToString (idata->getShutterSpeed())), + M ("QINFO_ISO"), idata->getISOSpeed(), + Glib::ustring::format (std::setw (3), std::fixed, std::setprecision (2), idata->getFocalLen())); - expcomp = Glib::ustring (idata->expcompToString (idata->getExpComp(selectedFrame), true)); // maskZeroexpcomp + expcomp = Glib::ustring (idata->expcompToString (idata->getExpComp(), true)); // maskZeroexpcomp if (!expcomp.empty ()) { infoString = Glib::ustring::compose ("%1 %2EV", @@ -1366,7 +1366,7 @@ void EditorPanel::info_toggled () if (isHDR) { infoString = Glib::ustring::compose ("%1\n" + M("QINFO_HDR"), infoString, numFrames); if (numFrames == 1) { - int sampleFormat = idata->getSampleFormat(selectedFrame); + int sampleFormat = idata->getSampleFormat(); infoString = Glib::ustring::compose ("%1 / %2", infoString, M(Glib::ustring::compose("SAMPLEFORMAT_%1", sampleFormat))); } } else if (isPixelShift) { diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index c5036798e..661118e32 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -21,20 +21,25 @@ #include "guiutils.h" #include "rtimage.h" #include "options.h" +#include "../rtengine/imagedata.h" #include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; -using namespace rtexif; ExifPanel::ExifPanel() : idata(nullptr), changeList(new rtengine::procparams::ExifPairs), defChangeList(new rtengine::procparams::ExifPairs) { - recursiveOp = true; - + editable_ = { + { "Exif.Photo.UserComment", "User Comment" }, + { "Exif.Image.Artist", "Artist" }, + { "Exif.Image.Copyright", "Copyright" }, + { "Exif.Image.ImageDescription", "Image Description"} + }; + exifTree = Gtk::manage (new Gtk::TreeView()); scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); @@ -51,11 +56,10 @@ ExifPanel::ExifPanel() : exifTreeModel = Gtk::TreeStore::create (exifColumns); exifTree->set_model (exifTreeModel); 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"); + exifTree->set_show_expanders(false); + keepicon = RTImage::createPixbufFromFile ("tick-small.png"); - editicon = RTImage::createPixbufFromFile ("add-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 ()); @@ -64,7 +68,7 @@ ExifPanel::ExifPanel() : viewcol->pack_start (*render_pb, false); viewcol->pack_start (*render_txt, true); viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon); - viewcol->add_attribute (*render_txt, "markup", exifColumns.field); + viewcol->add_attribute (*render_txt, "markup", exifColumns.label); viewcol->set_expand (true); viewcol->set_resizable (true); viewcol->set_fixed_width (35); @@ -99,24 +103,6 @@ ExifPanel::ExifPanel() : buttons1->set_row_homogeneous (true); buttons1->set_column_homogeneous (true); setExpandAlignProperties (buttons1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - Gtk::Grid* buttons2 = Gtk::manage (new Gtk::Grid()); - buttons2->set_row_homogeneous (true); - buttons2->set_column_homogeneous (true); - setExpandAlignProperties (buttons2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - remove = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_REMOVE") - remove->set_image (*Gtk::manage (new RTImage(delicon))); - remove->set_tooltip_text (M ("EXIFPANEL_REMOVEHINT")); - remove->get_style_context()->add_class ("Left"); - setExpandAlignProperties (remove, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to (*remove, Gtk::POS_LEFT, 1, 1); - - keep = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_KEEP") - keep->set_image (*Gtk::manage (new RTImage(keepicon))); - keep->set_tooltip_text (M ("EXIFPANEL_KEEPHINT")); - keep->get_style_context()->add_class ("MiddleH"); - setExpandAlignProperties (keep, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to (*keep, Gtk::POS_RIGHT, 1, 1); add = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_ADDEDIT") add->set_image (*Gtk::manage (new RTImage(editicon))); @@ -125,178 +111,152 @@ ExifPanel::ExifPanel() : setExpandAlignProperties (add, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); buttons1->attach_next_to (*add, Gtk::POS_RIGHT, 1, 1); - showAll = Gtk::manage (new Gtk::ToggleButton (M ("EXIFPANEL_SHOWALL"))); - //add->set_tooltip_text (M("EXIFPANEL_SHOWALL")); - showAll->get_style_context()->add_class ("Left"); - setExpandAlignProperties (showAll, false, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - showAll->set_active (options.lastShowAllExif); - buttons2->attach_next_to (*showAll, Gtk::POS_LEFT, 1, 1); - reset = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESET") reset->set_image (*Gtk::manage (new RTImage("undo.png", "redo.png"))); reset->set_tooltip_text (M ("EXIFPANEL_RESETHINT")); reset->get_style_context()->add_class ("MiddleH"); setExpandAlignProperties (reset, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons2->attach_next_to (*reset, Gtk::POS_RIGHT, 1, 1); + buttons1->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_tooltip_text (M ("EXIFPANEL_RESETALLHINT")); resetAll->get_style_context()->add_class ("Right"); setExpandAlignProperties (resetAll, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons2->attach_next_to (*resetAll, Gtk::POS_RIGHT, 1, 1); + buttons1->attach_next_to (*resetAll, Gtk::POS_RIGHT, 1, 1); - pack_end (*buttons2, Gtk::PACK_SHRINK); pack_end (*buttons1, Gtk::PACK_SHRINK); exifTree->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ExifPanel::exifSelectionChanged)); - exifTree->signal_row_activated().connect (sigc::mem_fun (*this, &ExifPanel::row_activated)); + // exifTree->signal_row_activated().connect (sigc::mem_fun (*this, &ExifPanel::row_activated)); - remove->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::removePressed) ); - keep->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::keepPressed) ); reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) ); resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) ); add->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::addPressed) ); - showAll->signal_toggled().connect ( sigc::mem_fun (*this, &ExifPanel::showAlltoggled) ); show_all (); } + ExifPanel::~ExifPanel () { } + void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); *changeList = pp->exif; setImageData (idata); - applyChangeList (); - exifSelectionChanged (); + refreshTags(); enableListener (); } + void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) { - -// updateChangeList (); pp->exif = *changeList; } + void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { *defChangeList = defParams->exif; } + void ExifPanel::setImageData (const FramesMetaData* id) { idata = id; - exifTreeModel->clear (); - - if (idata) { - for (unsigned int rootNum = 0; rootNum < id->getRootCount (); ++rootNum) { - if ( id->getRootExifData (rootNum)) { - addDirectory (id->getRootExifData (rootNum), exifTreeModel->children(), rootNum > 0); - } - } - } } -Gtk::TreeModel::Children ExifPanel::addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, rtexif::ActionCode action, bool editable) + +Gtk::TreeModel::Children ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited) { + auto root = exifTreeModel->children(); Gtk::TreeModel::Row row = * (exifTreeModel->append (root)); - row[exifColumns.action] = action; row[exifColumns.editable] = editable; - row[exifColumns.edited] = false; - row[exifColumns.field_nopango] = field; + row[exifColumns.edited] = edited; + row[exifColumns.key] = key; + row[exifColumns.label] = label; row[exifColumns.value_nopango] = value; - row[exifColumns.orig_value] = value; + row[exifColumns.value] = value; - if (action == AC_WRITE) { + row[exifColumns.label] = escapeHtmlChars(label); + row[exifColumns.value] = escapeHtmlChars(value); + + if (edited) { + row[exifColumns.icon] = editicon; + } else if (editable) { row[exifColumns.icon] = keepicon; - } else if (action == AC_DONTWRITE) { - row[exifColumns.icon] = delicon; - } - - if (editable) { - row[exifColumns.field] = Glib::ustring ("") + escapeHtmlChars (field) + ""; - row[exifColumns.value] = Glib::ustring ("") + escapeHtmlChars (value) + ""; - } else if (action == AC_SYSTEM) { - row[exifColumns.field] = Glib::ustring ("") + escapeHtmlChars (field) + ""; - row[exifColumns.value] = Glib::ustring ("") + escapeHtmlChars (value) + ""; - } else { - row[exifColumns.field] = escapeHtmlChars (field); - row[exifColumns.value] = escapeHtmlChars (value); } return row.children(); } -Gtk::TreeModel::Children ExifPanel::addSeparator () + +void ExifPanel::refreshTags() { + Glib::RefPtr selection = exifTree->get_selection(); + std::vector sel = selection->get_selected_rows(); + + exifTreeModel->clear(); + + if (!idata) { + return; + } - Gtk::TreeModel::Row row = * (exifTreeModel->append (exifTreeModel->children())); - row[exifColumns.action] = rtexif::ActionCode::AC_INVALID; - row[exifColumns.editable] = false; - row[exifColumns.edited] = false; - row[exifColumns.field_nopango] = ""; - row[exifColumns.value_nopango] = ""; - row[exifColumns.orig_value] = ""; - row[exifColumns.isSeparator] = true; + Glib::ustring fn = idata->getFileName(); + if (fn.empty()) { + return; + } - return row.children(); -} - -void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root, bool checkForSeparator) -{ - - for (int i = 0; i < dir->getCount(); ++i) { - Tag* t = (const_cast (dir))->getTagByIndex (i); - - bool hasContent = false; - - if (checkForSeparator && i == 0) { - for (int j = 0; j < dir->getCount(); ++j) { - Tag* t2 = (const_cast (dir))->getTagByIndex (j); - const TagAttrib* currAttrib = t2->getAttrib(); - - if (currAttrib && (options.lastShowAllExif || currAttrib->action != AC_SYSTEM)) { - addSeparator(); - hasContent = true; - break; - } + std::unordered_set ed; + for (auto &p : editable_) { + ed.insert(p.first); + } + + try { + auto img = open_exiv2(fn); + img->readMetadata(); + auto &exif = img->exifData(); + + for (auto &p : *changeList) { + try { + exif[p.first] = p.second; + } catch (Exiv2::AnyError &exc) { } - } else { - hasContent = true; } - if (!hasContent) { - return; - } - - const TagAttrib* currAttrib = t->getAttrib(); - - if (!options.lastShowAllExif && currAttrib && currAttrib->action == AC_SYSTEM) { - continue; - } - - if (t->isDirectory()) { - for (int j = 0; t->getDirectory (j); j++) { - Gtk::TreeModel::Children ch = addTag (root, t->nameToString (j), M ("EXIFPANEL_SUBDIRECTORY"), currAttrib ? currAttrib->action : AC_DONTWRITE, currAttrib && currAttrib->editable); - addDirectory (t->getDirectory (j), ch); + for (auto &p : editable_) { + auto pos = exif.findKey(Exiv2::ExifKey(p.first)); + if (pos != exif.end() && pos->size()) { + bool edited = changeList->find(pos->key()) != changeList->end(); + addTag(pos->key(), pos->tagLabel(), pos->print(&exif), true, edited); } - } else { - addTag (root, t->nameToString (), t->valueToString (), currAttrib ? (t->getOwnMemory() ? currAttrib->action : AC_SYSTEM) : AC_DONTWRITE, currAttrib && currAttrib->editable); } + for (auto &tag : exif) { + bool editable = ed.find(tag.key()) != ed.end(); + if (!editable && !tag.tagLabel().empty() && tag.typeId() != Exiv2::undefined && + (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { + addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); + } + } + } catch (Exiv2::AnyError &exc) { + return; + } + + for (auto &p : sel) { + exifTree->get_selection()->select(p); } } + void ExifPanel::exifSelectionChanged () { @@ -304,170 +264,53 @@ void ExifPanel::exifSelectionChanged () std::vector sel = selection->get_selected_rows(); if (sel.size() > 1) { - remove->set_sensitive (1); - keep->set_sensitive (1); reset->set_sensitive (1); } else if (sel.size() == 1) { Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (sel[0]); - if (iter->get_value (exifColumns.action) == AC_SYSTEM) { - remove->set_sensitive (0); - keep->set_sensitive (0); - reset->set_sensitive (0); - } else if (!iter->children().empty()) { - remove->set_sensitive (1); - keep->set_sensitive (1); - reset->set_sensitive (1); - } else if (iter->get_value (exifColumns.icon) == delicon) { - remove->set_sensitive (0); - keep->set_sensitive (1); - reset->set_sensitive (1); - } else if (iter->get_value (exifColumns.icon) == keepicon || iter->get_value (exifColumns.icon) == editicon) { - keep->set_sensitive (0); - remove->set_sensitive (1); + if (iter->get_value(exifColumns.icon) == editicon) { reset->set_sensitive (1); } } else { - remove->set_sensitive (0); - keep->set_sensitive (0); reset->set_sensitive (0); } } -void ExifPanel::delIt (Gtk::TreeModel::iterator iter) -{ +void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) +{ if (!iter) { return; } - if (iter->get_value (exifColumns.action) != AC_SYSTEM) { - iter->set_value (exifColumns.icon, delicon); - } - - if (recursiveOp) - for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); ++i) { - delIt (i); - } + auto key = iter->get_value(exifColumns.key); + changeList->erase(key); } -void ExifPanel::removePressed () -{ - std::vector sel = exifTree->get_selection()->get_selected_rows(); - - for (size_t i = 0; i < sel.size(); i++) { - delIt (exifTreeModel->get_iter (sel[i])); - } - - exifSelectionChanged (); - updateChangeList (); - notifyListener (); -} - -void ExifPanel::keepIt (Gtk::TreeModel::iterator iter) -{ - - if (!iter) { - return; - } - - if (iter->get_value (exifColumns.action) != AC_SYSTEM) { - iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); - } - - if (recursiveOp) - for (Gtk::TreeModel::iterator i = iter->children().begin(); i != iter->children().end(); ++i) { - keepIt (i); - } -} - -void ExifPanel::keepPressed () -{ - - std::vector sel = exifTree->get_selection()->get_selected_rows(); - - for (size_t i = 0; i < sel.size(); i++) { - keepIt (exifTreeModel->get_iter (sel[i])); - } - - exifSelectionChanged (); - updateChangeList (); - notifyListener (); -} - -/*void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) { - - if (!iter) - return; - - if (iter->get_value (exifColumns.action)!=AC_SYSTEM) - iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); - if (iter->get_value (exifColumns.edited)) { - iter->set_value (exifColumns.value, Glib::ustring("") + iter->get_value(exifColumns.orig_value) + ""); - iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value)); - iter->set_value (exifColumns.edited, false); - } - if (iter->get_value (exifColumns.action)==AC_INVALID) - exifTreeModel->erase (iter); - else - if (recursiveOp) - for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) - resetIt (i); -}*/ -Gtk::TreeModel::iterator ExifPanel::resetIt (Gtk::TreeModel::iterator iter) -{ - - if (!iter) { - return iter; - } - - if (iter->get_value (exifColumns.action) != AC_SYSTEM) { - iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); - } - - if (iter->get_value (exifColumns.edited)) { - iter->set_value (exifColumns.value, Glib::ustring ("") + iter->get_value (exifColumns.orig_value) + ""); - iter->set_value (exifColumns.value_nopango, iter->get_value (exifColumns.orig_value)); - iter->set_value (exifColumns.edited, false); - } - - if (iter->get_value (exifColumns.action) == AC_INVALID) { - return exifTreeModel->erase (iter); - } else if (recursiveOp) { - Gtk::TreeModel::iterator i = iter->children().begin(); - - while (i && i != iter->children().end()) { - i = resetIt (i); - } - } - - return ++iter; -} void ExifPanel::resetPressed () { std::vector sel = exifTree->get_selection()->get_selected_rows(); for (size_t i = 0; i < sel.size(); i++) { - resetIt (exifTreeModel->get_iter (sel[i])); + resetIt(exifTreeModel->get_iter(sel[i])); } - exifSelectionChanged (); - updateChangeList (); - notifyListener (); + refreshTags(); + notifyListener(); } + void ExifPanel::resetAllPressed () { - - setImageData (idata); + setImageData(idata); *changeList = *defChangeList; - applyChangeList (); - exifSelectionChanged (); + refreshTags(); notifyListener (); } + void ExifPanel::addPressed () { @@ -481,10 +324,9 @@ void ExifPanel::addPressed () Gtk::Label* tlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_SELECTTAG") + ":"); MyComboBoxText* tcombo = new MyComboBoxText (); - tcombo->append ("Artist"); - tcombo->append ("Copyright"); - tcombo->append ("ImageDescription"); - tcombo->append ("Exif.UserComment"); + for (auto &p : editable_) { + tcombo->append(p.second); + } hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4); hb1->pack_start (*tcombo); @@ -494,21 +336,33 @@ void ExifPanel::addPressed () hb2->pack_start (*vlabel, Gtk::PACK_SHRINK, 4); hb2->pack_start (*ventry); - Glib::ustring sel = getSelection (true); + Glib::ustring sel; + Glib::ustring val; + { + Glib::RefPtr selection = exifTree->get_selection(); + std::vector rows = selection->get_selected_rows(); - if (sel == "") { - tcombo->set_active_text ("Exif.UserComment"); - } else { - tcombo->set_active_text (sel); - - if (!tcombo->get_active ()) { - tcombo->append (sel); - tcombo->set_active_text (sel); + if (rows.size() == 1) { + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter(rows[0]); + if (iter->get_value(exifColumns.editable)) { + sel = iter->get_value(exifColumns.key); + val = iter->get_value(exifColumns.value_nopango); + } } - - ventry->set_text (getSelectedValue ()); } + if (sel == "") { + tcombo->set_active(0); + } else { + for (size_t i = 0; i < editable_.size(); ++i) { + if (editable_[i].first == sel) { + tcombo->set_active(i); + break; + } + } + } + + ventry->set_text(val); ventry->set_activates_default (true); dialog->set_default_response (Gtk::RESPONSE_OK); dialog->get_content_area()->pack_start (*hb1, Gtk::PACK_SHRINK); @@ -521,8 +375,10 @@ void ExifPanel::addPressed () hb2->show (); if (dialog->run () == Gtk::RESPONSE_OK) { - editTag (exifTreeModel->children(), tcombo->get_active_text(), ventry->get_text()); - updateChangeList (); + auto key = editable_[tcombo->get_active_row_number()].first; + auto value = ventry->get_text(); + (*changeList)[key] = value; + refreshTags(); notifyListener (); } @@ -535,186 +391,9 @@ void ExifPanel::addPressed () delete hb2; } -void ExifPanel::showAlltoggled () -{ - options.lastShowAllExif = showAll->get_active(); - setImageData (idata); -} - -bool ExifPanel::rowSeperatorFunc(const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) -{ - return iter->get_value(exifColumns.isSeparator); -} - -void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value) -{ - - Glib::ustring::size_type dp = name.find_first_of ('.'); - Glib::ustring fseg = name.substr (0, dp); - // look up first segment of the path - Gtk::TreeModel::iterator iter; - - for (iter = root.begin(); iter != root.end(); ++iter) - if (iter->get_value (exifColumns.field_nopango) == fseg) { - break; - } - - if (iter == root.end() && value != "#keep" && value != "#delete") { - iter = exifTreeModel->append (root); - iter->set_value (exifColumns.field_nopango, fseg); - iter->set_value (exifColumns.action, AC_INVALID); - - if (dp == Glib::ustring::npos) { - iter->set_value (exifColumns.value, Glib::ustring ("") + value + ""); - iter->set_value (exifColumns.value_nopango, value); - iter->set_value (exifColumns.orig_value, value); - iter->set_value (exifColumns.field, Glib::ustring ("") + fseg + ""); - iter->set_value (exifColumns.edited, true); - iter->set_value (exifColumns.editable, true); - iter->set_value (exifColumns.icon, editicon); - } else { - iter->set_value (exifColumns.value, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); - iter->set_value (exifColumns.value_nopango, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); - iter->set_value (exifColumns.field, fseg); - iter->set_value (exifColumns.icon, keepicon); - iter->set_value (exifColumns.orig_value, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); - } - } - - if (iter == root.end()) { - return; - } - - if (dp == Glib::ustring::npos) { - if (value == "#keep" && iter->get_value (exifColumns.action) != AC_SYSTEM) { - iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); - } else if (value == "#delete" && iter->get_value (exifColumns.action) != AC_SYSTEM) { - iter->set_value (exifColumns.icon, delicon); - } else { - iter->set_value (exifColumns.value, Glib::ustring ("") + value + ""); - iter->set_value (exifColumns.value_nopango, value); - iter->set_value (exifColumns.edited, true); - iter->set_value (exifColumns.icon, editicon); - } - } else { - editTag (iter->children(), name.substr (dp + 1, Glib::ustring::npos), value); - } -} - -Glib::ustring ExifPanel::getSelectedValue () -{ - - Glib::RefPtr selection = exifTree->get_selection(); - std::vector rows = selection->get_selected_rows(); - - if (rows.size() != 1) { - return ""; - } - - Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); - - if (iter) { - return iter->get_value (exifColumns.value_nopango); - } - - return ""; -} - -Glib::ustring ExifPanel::getSelection (bool onlyeditable) -{ - - Glib::RefPtr selection = exifTree->get_selection(); - std::vector rows = selection->get_selected_rows(); - - if (rows.size() != 1) { - return ""; - } - - Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); - - Glib::ustring ret = ""; - bool first = true; - bool editable = false; - - while (iter) { - if (first) { - ret = iter->get_value (exifColumns.field_nopango); - editable = iter->get_value (exifColumns.editable); - } else { - ret = iter->get_value (exifColumns.field_nopango) + "." + ret; - } - - iter = iter->parent (); - first = false; - } - - if (!editable && onlyeditable) { - return ""; - } - - return ret; -} - -void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string prefix) -{ - - if (prefix != "") { - prefix = prefix + "."; - } - - Gtk::TreeModel::iterator iter; - - for (iter = root.begin(); iter != root.end(); ++iter) { - if (iter->get_value (exifColumns.edited)) { - (*changeList)[ prefix + iter->get_value (exifColumns.field_nopango) ] = iter->get_value (exifColumns.value_nopango); - } else if (iter->get_value (exifColumns.action) == AC_WRITE && iter->get_value (exifColumns.icon) == delicon) { - (*changeList)[ prefix + iter->get_value (exifColumns.field_nopango) ] = "#delete"; - } else if (iter->get_value (exifColumns.action) == AC_DONTWRITE && iter->get_value (exifColumns.icon) == keepicon) { - (*changeList)[ prefix + iter->get_value (exifColumns.field_nopango) ] = "#keep"; - } - - if (iter->get_value (exifColumns.icon) == keepicon) { - updateChangeList (iter->children(), prefix + iter->get_value (exifColumns.field_nopango)); - } - } -} - -void ExifPanel::updateChangeList () -{ - - changeList->clear (); - updateChangeList (exifTreeModel->children(), ""); -} - -void ExifPanel::applyChangeList () -{ - - for (rtengine::procparams::ExifPairs::const_iterator i = changeList->begin(); i != changeList->end(); ++i) { - editTag (exifTreeModel->children(), i->first, i->second); - } -} - -void ExifPanel::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) -{ - - Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (path); - - if (iter) { - if (!iter->children().empty()) - if (exifTree->row_expanded (path)) { - exifTree->collapse_row (path); - } else { - exifTree->expand_row (path, false); - } else if (iter->get_value (exifColumns.editable)) { - addPressed (); - } - } -} - void ExifPanel::notifyListener () { - if (listener) { listener->panelChanged (EvExif, M ("HISTORY_CHANGED")); } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index c8597a287..97708ab7b 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -20,8 +20,8 @@ #define _EXIFPANEL_ #include - #include +#include #include "toolpanel.h" @@ -32,37 +32,29 @@ private: const rtengine::FramesMetaData* idata; const std::unique_ptr changeList; const std::unique_ptr defChangeList; - bool recursiveOp; class ExifColumns : public Gtk::TreeModelColumnRecord { public: Gtk::TreeModelColumn > icon; - Gtk::TreeModelColumn field; - Gtk::TreeModelColumn field_nopango; + Gtk::TreeModelColumn key; + Gtk::TreeModelColumn label; Gtk::TreeModelColumn value; Gtk::TreeModelColumn value_nopango; - Gtk::TreeModelColumn orig_value; - Gtk::TreeModelColumn action; Gtk::TreeModelColumn editable; Gtk::TreeModelColumn edited; - Gtk::TreeModelColumn isSeparator; ExifColumns() { - add (field); - add (value); - add (icon); - add (action); - add (edited); - add (field_nopango); - add (value_nopango); - add (editable); - add (orig_value); - add (isSeparator); + add(key); + add(label); + add(value); + add(icon); + add(edited); + add(value_nopango); + add(editable); } }; - Glib::RefPtr delicon; Glib::RefPtr keepicon; Glib::RefPtr editicon; @@ -71,32 +63,18 @@ private: Gtk::ScrolledWindow* scrolledWindow; Glib::RefPtr exifTreeModel; - Gtk::Button* remove; - Gtk::Button* keep; Gtk::Button* add; Gtk::Button* reset; Gtk::Button* resetAll; - Gtk::ToggleButton* showAll; - Gtk::TreeModel::Children addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, rtexif::ActionCode action, bool editable); - void editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value); - void updateChangeList (Gtk::TreeModel::Children root, std::string prefix); - void addDirectory (const rtexif::TagDirectory* dir, Gtk::TreeModel::Children root, bool checkForSeparator = false); - Gtk::TreeModel::Children addSeparator(); - Glib::ustring getSelection (bool onlyifeditable = false); - Glib::ustring getSelectedValue(); - void updateChangeList(); - void applyChangeList(); - void keepIt (Gtk::TreeModel::iterator iter); - void delIt (Gtk::TreeModel::iterator iter); - Gtk::TreeModel::iterator resetIt (Gtk::TreeModel::iterator iter); - void removePressed(); - void keepPressed(); + std::vector> editable_; + + Gtk::TreeModel::Children addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); + void refreshTags(); + void resetIt (Gtk::TreeModel::iterator iter); void resetPressed(); void resetAllPressed(); void addPressed(); - void showAlltoggled(); - bool rowSeperatorFunc(const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); public: ExifPanel (); @@ -109,7 +87,7 @@ public: void setImageData (const rtengine::FramesMetaData* id); void exifSelectionChanged(); - void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); + // void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); void notifyListener(); diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 7347927a0..9e534db2f 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -16,19 +16,66 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include "iptcpanel.h" #include "clipboard.h" #include "rtimage.h" +#include "../rtengine/imagedata.h" #include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; -IPTCPanel::IPTCPanel () : +namespace { + +const std::string CAPTION("Iptc.Application2.Caption"); +const std::string CAPTION_WRITER("Iptc.Application2.Writer"); +const std::string CATEGORY("Iptc.Application2.Category"); +const std::string CITY("Iptc.Application2.City"); +const std::string COPYRIGHT("Iptc.Application2.Copyright"); +const std::string COUNTRY("Iptc.Application2.CountryName"); +const std::string CREATOR("Iptc.Application2.Byline"); +const std::string CREATOR_JOB_TITLE("Iptc.Application2.BylineTitle"); +const std::string CREDIT("Iptc.Application2.Credit"); +const std::string DATE_CREATED("Iptc.Application2.DateCreated"); +const std::string HEADLINE("Iptc.Application2.Headline"); +const std::string INSTRUCTIONS("Iptc.Application2.SpecialInstructions"); +const std::string KEYWORDS("Iptc.Application2.Keywords"); +const std::string PROVINCE("Iptc.Application2.ProvinceState"); +const std::string SOURCE("Iptc.Application2.Source"); +const std::string SUPPLEMENTAL_CATEGORIES("Iptc.Application2.SuppCategory"); +const std::string TITLE("Iptc.Application2.ObjectName"); +const std::string TRANS_REFERENCE("Iptc.Application2.TransmissionReference"); + +const std::set iptc_keys = { + CAPTION, + CAPTION_WRITER, + CATEGORY, + CITY, + COPYRIGHT, + COUNTRY, + CREATOR, + CREATOR_JOB_TITLE, + CREDIT, + DATE_CREATED, + HEADLINE, + INSTRUCTIONS, + KEYWORDS, + PROVINCE, + SOURCE, + SUPPLEMENTAL_CATEGORIES, + TITLE, + TRANS_REFERENCE +}; + +} // namespace + + +IPTCPanel::IPTCPanel(): changeList(new rtengine::procparams::IPTCPairs), defChangeList(new rtengine::procparams::IPTCPairs), - embeddedData(new rtengine::procparams::IPTCPairs) + embeddedData(new rtengine::procparams::IPTCPairs) { set_spacing (4); @@ -441,11 +488,20 @@ void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pe void IPTCPanel::setImageData (const FramesMetaData* id) { - + embeddedData->clear(); if (id) { - *embeddedData = id->getIPTCData (); - } else { - embeddedData->clear (); + try { + auto img = open_exiv2(id->getFileName()); + img->readMetadata(); + auto &iptc = img->iptcData(); + for (auto &tag : iptc) { + if (iptc_keys.find(tag.key()) != iptc_keys.end()) { + (*embeddedData)[tag.key()].push_back(tag.toString()); + } + } + } catch (Exiv2::AnyError &exc) { + embeddedData->clear(); + } } file->set_sensitive (!embeddedData->empty()); @@ -570,32 +626,32 @@ void IPTCPanel::updateChangeList () { changeList->clear (); - (*changeList)["Caption" ].push_back (captionText->get_text ()); - (*changeList)["CaptionWriter" ].push_back (captionWriter->get_text ()); - (*changeList)["Headline" ].push_back (headline->get_text ()); - (*changeList)["Instructions" ].push_back (instructions->get_text ()); + (*changeList)[CAPTION].push_back (captionText->get_text ()); + (*changeList)[CAPTION_WRITER].push_back (captionWriter->get_text ()); + (*changeList)[HEADLINE].push_back (headline->get_text ()); + (*changeList)[INSTRUCTIONS].push_back (instructions->get_text ()); for (unsigned int i = 0; i < keywords->size(); i++) { - (*changeList)["Keywords" ].push_back (keywords->get_text (i)); + (*changeList)[KEYWORDS].push_back (keywords->get_text (i)); } - (*changeList)["Category" ].push_back (category->get_entry()->get_text ()); + (*changeList)[CATEGORY].push_back (category->get_entry()->get_text ()); for (unsigned int i = 0; i < suppCategories->size(); i++) { - (*changeList)["SupplementalCategories"].push_back (suppCategories->get_text (i)); + (*changeList)[SUPPLEMENTAL_CATEGORIES].push_back (suppCategories->get_text (i)); } - (*changeList)["Creator" ].push_back (creator->get_text ()); - (*changeList)["CreatorJobTitle"].push_back (creatorJobTitle->get_text ()); - (*changeList)["Credit" ].push_back (credit->get_text ()); - (*changeList)["Source" ].push_back (source->get_text ()); - (*changeList)["Copyright" ].push_back (copyright->get_text ()); - (*changeList)["City" ].push_back (city->get_text ()); - (*changeList)["Province" ].push_back (province->get_text ()); - (*changeList)["Country" ].push_back (country->get_text ()); - (*changeList)["Title" ].push_back (title->get_text ()); - (*changeList)["DateCreated" ].push_back (dateCreated->get_text ()); - (*changeList)["TransReference" ].push_back (transReference->get_text ()); + (*changeList)[CREATOR].push_back (creator->get_text ()); + (*changeList)[CREATOR_JOB_TITLE].push_back (creatorJobTitle->get_text ()); + (*changeList)[CREDIT].push_back (credit->get_text ()); + (*changeList)[SOURCE].push_back (source->get_text ()); + (*changeList)[COPYRIGHT].push_back (copyright->get_text ()); + (*changeList)[CITY].push_back (city->get_text ()); + (*changeList)[PROVINCE].push_back (province->get_text ()); + (*changeList)[COUNTRY].push_back (country->get_text ()); + (*changeList)[TITLE].push_back (title->get_text ()); + (*changeList)[DATE_CREATED].push_back (dateCreated->get_text ()); + (*changeList)[TRANS_REFERENCE].push_back (transReference->get_text ()); notifyListener (); } @@ -629,45 +685,45 @@ void IPTCPanel::applyChangeList () suppCategory->get_entry()->set_text (""); for (rtengine::procparams::IPTCPairs::const_iterator i = changeList->begin(); i != changeList->end(); ++i) { - if (i->first == "Caption" && !i->second.empty()) { + if (i->first == CAPTION && !i->second.empty()) { captionText->set_text (i->second.at(0)); - } else if (i->first == "CaptionWriter" && !i->second.empty()) { + } else if (i->first == CAPTION_WRITER && !i->second.empty()) { captionWriter->set_text (i->second.at(0)); - } else if (i->first == "Headline" && !i->second.empty()) { + } else if (i->first == HEADLINE && !i->second.empty()) { headline->set_text (i->second.at(0)); - } else if (i->first == "Instructions" && !i->second.empty()) { + } else if (i->first == INSTRUCTIONS && !i->second.empty()) { instructions->set_text (i->second.at(0)); - } else if (i->first == "Keywords") + } else if (i->first == KEYWORDS) for (unsigned int j = 0; j < i->second.size(); j++) { keywords->append (i->second.at(j)); } - else if (i->first == "Category" && !i->second.empty()) { + else if (i->first == CATEGORY && !i->second.empty()) { category->get_entry()->set_text (i->second.at(0)); - } else if (i->first == "SupplementalCategories") + } else if (i->first == SUPPLEMENTAL_CATEGORIES) for (unsigned int j = 0; j < i->second.size(); j++) { suppCategories->append (i->second.at(j)); } - else if (i->first == "Creator" && !i->second.empty()) { + else if (i->first == CREATOR && !i->second.empty()) { creator->set_text (i->second.at(0)); - } else if (i->first == "CreatorJobTitle" && !i->second.empty()) { + } else if (i->first == CREATOR_JOB_TITLE && !i->second.empty()) { creatorJobTitle->set_text (i->second.at(0)); - } else if (i->first == "Credit" && !i->second.empty()) { + } else if (i->first == CREDIT && !i->second.empty()) { credit->set_text (i->second.at(0)); - } else if (i->first == "Source" && !i->second.empty()) { + } else if (i->first == SOURCE && !i->second.empty()) { source->set_text (i->second.at(0)); - } else if (i->first == "Copyright" && !i->second.empty()) { + } else if (i->first == COPYRIGHT && !i->second.empty()) { copyright->set_text (i->second.at(0)); - } else if (i->first == "City" && !i->second.empty()) { + } else if (i->first == CITY && !i->second.empty()) { city->set_text (i->second.at(0)); - } else if (i->first == "Province" && !i->second.empty()) { + } else if (i->first == PROVINCE && !i->second.empty()) { province->set_text (i->second.at(0)); - } else if (i->first == "Country" && !i->second.empty()) { + } else if (i->first == COUNTRY && !i->second.empty()) { country->set_text (i->second.at(0)); - } else if (i->first == "Title" && !i->second.empty()) { + } else if (i->first == TITLE && !i->second.empty()) { title->set_text (i->second.at(0)); - } else if (i->first == "DateCreated" && !i->second.empty()) { + } else if (i->first == DATE_CREATED && !i->second.empty()) { dateCreated->set_text (i->second.at(0)); - } else if (i->first == "TransReference" && !i->second.empty()) { + } else if (i->first == TRANS_REFERENCE && !i->second.empty()) { transReference->set_text (i->second.at(0)); } } diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 106715a17..decbfb2f5 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.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 "resize.h" #include "eventmapper.h" diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index d55ce30fd..fe436b5ca 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ +#include #include "shcselector.h" #include "multilangmgr.h" #include "mycurve.h" diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 757708002..17667ea1a 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -34,6 +34,8 @@ #include "extprog.h" #include "profilestorecombobox.h" #include "procparamchangers.h" +#include "ppversion.h" +#include "version.h" using namespace rtengine::procparams; @@ -153,24 +155,23 @@ void Thumbnail::_generateThumbnailImage () // image out of the RAW. Mark as "quick". // 2. if we don't find that then just grab the real image. bool quick = false; - rtengine::RawMetaDataLocation ri; rtengine::eSensorType sensorType = rtengine::ST_NONE; if ( initial_ && options.internalThumbIfUntouched) { quick = true; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, tw, th, 1, TRUE); + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, tw, th, 1, TRUE); } if ( tpp == nullptr ) { quick = false; - tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams->wb.equal, TRUE); + tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, TRUE); } cfs.sensortype = sensorType; if (tpp) { cfs.format = FT_Raw; cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; - infoFromImage (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(ri))); + infoFromImage (fname); } } @@ -218,6 +219,67 @@ const ProcParams& Thumbnail::getProcParamsU () return *pparams; // there is no valid pp to return, but we have to return something } + +namespace { + +bool CPBDump(const Glib::ustring &commFName, const Glib::ustring &imageFName, + const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, + const CacheImageData* cfs, const bool flagMode) +{ + const auto kf = new Glib::KeyFile; + + if (!kf) { + return false; + } + + FILE *f = nullptr; + + // open the file in write mode + f = g_fopen (commFName.c_str (), "wt"); + + if (f == nullptr) { + printf ("CPBDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); + delete kf; + return false; + } + + try { + + kf->set_string ("RT General", "CachePath", options.cacheBaseDir); + kf->set_string ("RT General", "AppVersion", RTVERSION); + kf->set_integer ("RT General", "ProcParamsVersion", PPVERSION); + kf->set_string ("RT General", "ImageFileName", imageFName); + kf->set_string ("RT General", "OutputProfileFileName", profileFName); + kf->set_string ("RT General", "DefaultProcParams", defaultPParams); + kf->set_boolean ("RT General", "FlaggingMode", flagMode); + + kf->set_integer ("Common Data", "FrameCount", cfs->frameCount); + kf->set_integer ("Common Data", "SampleFormat", cfs->sampleFormat); + kf->set_boolean ("Common Data", "IsHDR", cfs->isHDR); + kf->set_boolean ("Common Data", "IsPixelShift", cfs->isPixelShift); + kf->set_double ("Common Data", "FNumber", cfs->fnumber); + kf->set_double ("Common Data", "Shutter", cfs->shutter); + kf->set_double ("Common Data", "FocalLength", cfs->focalLen); + kf->set_integer ("Common Data", "ISO", cfs->iso); + kf->set_string ("Common Data", "Lens", cfs->lens); + kf->set_string ("Common Data", "Make", cfs->camMake); + kf->set_string ("Common Data", "Model", cfs->camModel); + + } catch (Glib::KeyFileError&) {} + + try { + fprintf (f, "%s", kf->to_data().c_str()); + } catch (Glib::KeyFileError&) {} + + fclose (f); + delete kf; + + return true; +} + + +} // namespace + /** @brief Create default params on demand and returns a new updatable object * * The loaded profile may be partial, but it return a complete ProcParams (i.e. without ParamsEdited) @@ -242,7 +304,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu const CacheImageData* cfs = getCacheImageData(); Glib::ustring defaultPparamsPath = options.findProfilePath(defProf); const bool create = (!hasProcParams() || force); - const bool run_cpb = !options.CPBPath.empty() && !defaultPparamsPath.empty() && cfs && cfs->exifValid && create; + const bool run_cpb = false; //!options.CPBPath.empty() && !defaultPparamsPath.empty() && cfs && cfs->exifValid && create; const Glib::ustring outFName = (options.paramsLoadLocation == PLL_Input && options.saveParamsFile) ? @@ -251,16 +313,8 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu if (!run_cpb) { if (defProf == DEFPROFILE_DYNAMIC && create && cfs && cfs->exifValid) { - rtengine::FramesMetaData* imageMetaData; - if (getType() == FT_Raw) { - // Should we ask all frame's MetaData ? - imageMetaData = rtengine::FramesMetaData::fromFile (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(rtengine::Thumbnail::loadMetaDataFromRaw(fname))), true); - } else { - // Should we ask all frame's MetaData ? - imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); - } - PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData); - delete imageMetaData; + std::unique_ptr imageMetaData(rtengine::FramesMetaData::fromFile(fname)); + PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData.get()); int err = pp->pparams->save(outFName); pp->deleteInstance(); delete pp; @@ -275,28 +329,11 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu } } else { // First generate the communication file, with general values and EXIF metadata - rtengine::FramesMetaData* imageMetaData; - - if (getType() == FT_Raw) { - // Should we ask all frame's MetaData ? - imageMetaData = rtengine::FramesMetaData::fromFile (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(rtengine::Thumbnail::loadMetaDataFromRaw(fname))), true); - } else { - // Should we ask all frame's MetaData ? - imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); - } - Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) ); - const rtexif::TagDirectory* exifDir = nullptr; - - if (imageMetaData && (exifDir = imageMetaData->getRootExifData())) { - exifDir->CPBDump(tmpFileName, fname, outFName, - defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension), - cfs, - flaggingMode); - } - delete imageMetaData; - + CPBDump(tmpFileName, fname, outFName, + defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension), cfs, flaggingMode); + // For the filename etc. do NOT use streams, since they are not UTF8 safe Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\""); @@ -778,9 +815,9 @@ ThFileType Thumbnail::getType () return (ThFileType) cfs.format; } -int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptr rml) +int Thumbnail::infoFromImage (const Glib::ustring& fname) { - rtengine::FramesMetaData* idata = rtengine::FramesMetaData::fromFile (fname, std::move(rml)); + rtengine::FramesMetaData* idata = rtengine::FramesMetaData::fromFile (fname); if (!idata) { return 0; diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 0bcdd470a..33bccbf81 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -73,7 +73,7 @@ class Thumbnail void _loadThumbnail (bool firstTrial = true); void _saveThumbnail (); void _generateThumbnailImage (); - int infoFromImage (const Glib::ustring& fname, std::unique_ptr rml = nullptr); + int infoFromImage (const Glib::ustring& fname); void loadThumbnail (bool firstTrial = true); void generateExifDateTimeStrings (); diff --git a/tools/generateRtexifUpdates b/tools/generateRtexifUpdates deleted file mode 100755 index 72a97862e..000000000 --- a/tools/generateRtexifUpdates +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash - -# This Bash4 script generates lens ID and other parameter lists for rtexif/*.cc -# using ExifTool. It uses xmlstarlet to parse ExifTool's output. -# -# Run the script from the project root: -# ./tools/generateRtexifUpdates -# -# Manually replace old code in rtexif/* with new from /tmp/rt-generateRtexifUpdates/* -# -# Blame DrSlony -# Please report bugs or enhancements to https://github.com/Beep6581/RawTherapee - -et="$HOME/programs/code-exiftool/exiftool" - -hash "$et" 2>/dev/null || { echo >&2 "ExifTool not found, install it first."; exit 1; } -hash xmlstarlet 2>/dev/null || { echo >&2 "XMLStarlet not found, install it first."; exit 1; } - -unset cam cams - -tmpdir="/tmp/rt-generateRtexifUpdates" - -printf '%s\n' "ExifTool version: $("$et" -ver)" "" "XMLStarlet version: $(xmlstarlet --version)" | sed 's/^/# /' - -if [[ -d ${tmpdir} ]]; then - printf '%s\n' "" "Must remove temp folder from previous run: $tmpdir" - rm -rvI "$tmpdir" || exit 1 -fi -mkdir -p "$tmpdir" || { printf '%s\n' "Error creating $tmpdir" ""; exit 1; } -echo - -#------------------------------------------------------------------------------ -# Canon -printf '%s\n' "Saving ${tmpdir}/canon_lenses" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_lenses" - -#In :10.1 Sigma 50mm f/2.8 EX -#Out: {10, "Sigma 50mm f/2.8 EX"}, -# delete lines matching '-1n/a' -# replace '10.1Sigma' with '10, "Sigma' -# prepend whitespace -# append closing braces -# replace ' F/11' with ' f/11' -sed -r -i \ - -e '/-1\tn\/a/d' \ - -e 's/([0-9]+)[0-9.]*\t/\1, "/' \ - -e 's/^/ {/' \ - -e 's/$/"},/' \ - -e 's| F/([0-9]+)| f/\1|' \ - "${tmpdir}/canon_lenses" - -#In :16842752 PowerShot A30 -#Out: choices[16842752] = "PowerShot A30"; -# prepend whitespace and 'choices[' -# replace with '] = "' -# append '";' -printf '%s\n' "Saving ${tmpdir}/canon_cameras" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='CanonModelID']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_cameras" -sed -r -i \ - -e 's/^/ choices[/' \ - -e 's/\t/] = "/' \ - -e 's/$/";/' \ - "${tmpdir}/canon_cameras" - -#------------------------------------------------------------------------------ -# Nikon LensIDs are composite tags -printf '%s\n' "Saving ${tmpdir}/nikon" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensID']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -composite:all) > "${tmpdir}/nikon" -sed -r -i -e '/^... /d' -e 's/^/ {"/' -e 's/([A-F0-9]+)[A-F0-9.]*\t/\1", "/' -e 's/$/"},/' -e 's|(.* ")(.*) F([0-9]+)|\1\2 f/\3|' -e 's| F/([0-9]+)| f/\1|' "${tmpdir}/nikon" - -#------------------------------------------------------------------------------ -# Olympus -printf '%s\n' "Saving ${tmpdir}/olympus" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -olympus:all) | sort -fuV > "${tmpdir}/olympus" -sed -r -i -e '/0 00 00\tNone/d' -e 's/^/ lenses["0/' -e 's/\t/"] = "/' -e 's/$/";/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/olympus" - -#------------------------------------------------------------------------------ -# Pentax -printf '%s\n' "Saving ${tmpdir}/pentax" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -pentax:all) | sort -fuV > "${tmpdir}/pentax" -sed -r -i -e 's/^/ choices.insert (p_t (256 * /' -e 's/([0-9]+) ([0-9]+)([0-9.]*)/\1 + \2/' -e 's/\t/, "/' -e 's/$/"));/' -e 's| F([0-9]+)| f/\1|' "${tmpdir}/pentax" - -#------------------------------------------------------------------------------ -# Sony -printf '%s\n' "Saving ${tmpdir}/sony" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony" -# Sony has more lenses under the LensType2 tag -printf '%s\n' "Saving ${tmpdir}/sony-lenstype2" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType2']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony-lenstype2" -sed -r -i -e 's/^/ {/' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/$/"},/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/sony" -sed -r -i -e '/255\tTamron Lens (255)/d' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/^/ choices.insert (p_t (/' -e 's/$/"));/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/sony-lenstype2" - From ba4de904cc5d6a719f7ca3544049b0b15850741a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 10 May 2019 21:24:22 +0200 Subject: [PATCH 002/326] Cleanups and a few fixes --- rtengine/dcp.cc | 158 ++++++++++++++-------------- rtengine/histmatching.cc | 4 +- rtengine/imagedata.cc | 190 ++++++++++++++++++---------------- rtengine/imagedata.h | 20 ++-- rtengine/imageio.cc | 88 ++++++++++------ rtengine/imageio.h | 47 +++++---- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 1 - rtengine/improcfun.cc | 1 + rtengine/procparams.cc | 16 +-- rtengine/procparams.h | 100 +++++++++++++++++- rtengine/rawimagesource.cc | 14 +-- rtengine/rtengine.h | 7 +- rtengine/rtthumbnail.cc | 32 +++--- rtengine/simpleprocess.cc | 20 ++-- rtgui/cacheimagedata.h | 1 - rtgui/exifpanel.cc | 87 +++++++++------- rtgui/exifpanel.h | 18 +++- rtgui/iptcpanel.cc | 13 +-- rtgui/resize.cc | 1 + rtgui/shcselector.cc | 2 + rtgui/thumbnail.cc | 174 ++++++++++++++++--------------- 22 files changed, 582 insertions(+), 414 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 0f5b32d34..c6c38077a 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -40,7 +40,8 @@ extern const Settings* settings; using namespace rtengine; -namespace { +namespace +{ // This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here @@ -442,8 +443,8 @@ std::map getAliases(const Glib::ustring& profile_dir) return res; } - class DCPMetadata { + // TODO: Review enum TagType { INVALID = 0, BYTE = 1, @@ -465,10 +466,10 @@ class DCPMetadata { INTEL = 0x4949, MOTOROLA = 0x4D4D }; - + public: explicit DCPMetadata(FILE *file): order_(UNKNOWN), file_(file) {} - + bool parse() { int offset = 0; @@ -487,7 +488,7 @@ public: unsigned short bo; fread(&bo, 1, 2, f); order_ = ByteOrder(int(bo)); - + get2(f, order_); if (!offset) { offset = get4(f, order_); @@ -513,12 +514,12 @@ public: return true; } - + bool find(int id) const { return tags_.find(id) != tags_.end(); } - + std::string toString(int id) { auto it = tags_.find(id); @@ -578,12 +579,12 @@ public: return 0; } } - + int toShort(int id, int ofs=0) { return toInt(id, ofs, SHORT); } - + double toDouble(int id, int ofs=0) { auto it = tags_.find(id); @@ -592,7 +593,7 @@ public: } auto &t = it->second; - + union IntFloat { uint32_t i; float f; @@ -651,7 +652,7 @@ private: return s[0] << 8 | s[1]; } } - + static int sget4(unsigned char *s, ByteOrder order) { if (order == INTEL) { @@ -660,21 +661,21 @@ private: return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } } - + static unsigned short get2(FILE* f, ByteOrder order) - { + { unsigned char str[2] = { 0xff, 0xff }; fread (str, 1, 2, f); return sget2(str, order); } - + static int get4(FILE *f, ByteOrder order) - { + { unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; fread (str, 1, 4, f); return sget4 (str, order); } - + static short int int2_to_signed(short unsigned int i) { union { @@ -744,7 +745,6 @@ private: } // namespace - struct DCPProfile::ApplyState::Data { float pro_photo[3][3]; float work[3][3]; @@ -778,22 +778,22 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : constexpr int tiff_float_size = 4; enum TagKey { - COLOR_MATRIX_1 = 50721, - COLOR_MATRIX_2 = 50722, - PROFILE_HUE_SAT_MAP_DIMS = 50937, - PROFILE_HUE_SAT_MAP_DATA_1 = 50938, - PROFILE_HUE_SAT_MAP_DATA_2 = 50939, - PROFILE_TONE_CURVE = 50940, - PROFILE_TONE_COPYRIGHT = 50942, - CALIBRATION_ILLUMINANT_1 = 50778, - CALIBRATION_ILLUMINANT_2 = 50779, - FORWARD_MATRIX_1 = 50964, - FORWARD_MATRIX_2 = 50965, - PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant - PROFILE_LOOK_TABLE_DATA = 50982, - PROFILE_HUE_SAT_MAP_ENCODING = 51107, - PROFILE_LOOK_TABLE_ENCODING = 51108, - BASELINE_EXPOSURE_OFFSET = 51109 + TAG_KEY_COLOR_MATRIX_1 = 50721, + TAG_KEY_COLOR_MATRIX_2 = 50722, + TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS = 50937, + TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1 = 50938, + TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2 = 50939, + TAG_KEY_PROFILE_TONE_CURVE = 50940, + TAG_KEY_PROFILE_TONE_COPYRIGHT = 50942, + TAG_KEY_CALIBRATION_ILLUMINANT_1 = 50778, + TAG_KEY_CALIBRATION_ILLUMINANT_2 = 50779, + TAG_KEY_FORWARD_MATRIX_1 = 50964, + TAG_KEY_FORWARD_MATRIX_2 = 50965, + TAG_KEY_PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant + TAG_KEY_PROFILE_LOOK_TABLE_DATA = 50982, + TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING = 51107, + TAG_KEY_PROFILE_LOOK_TABLE_ENCODING = 51108, + TAG_KEY_BASELINE_EXPOSURE_OFFSET = 51109 }; static const float adobe_camera_raw_default_curve[] = { @@ -1065,46 +1065,46 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : DCPMetadata md(file); if (!md.parse()) { - printf ("Unable to load DCP profile '%s' !", filename.c_str()); + printf ("Unable to load DCP profile '%s'.", filename.c_str()); return; } light_source_1 = - md.find(CALIBRATION_ILLUMINANT_1) ? - md.toShort(CALIBRATION_ILLUMINANT_1) : - -1; + md.find(TAG_KEY_CALIBRATION_ILLUMINANT_1) + ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_1) + : -1; light_source_2 = - md.find(CALIBRATION_ILLUMINANT_2) ? - md.toShort(CALIBRATION_ILLUMINANT_2) : - -1; + md.find(TAG_KEY_CALIBRATION_ILLUMINANT_2) + ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_2) + : -1; temperature_1 = calibrationIlluminantToTemperature(light_source_1); temperature_2 = calibrationIlluminantToTemperature(light_source_2); - const bool has_second_hue_sat = md.find(PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat + const bool has_second_hue_sat = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat // Fetch Forward Matrices, if any - has_forward_matrix_1 = md.find(FORWARD_MATRIX_1); + has_forward_matrix_1 = md.find(TAG_KEY_FORWARD_MATRIX_1); if (has_forward_matrix_1) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_1[row][col] = md.toDouble(FORWARD_MATRIX_1, (col + row * 3) * 8); + forward_matrix_1[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_1, (col + row * 3) * 8); } } } - has_forward_matrix_2 = md.find(FORWARD_MATRIX_2); + has_forward_matrix_2 = md.find(TAG_KEY_FORWARD_MATRIX_2); if (has_forward_matrix_2) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_2[row][col] = md.toDouble(FORWARD_MATRIX_2, (col + row * 3) * 8); + forward_matrix_2[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_2, (col + row * 3) * 8); } } } // Color Matrix (one is always there) - if (!md.find(COLOR_MATRIX_1)) { + if (!md.find(TAG_KEY_COLOR_MATRIX_1)) { std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; fclose(file); return; @@ -1114,24 +1114,24 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - color_matrix_1[row][col] = md.toDouble(COLOR_MATRIX_1, (col + row * 3) * 8); + color_matrix_1[row][col] = md.toDouble(TAG_KEY_COLOR_MATRIX_1, (col + row * 3) * 8); } } - if (md.find(PROFILE_LOOK_TABLE_DIMS)) { - look_info.hue_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 0); - look_info.sat_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 4); - look_info.val_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 8); + if (md.find(TAG_KEY_PROFILE_LOOK_TABLE_DIMS)) { + look_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 0); + look_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 4); + look_info.val_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 8); - look_info.srgb_gamma = md.find(PROFILE_LOOK_TABLE_ENCODING) && md.toInt(PROFILE_LOOK_TABLE_ENCODING); + look_info.srgb_gamma = md.find(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING) && md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING); - look_info.array_count = md.getCount(PROFILE_LOOK_TABLE_DATA) / 3; + look_info.array_count = md.getCount(TAG_KEY_PROFILE_LOOK_TABLE_DATA) / 3; look_table.resize(look_info.array_count); for (unsigned int i = 0; i < look_info.array_count; i++) { - look_table[i].hue_shift = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); - look_table[i].sat_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); - look_table[i].val_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); + look_table[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); + look_table[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); + look_table[i].val_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); } // Precalculated constants for table application @@ -1148,20 +1148,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : look_info.pc.val_step = look_info.hue_divisions * look_info.pc.hue_step; } - if (md.find(PROFILE_HUE_SAT_MAP_DIMS)) { - delta_info.hue_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 0); - delta_info.sat_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 4); - delta_info.val_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 8); + if (md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS)) { + delta_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 0); + delta_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 4); + delta_info.val_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 8); - delta_info.srgb_gamma = md.find(PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(PROFILE_HUE_SAT_MAP_ENCODING); + delta_info.srgb_gamma = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING); - delta_info.array_count = md.getCount(PROFILE_HUE_SAT_MAP_DATA_1) / 3; + delta_info.array_count = md.getCount(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1) / 3; deltas_1.resize(delta_info.array_count); for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_1[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); - deltas_1[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); - deltas_1[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); + deltas_1[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); + deltas_1[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); + deltas_1[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); } delta_info.pc.h_scale = @@ -1181,14 +1181,14 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Second matrix has_color_matrix_2 = true; - bool cm2 = md.find(COLOR_MATRIX_2); + const bool cm2 = md.find(TAG_KEY_COLOR_MATRIX_2); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { color_matrix_2[row][col] = cm2 - ? md.toDouble(COLOR_MATRIX_2, (col + row * 3) * 8) - : color_matrix_1[row][col]; + ? md.toDouble(TAG_KEY_COLOR_MATRIX_2, (col + row * 3) * 8) + : color_matrix_1[row][col]; } } @@ -1198,20 +1198,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Saturation maps. Need to be unwinded. for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_2[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); - deltas_2[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); - deltas_2[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); + deltas_2[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); + deltas_2[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); + deltas_2[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); } } } - has_baseline_exposure_offset = md.find(BASELINE_EXPOSURE_OFFSET); + has_baseline_exposure_offset = md.find(TAG_KEY_BASELINE_EXPOSURE_OFFSET); if (has_baseline_exposure_offset) { - baseline_exposure_offset = md.toDouble(BASELINE_EXPOSURE_OFFSET); + baseline_exposure_offset = md.toDouble(TAG_KEY_BASELINE_EXPOSURE_OFFSET); } // Read tone curve points, if any, but disable to RTs own profiles - if (md.find(PROFILE_TONE_CURVE)) { + if (md.find(TAG_KEY_PROFILE_TONE_CURVE)) { std::vector curve_points = { static_cast(DCT_Spline) // The first value is the curve type }; @@ -1219,9 +1219,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Push back each X/Y coordinates in a loop bool curve_is_linear = true; - for (unsigned int i = 0, n = md.getCount(PROFILE_TONE_CURVE); i < n; i += 2) { - const double x = md.toDouble(PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); - const double y = md.toDouble(PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); + for (unsigned int i = 0, n = md.getCount(TAG_KEY_PROFILE_TONE_CURVE); i < n; i += 2) { + const double x = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); + const double y = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); if (x != y) { curve_is_linear = false; @@ -1237,7 +1237,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); } } else { - if (md.find(PROFILE_TONE_COPYRIGHT) && md.toString(PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { + if (md.find(TAG_KEY_PROFILE_TONE_COPYRIGHT) && md.toString(TAG_KEY_PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { // An Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that std::vector curve_points = { static_cast(DCT_Spline) @@ -2076,7 +2076,7 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) std::deque dirs = { rt_profile_dir, - Glib::build_filename(options.rtdir, "dcpprofiles") + Glib::build_filename(options.rtdir, "dcpprofiles") }; while (!dirs.empty()) { diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 5a17ab6ec..322775ca4 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -280,7 +280,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st { eSensorType sensor_type; int w, h; - std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), sensor_type, w, h, 1, false, true, true)); + const std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), sensor_type, w, h, 1, false, true, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: no thumbnail found, generating a neutral curve" << std::endl; @@ -312,7 +312,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st eSensorType sensor_type; double scale; int w = fw / skip, h = fh / skip; - std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), sensor_type, w, h, 1, false, false, true)); + const std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), sensor_type, w, h, 1, false, false, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index e0f6b50a3..1890739b8 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -17,43 +17,32 @@ * along with RawTherapee. If not, see . */ #include + #include -#include #include + +#include + #include #include "imagedata.h" #include "imagesource.h" #include "rt_math.h" + #pragma GCC diagnostic warning "-Wextra" #define PRINT_HDR_PS_DETECTION 0 using namespace rtengine; - -// namespace { - -// Glib::ustring to_utf8 (const std::string& str) -// { -// try { -// return Glib::locale_to_utf8 (str); -// } catch (Glib::Error&) { -// return Glib::convert_with_fallback (str, "UTF-8", "ISO-8859-1", "?"); -// } -// } - -// } // namespace - - namespace rtengine { extern const Settings *settings; -Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname) +Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) { #ifdef EXV_UNICODE_PATH - auto *ws = g_utf8_to_utf16(fname.c_str(), -1, NULL, NULL, NULL); - std::wstring wfname(ws); + const auto* const ws = g_utf8_to_utf16(fname.c_str(), -1, NULL, NULL, NULL); + const std::wstring wfname(ws); g_free(ws); auto image = Exiv2::ImageFactory::open(wfname); #else @@ -65,13 +54,12 @@ Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname) } // namespace rtengine - FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname) { return new FramesData(fname); } -FramesData::FramesData(const Glib::ustring &fname): +FramesData::FramesData(const Glib::ustring &fname) : ok_(false), fname_(fname), dcrawFrameCount(0), @@ -110,7 +98,7 @@ FramesData::FramesData(const Glib::ustring &fname): try { auto image = open_exiv2(fname); image->readMetadata(); - auto &exif = image->exifData(); + const auto& exif = image->exifData(); ok_ = true; // taken and adapted from darktable (src/common/exif.cc) @@ -133,66 +121,72 @@ FramesData::FramesData(const Glib::ustring &fname): You should have received a copy of the GNU General Public License along with darktable. If not, see . */ - + Exiv2::ExifData::const_iterator pos; - + const auto find_exif_tag = - [&](const std::string &name) -> bool + [&exif, &pos](const std::string &name) -> bool { pos = exif.findKey(Exiv2::ExifKey(name)); - return (pos != exif.end() && pos->size()); + return pos != exif.end() && pos->size(); }; const auto find_tag = - [&](decltype(Exiv2::make) func) -> bool + [&exif, &pos](decltype(Exiv2::make) func) -> bool { pos = func(exif); return pos != exif.end() && pos->size(); }; - /* List of tag names taken from exiv2's printSummary() in actions.cpp */ + // List of tag names taken from exiv2's printSummary() in actions.cpp if (find_tag(Exiv2::make)) { make = pos->print(&exif); } - + if (find_tag(Exiv2::model)) { model = pos->print(&exif); } if (make.size() > 0) { for (const auto& corp : { - "Canon", - "NIKON", - "EPSON", - "KODAK", - "Kodak", - "OLYMPUS", - "PENTAX", - "RICOH", - "MINOLTA", - "Minolta", - "Konica", - "CASIO", - "Sinar", - "Phase One", - "SAMSUNG", - "Mamiya", - "MOTOROLA", - "Leaf", - "Panasonic" - }) { + "Canon", + "NIKON", + "EPSON", + "KODAK", + "Kodak", + "OLYMPUS", + "PENTAX", + "RICOH", + "MINOLTA", + "Minolta", + "Konica", + "CASIO", + "Sinar", + "Phase One", + "SAMSUNG", + "Mamiya", + "MOTOROLA", + "Leaf", + "Panasonic" + }) { if (make.find(corp) != std::string::npos) { // Simplify company names make = corp; break; } } - } - make.erase(make.find_last_not_of(' ') + 1); - model.erase(model.find_last_not_of(' ') + 1); + } + std::string::size_type nonspace_pos = make.find_last_not_of(' '); + if (nonspace_pos != std::string::npos && nonspace_pos + 1 < make.size()) { + make.erase(nonspace_pos + 1); + } + nonspace_pos = model.find_last_not_of(' '); + if (nonspace_pos != std::string::npos && nonspace_pos + 1 < model.size()) { + model.erase(nonspace_pos + 1); + } - if (make.length() > 0 && model.find(make + " ") == 0) { - model = model.substr(make.length() + 1); + if (!make.empty() && model.find(make + ' ') == 0) { + model.erase(0, make.size() + 1); } if (find_tag(Exiv2::exposureTime)) { @@ -203,24 +197,28 @@ FramesData::FramesData(const Glib::ustring &fname): aperture = pos->toFloat(); } - /* Read ISO speed - Nikon happens to return a pair for Lo and Hi modes */ + // Read ISO speed - Nikon happens to return a pair for Lo and Hi modes if (find_tag(Exiv2::isoSpeed)) { - // if standard exif iso tag, use the old way of interpreting the return value to be more regression-save - if (strcmp(pos->key().c_str(), "Exif.Photo.ISOSpeedRatings") == 0) { - int isofield = pos->count() > 1 ? 1 : 0; + // If standard exif iso tag, use the old way of interpreting the return value to be more regression-save + if (pos->key() == "Exif.Photo.ISOSpeedRatings") { + const long isofield = pos->count() > 1 ? 1 : 0; iso_speed = pos->toFloat(isofield); } else { - std::string str = pos->print(); - iso_speed = std::atof(str.c_str()); + iso_speed = std::atof(pos->print().c_str()); } } - // some newer cameras support iso settings that exceed the 16 bit of exif's ISOSpeedRatings + // Some newer cameras support iso settings that exceed the 16 bit of exif's ISOSpeedRatings if (iso_speed == 65535 || iso_speed == 0) { if (find_exif_tag("Exif.PentaxDng.ISO") || find_exif_tag("Exif.Pentax.ISO")) { - std::string str = pos->print(); - iso_speed = std::atof(str.c_str()); - } else if((!g_strcmp0(make.c_str(), "SONY") || !g_strcmp0(make.c_str(), "Canon")) - && find_exif_tag("Exif.Photo.RecommendedExposureIndex")) { + iso_speed = std::atof(pos->print().c_str()); + } + else if ( + ( + make == "SONY" + || make == "Canon" + ) + && find_exif_tag("Exif.Photo.RecommendedExposureIndex") + ) { iso_speed = pos->toFloat(); } } @@ -240,9 +238,9 @@ FramesData::FramesData(const Glib::ustring &fname): } if (find_tag(Exiv2::subjectDistance)) { - focus_dist = (0.01 * pow(10, pos->toFloat() / 40)); + focus_dist = (0.01 * std::pow(10, pos->toFloat() / 40)); } - + if (find_tag(Exiv2::orientation)) { orientation = pos->print(&exif); } @@ -257,7 +255,8 @@ FramesData::FramesData(const Glib::ustring &fname): std::string datetime_taken; if (find_exif_tag("Exif.Image.DateTimeOriginal")) { datetime_taken = pos->print(&exif); - } else if(find_exif_tag("Exif.Photo.DateTimeOriginal")) { + } + else if (find_exif_tag("Exif.Photo.DateTimeOriginal")) { datetime_taken = pos->print(&exif); } if (sscanf(datetime_taken.c_str(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { @@ -275,23 +274,23 @@ FramesData::FramesData(const Glib::ustring &fname): // Special file type detection (HDR, PixelShift) // ------------------------ uint16 bitspersample = 0, samplesperpixel = 0, sampleformat = 0, photometric = 0, compression = 0; - auto bps = exif.findKey(Exiv2::ExifKey("Exif.Image.BitsPerSample")); - auto spp = exif.findKey(Exiv2::ExifKey("Exif.Image.SamplesPerPixel")); - auto sf = exif.findKey(Exiv2::ExifKey("Exif.Image.SampleFormat")); - auto pi = exif.findKey(Exiv2::ExifKey("Exif.Image.PhotometricInterpretation")); - auto c = exif.findKey(Exiv2::ExifKey("Exif.Image.Compression")); + const auto bps = exif.findKey(Exiv2::ExifKey("Exif.Image.BitsPerSample")); + const auto spp = exif.findKey(Exiv2::ExifKey("Exif.Image.SamplesPerPixel")); + const auto sf = exif.findKey(Exiv2::ExifKey("Exif.Image.SampleFormat")); + const auto pi = exif.findKey(Exiv2::ExifKey("Exif.Image.PhotometricInterpretation")); + const auto c = exif.findKey(Exiv2::ExifKey("Exif.Image.Compression")); - if ((!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { -// if (find_exif_tag("Exif.Pentax.HDR") && pos->toLong() > 0) { -// isHDR = true; -// #if PRINT_HDR_PS_DETECTION -// printf("HDR detected ! -> \"HDR\" tag found\n"); -// #endif -// } else + if ( + !make.compare(0, 6, "PENTAX") + || ( + !make.compare(0, 5, "RICOH") + && !model.compare (0, 6, "PENTAX") + ) + ) { if (find_exif_tag("Exif.Pentax.DriveMode")) { std::string buf = pos->toString(3); buf[3] = 0; - if (!strcmp(buf.c_str(), "HDR")) { + if (buf == "HDR") { isHDR = true; #if PRINT_HDR_PS_DETECTION printf("HDR detected ! -> DriveMode = \"HDR\"\n"); @@ -299,8 +298,14 @@ FramesData::FramesData(const Glib::ustring &fname): } } - if (!isHDR && find_exif_tag("Exif.Pentax.Quality") && - (pos->toLong() == 7 || pos->toLong() == 8)) { + if ( + !isHDR + && find_exif_tag("Exif.Pentax.Quality") + && ( + pos->toLong() == 7 + || pos->toLong() == 8 + ) + ) { isPixelShift = true; #if PRINT_HDR_PS_DETECTION printf("PixelShift detected ! -> \"Quality\" = 7\n"); @@ -434,7 +439,7 @@ FramesData::FramesData(const Glib::ustring &fname): #endif } } - } catch(Exiv2::AnyError &e) { + } catch (const Exiv2::AnyError& e) { if (settings->verbose) { std::cerr << "EXIV2 ERROR: " << e.what() << std::endl; } @@ -564,7 +569,7 @@ void FramesData::setDCRawFrameCount(unsigned int frameCount) unsigned int FramesData::getFrameCount() const { - return dcrawFrameCount ? dcrawFrameCount : 1; + return std::max(1U, dcrawFrameCount); } @@ -578,7 +583,7 @@ Glib::ustring FramesData::getFileName() const std::string FramesMetaData::apertureToString(double aperture) { - + // TODO: Replace sprintf() char buffer[256]; sprintf (buffer, "%0.1f", aperture); return buffer; @@ -618,18 +623,21 @@ std::string FramesMetaData::expcompToString(double expcomp, bool maskZeroexpcomp double FramesMetaData::shutterFromString(std::string s) { - size_t i = s.find_first_of ('/'); + const std::string::size_type i = s.find_first_of ('/'); if (i == std::string::npos) { - return atof (s.c_str()); + return std::atof(s.c_str()); } else { - return atof (s.substr(0, i).c_str()) / atof (s.substr(i + 1).c_str()); + const double denominator = std::atof(s.substr(i + 1).c_str()); + return + denominator + ? std::atof(s.substr(0, i).c_str()) / denominator + : 0.0; } } double FramesMetaData::apertureFromString(std::string s) { - return atof(s.c_str()); + return std::atof(s.c_str()); } - diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 6f2147277..eeeefdc58 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -16,24 +16,28 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __IMAGEDATA_H__ -#define __IMAGEDATA_H__ +#pragma once #include #include -#include "rawimage.h" #include + #include + #include + +#include "rawimage.h" #include "rtengine.h" namespace rtengine { -Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname); +Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname); // TODO: Global function? -class FramesData : public FramesMetaData { +class FramesData : + public FramesMetaData +{ private: bool ok_; Glib::ustring fname_; @@ -52,9 +56,9 @@ private: IIOSampleFormat sampleFormat; bool isPixelShift; bool isHDR; - + public: - FramesData (const Glib::ustring& fname); + FramesData(const Glib::ustring& fname); void setDCRawFrameCount(unsigned int frameCount); unsigned int getFrameCount() const override; @@ -80,6 +84,4 @@ public: Glib::ustring getFileName() const override; }; - } -#endif diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index f7d95b2df..83ef10b28 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -36,7 +36,6 @@ #endif #include "imageio.h" -//#include "iptcpairs.h" #include "iccjpeg.h" #include "color.h" #include "imagedata.h" @@ -78,27 +77,51 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) } -Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."}; - -void ImageIO::setOutputProfile (const char* pdata, int plen) +MetadataInfo::MetadataInfo(const Glib::ustring& src) : + src_(src), + exif_(new rtengine::procparams::ExifPairs), + iptc_(new rtengine::procparams::IPTCPairs) { +} - delete [] profileData; +const Glib::ustring& MetadataInfo::filename() const +{ + return src_; +} - if (pdata) { - profileData = new char [plen]; - memcpy (profileData, pdata, plen); - } else { - profileData = nullptr; - } +const rtengine::procparams::ExifPairs& MetadataInfo::exif() const +{ + return *exif_; +} - profileLength = plen; +const rtengine::procparams::IPTCPairs& MetadataInfo::iptc() const +{ + return *iptc_; +} + +void MetadataInfo::setExif(const rtengine::procparams::ExifPairs &exif) +{ + *exif_ = exif; +} + +void MetadataInfo::setIptc(const rtengine::procparams::IPTCPairs &iptc) +{ + *iptc_ = iptc; +} + +void ImageIO::setMetadata(MetadataInfo info) +{ + metadataInfo = std::move(info); +} + +void ImageIO::setOutputProfile(const std::string& pdata) +{ + profileData = pdata; } ImageIO::ImageIO() : pl(nullptr), embProfile(nullptr), - profileData(nullptr), profileLength(0), loadedProfileData(nullptr), loadedProfileDataJpg(false), @@ -116,8 +139,6 @@ ImageIO::~ImageIO () } deleteLoadedProfileData(); - // delete exifRoot; - delete [] profileData; } void png_read_data(png_struct_def *png_ptr, unsigned char *data, size_t length); @@ -853,7 +874,7 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED) png_set_option(png, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); #endif - + png_infop info = png_create_info_struct(png); if (!info) { @@ -887,13 +908,13 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const png_set_IHDR(png, info, width, height, bps, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_BASE); - if (profileData) { + if (!profileData.empty()) { #if PNG_LIBPNG_VER < 10500 - png_charp profdata = reinterpret_cast(profileData); + png_const_charp profdata = reinterpret_cast(profileData.data()); #else - png_bytep profdata = reinterpret_cast(profileData); + png_const_bytep profdata = reinterpret_cast(profileData.data()); #endif - png_set_iCCP(png, info, const_cast("icc"), 0, profdata, profileLength); + png_set_iCCP(png, info, "icc", 0, profdata, profileData.size()); } int rowlen = width * 3 * bps / 8; @@ -1034,8 +1055,8 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con jpeg_start_compress(&cinfo, TRUE); // write icc profile to the output - if (profileData) { - write_icc_profile (&cinfo, (JOCTET*)profileData, profileLength); + if (!profileData.empty()) { + write_icc_profile (&cinfo, reinterpret_cast(profileData.data()), profileData.size()); } // write image data @@ -1115,7 +1136,7 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u unsigned char* linebuffer = new unsigned char[lineWidth]; // little hack to get libTiff to use proper byte order (see TIFFClienOpen()): - const char *mode = "w"; + const char* const mode = "w"; #ifdef WIN32 FILE *file = g_fopen_withBinaryAndLock (fname); int fileno = _fileno(file); @@ -1153,8 +1174,8 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, (bps == 16 || bps == 32) && isFloat ? PREDICTOR_FLOATINGPOINT : PREDICTOR_HORIZONTAL); } - if (profileData) { - TIFFSetField (out, TIFFTAG_ICCPROFILE, profileLength, profileData); + if (!profileData.empty()) { + TIFFSetField (out, TIFFTAG_ICCPROFILE, profileData.size(), profileData.data()); } for (int row = 0; row < height; row++) { @@ -1338,7 +1359,6 @@ void ImageIO::deleteLoadedProfileData( ) loadedProfileData = nullptr; } - bool ImageIO::saveMetadata(const Glib::ustring &fname) const { if (metadataInfo.filename().empty()) { @@ -1351,15 +1371,16 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const src->readMetadata(); dst->setMetadata(*src); dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; - for (auto &p : metadataInfo.exif()) { + for (const auto& p : metadataInfo.exif()) { try { dst->exifData()[p.first] = p.second; - } catch (Exiv2::AnyError &exc) {} + } catch (const Exiv2::AnyError& exc) { + } } - for (auto &p : metadataInfo.iptc()) { + for (const auto& p : metadataInfo.iptc()) { try { - auto &v = p.second; - if (v.size() >= 1) { + auto& v = p.second; + if (!v.empty()) { dst->iptcData()[p.first] = v[0]; for (size_t j = 1; j < v.size(); ++j) { Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); @@ -1367,11 +1388,12 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const dst->iptcData().add(d); } } - } catch (Exiv2::AnyError &exc) {} + } catch (const Exiv2::AnyError& exc) { + } } dst->writeMetadata(); return true; - } catch (Exiv2::AnyError &exc) { + } catch (const Exiv2::AnyError& exc) { std::cout << "EXIF ERROR: " << exc.what() << std::endl; return false; } diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 0bdb7d43a..f0eafc701 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -31,35 +31,44 @@ #include #include -#include "rtengine.h" -#include "imageformat.h" -#include "imagedimensions.h" -#include "iimage.h" + #include "colortemp.h" -#include "procparams.h" +#include "iimage.h" +#include "imagedimensions.h" +#include "imageformat.h" +#include "rtengine.h" namespace rtengine { +namespace procparams +{ + +class ExifPairs; +class IPTCPairs; + +} + class ProgressListener; class Imagefloat; -class MetadataInfo { +class MetadataInfo final +{ public: - explicit MetadataInfo(const Glib::ustring &src=Glib::ustring()): - src_(src) {} + explicit MetadataInfo(const Glib::ustring& src = {}); - const Glib::ustring &filename() const { return src_; } + const Glib::ustring& filename() const; - const rtengine::procparams::ExifPairs &exif() const { return exif_; } - const rtengine::procparams::IPTCPairs &iptc() const { return iptc_; } - void setExif(const rtengine::procparams::ExifPairs &exif) { exif_ = exif; } - void setIptc(const rtengine::procparams::IPTCPairs &iptc) { iptc_ = iptc; } + const rtengine::procparams::ExifPairs& exif() const; + const rtengine::procparams::IPTCPairs& iptc() const; + + void setExif(const rtengine::procparams::ExifPairs &exif); + void setIptc(const rtengine::procparams::IPTCPairs &iptc); private: Glib::ustring src_; - rtengine::procparams::ExifPairs exif_; - rtengine::procparams::IPTCPairs iptc_; + std::unique_ptr exif_; + std::unique_ptr iptc_; }; class ImageIO : virtual public ImageDatas @@ -68,7 +77,7 @@ class ImageIO : virtual public ImageDatas protected: ProgressListener* pl; cmsHPROFILE embProfile; - char* profileData; + std::string profileData; int profileLength; char* loadedProfileData; bool loadedProfileDataJpg; @@ -82,8 +91,6 @@ private: void deleteLoadedProfileData( ); public: - static Glib::ustring errorMsg[6]; - ImageIO(); ~ImageIO() override; @@ -118,8 +125,8 @@ public: cmsHPROFILE getEmbeddedProfile () const; void getEmbeddedProfileData (int& length, unsigned char*& pdata) const; - void setMetadata(const MetadataInfo &info) { metadataInfo = info; } - void setOutputProfile (const char* pdata, int plen); + void setMetadata(MetadataInfo info); + void setOutputProfile(const std::string& pdata); bool saveMetadata(const Glib::ustring &fname) const; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index a18cca9d7..8ce3ee2e9 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -153,7 +153,7 @@ public: { outCurve = { 0.0 }; } - + double getDirPyrDenoiseExpComp ( ) { return dirpyrdenoiseExpComp; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 079c5cb48..98ed2eaf0 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1403,7 +1403,6 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a im = tempImage; } - // im->setMetadata(imgsrc->getMetaData()->getRootExifData()); im->setMetadata(MetadataInfo(imgsrc->getFileName())); im->saveTIFF(fname, 16, false, true); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8dd57e74d..669037021 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5656,6 +5656,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_size) { if (fname != "") { + // TODO: std::unique_ptr<> to the rescue int w_raw = -1, h_raw = thumb_size; int w_thumb = -1, h_thumb = thumb_size; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f9daead22..3003cf3e0 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -295,15 +295,14 @@ bool saveToKeyfile( return false; } - -const std::map exif_keys = { +const std::map exif_keys = { {"Copyright", "Exif.Image.Copyright"}, {"Artist", "Exif.Image.Artist"}, {"ImageDescription", "Exif.Image.ImageDescription"}, {"Exif.UserComment", "Exif.Photo.UserComment"} }; -const std::map iptc_keys = { +const std::map iptc_keys = { {"Title", "Iptc.Application2.ObjectName"}, {"Category", "Iptc.Application2.Category"}, {"SupplementalCategories", "Iptc.Application2.SuppCategory"}, @@ -3168,9 +3167,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Dehaze saveToKeyfile(!pedited || pedited->dehaze.enabled, "Dehaze", "Enabled", dehaze.enabled, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); // Directional pyramid denoising saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile); @@ -3611,7 +3610,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // IPTC change list if (!pedited || pedited->iptc) { - std::map m; + std::map m; for (auto &p : iptc_keys) { m[p.second] = p.first; } @@ -4800,7 +4799,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap); assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth); } - + 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); @@ -5193,6 +5192,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (it == iptc_keys.end()) { continue; } + auto kk = it->second; const IPTCPairs::iterator element = iptc.find(kk); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 951b02b1a..07ec2a5fa 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1075,8 +1075,104 @@ struct MetaDataParams { }; -typedef std::map ExifPairs; -typedef std::map> IPTCPairs; +/** + * Minimal wrapper allowing forward declaration for representing a key/value for the exif metadata information + */ +class ExifPairs final +{ +private: + using Pairs = std::map; + +public: + using const_iterator = Pairs::const_iterator; + using size_type = Pairs::size_type; + + const_iterator find(const Glib::ustring& key) const + { + return pairs.find(key); + } + + const_iterator begin() const + { + return pairs.begin(); + } + + const_iterator end() const + { + return pairs.end(); + } + + void clear() + { + pairs.clear(); + } + + size_type erase(const Glib::ustring& key) + { + return pairs.erase(key); + } + + Glib::ustring& operator[](const Glib::ustring& key) + { + return pairs[key]; + } + + bool operator ==(const ExifPairs& other) const + { + return pairs == other.pairs; + } + +private: + Pairs pairs; +}; + +/** + * The IPTC key/value pairs + */ +class IPTCPairs final +{ +public: + using iterator = std::map>::iterator; + using const_iterator = std::map>::const_iterator; + + iterator find(const Glib::ustring& key) + { + return pairs.find(key); + } + + const_iterator begin() const + { + return pairs.begin(); + } + + const_iterator end() const + { + return pairs.end(); + } + + bool empty() const + { + return pairs.empty(); + } + + void clear() + { + pairs.clear(); + } + + std::vector& operator[](const Glib::ustring& key) + { + return pairs[key]; + } + + bool operator ==(const IPTCPairs& other) const + { + return pairs == other.pairs; + } + +private: + std::map> pairs; +}; struct WaveletParams { std::vector ccwcurve; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 5efb3249c..d605e602c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -726,7 +726,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima rm *= expcomp; gm *= expcomp; bm *= expcomp; - + #ifdef _OPENMP #pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) { @@ -1693,7 +1693,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) // Load complete Exif information - idata = new FramesData (fname); + idata = new FramesData(fname); // TODO: std::unique_ptr<> idata->setDCRawFrameCount (numFrames); green(W, H); @@ -1931,16 +1931,16 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (!bitmapBads) { bitmapBads = new PixelsMap(W, H); } - + int n = f.mark(rawData, *bitmapBads); totBP += n; if (n > 0) { if (settings->verbose) { - printf("Marked %d hot pixels from PDAF lines\n", n); + printf("Marked %d hot pixels from PDAF lines\n", n); } - auto &thresh = f.greenEqThreshold(); + auto &thresh = f.greenEqThreshold(); if (numFrames == 4) { for (int i = 0; i < 4; ++i) { green_equilibrate(thresh, *rawDataFrames[i]); @@ -1959,7 +1959,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le CameraConst *cc = ccs->get(ri->get_maker().c_str(), ri->get_model().c_str()); return cc && cc->get_globalGreenEquilibration(); }; - + if ( ri->getSensorType() == ST_BAYER && (raw.bayersensor.greenthresh || (globalGreenEq() && raw.bayersensor.method != RAWParams::BayerSensor::getMethodString( RAWParams::BayerSensor::Method::VNG4))) ) { if (settings->verbose) { printf("Performing global green equilibration...\n"); @@ -4120,7 +4120,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen } } } - + lcmsMutex->lock (); switch (camera_icc_type) { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index b6b7402f9..bdb94fe4a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -47,15 +47,14 @@ enum RenderingIntent : int; namespace procparams { -typedef std::map ExifPairs; -typedef std::map> IPTCPairs; +class ProcParams; +class IPTCPairs; struct RAWParams; struct ColorManagementParams; struct CropParams; enum class ToneCurveMode : int; -class ProcParams; } @@ -140,7 +139,7 @@ public: * Use it only for raw files. In caseof jpgs and tiffs pass a NULL pointer. * @param firstFrameOnly must be true to get the MetaData of the first frame only, e.g. for a PixelShift file. * @return The metadata */ - static FramesMetaData* fromFile (const Glib::ustring& fname); + static FramesMetaData* fromFile(const Glib::ustring& fname); virtual Glib::ustring getFileName() const = 0; }; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index a3c9ec6ba..2a1024609 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -207,7 +207,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, if (std::max(img->getWidth(), img->getHeight()) / std::min(img->getWidth(), img->getHeight()) >= 10) { return nullptr; } - + Thumbnail* tpp = new Thumbnail (); unsigned char* data; @@ -315,7 +315,7 @@ namespace { Image8 *load_inspector_mode(const Glib::ustring &fname, eSensorType &sensorType, int &w, int &h) { BENCHFUN - + RawImageSource src; int err = src.load(fname, true); if (err) { @@ -324,7 +324,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, eSensorType &sensorType, src.getFullSize(w, h); sensorType = src.getSensorType(); - + ProcParams neutral; neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); @@ -389,7 +389,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType return tpp; } - + RawImage *ri = new RawImage (fname); unsigned int imageNum = 0; int r = ri->loadRaw (false, imageNum, false); @@ -442,7 +442,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType if (!forHistogramMatching && settings->thumbnail_inspector_mode == Settings::ThumbnailInspectorMode::RAW_IF_NOT_JPEG_FULLSIZE && float(std::max(w, h))/float(std::max(ri->get_width(), ri->get_height())) < 0.9f) { delete img; delete ri; - + img = load_inspector_mode(fname, sensorType, w, h); if (!img) { delete tpp; @@ -451,7 +451,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType tpp->scale = 1.; tpp->thumbImg = img; - + return tpp; } } else { @@ -1055,12 +1055,12 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int // Full thumbnail processing, second stage if complete profile exists IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool forHistogramMatching) { - std::string camName = metadata->getCamera(); - float shutter = metadata->getShutterSpeed(); - float fnumber = metadata->getFNumber(); - float iso = metadata->getISOSpeed(); - float fcomp = metadata->getExpComp(); - + const std::string camName = metadata->getCamera(); + const float shutter = metadata->getShutterSpeed(); + const float fnumber = metadata->getFNumber(); + const float iso = metadata->getISOSpeed(); + const float fcomp = metadata->getExpComp(); + // check if the WB's equalizer value has changed if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4) || wbTempBias < (params.wb.tempBias - 5e-4) || wbTempBias > (params.wb.tempBias + 5e-4)) { wbEqual = params.wb.equal; @@ -1155,7 +1155,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT float red = baseImg->r (i, j) * rmi; float green = baseImg->g (i, j) * gmi; float blue = baseImg->b (i, j) * bmi; - + // avoid magenta highlights if highlight recovery is enabled if (params.toneCurve.hrenabled && red > MAXVALF && blue > MAXVALF) { baseImg->r(i, j) = baseImg->g(i, j) = baseImg->b(i, j) = CLIP((red + green + blue) / 3.f); @@ -1192,7 +1192,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.dehaze(baseImg); ipf.ToneMapFattal02(baseImg); - + // perform transform if (ipf.needsTransform()) { Imagefloat* trImg = new Imagefloat (fw, fh); @@ -1343,7 +1343,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT } } - + // luminance processing // ipf.EPDToneMap(labView,0,6); @@ -1416,7 +1416,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.ciecam_02float (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, sk, execsharp, d, dj, yb, rtt); delete cieView; } - + // color processing //ipf.colorCurve (labView, labView); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 64edc5c17..35cf82068 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -776,7 +776,7 @@ private: params.toneCurve.brightness = 0; params.toneCurve.contrast = 0; params.toneCurve.black = 0; - } + } // at this stage, we can flush the raw data to free up quite an important amount of memory // commented out because it makes the application crash when batch processing... @@ -1151,10 +1151,10 @@ private: if (params.colorappearance.enabled) { double adap; - float fnum = imgsrc->getMetaData()->getFNumber (); // F number - float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO - float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; //speed - float fcomp = imgsrc->getMetaData()->getExpComp (); //compensation + - + const float fnum = imgsrc->getMetaData()->getFNumber(); // F number + const float fiso = imgsrc->getMetaData()->getISOSpeed() ; // ISO + const float fspeed = imgsrc->getMetaData()->getShutterSpeed() ; // Speed + const float fcomp = imgsrc->getMetaData()->getExpComp(); // Compensation + - if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { adap = 2000.; @@ -1295,12 +1295,12 @@ private: // Sending back the whole first root, which won't necessarily be the selected frame number // and may contain subframe depending on initial raw's hierarchy // readyImg->setMetadata (ii->getMetaData()->getRootExifData ()); - readyImg->setMetadata(info); + readyImg->setMetadata(std::move(info)); break; case MetaDataParams::EDIT: info.setExif(params.exif); info.setIptc(params.iptc); - readyImg->setMetadata(info); + readyImg->setMetadata(std::move(info)); // ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy // readyImg->setMetadata (ii->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); break; @@ -1315,7 +1315,7 @@ private: if (!useLCMS) { // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma ProfileContent pc (jprof); - readyImg->setOutputProfile (pc.getData().c_str(), pc.getData().size()); + readyImg->setOutputProfile (pc.getData()); } } else { // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma @@ -1335,11 +1335,11 @@ private: } ProfileContent pc = ICCStore::getInstance()->getContent (params.icm.outputProfile); - readyImg->setOutputProfile (pc.getData().c_str(), pc.getData().size()); + readyImg->setOutputProfile (pc.getData()); } } else { // No ICM - readyImg->setOutputProfile (nullptr, 0); + readyImg->setOutputProfile ({}); } } diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 397bc1c48..6fe55c460 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -87,7 +87,6 @@ public: // FramesMetaData interface //------------------------------------------------------------------------- - /* unsigned int getRootCount () const override { return -1; } */ unsigned int getFrameCount () const override { return frameCount; } bool hasExif() const override { return false; } tm getDateTime() const override { return tm{}; } diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 661118e32..f4da2d4b1 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -16,13 +16,15 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + #include "exifpanel.h" #include "guiutils.h" #include "rtimage.h" #include "options.h" -#include "../rtengine/imagedata.h" +#include "../rtengine/imagedata.h" #include "../rtengine/procparams.h" using namespace rtengine; @@ -31,15 +33,15 @@ using namespace rtengine::procparams; ExifPanel::ExifPanel() : idata(nullptr), changeList(new rtengine::procparams::ExifPairs), - defChangeList(new rtengine::procparams::ExifPairs) + defChangeList(new rtengine::procparams::ExifPairs), + editableTags{ + {"Exif.Photo.UserComment", "User Comment"}, + {"Exif.Image.Artist", "Artist"}, + {"Exif.Image.Copyright", "Copyright"}, + {"Exif.Image.ImageDescription", "Image Description"} + } { - editable_ = { - { "Exif.Photo.UserComment", "User Comment" }, - { "Exif.Image.Artist", "Artist" }, - { "Exif.Image.Copyright", "Copyright" }, - { "Exif.Image.ImageDescription", "Image Description"} - }; - + exifTree = Gtk::manage (new Gtk::TreeView()); scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); @@ -57,7 +59,7 @@ ExifPanel::ExifPanel() : exifTree->set_model (exifTreeModel); exifTree->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_NONE); exifTree->set_show_expanders(false); - + keepicon = RTImage::createPixbufFromFile ("tick-small.png"); editicon = RTImage::createPixbufFromFile("add-small.png"); @@ -204,54 +206,61 @@ void ExifPanel::refreshTags() { Glib::RefPtr selection = exifTree->get_selection(); std::vector sel = selection->get_selected_rows(); - + exifTreeModel->clear(); - + if (!idata) { return; } - Glib::ustring fn = idata->getFileName(); + const Glib::ustring fn = idata->getFileName(); if (fn.empty()) { return; } std::unordered_set ed; - for (auto &p : editable_) { + for (const auto &p : editableTags) { ed.insert(p.first); } - + try { auto img = open_exiv2(fn); img->readMetadata(); - auto &exif = img->exifData(); - - for (auto &p : *changeList) { + auto& exif = img->exifData(); + + for (const auto& p : *changeList) { try { exif[p.first] = p.second; - } catch (Exiv2::AnyError &exc) { + } catch (const Exiv2::AnyError& exc) { } } - for (auto &p : editable_) { - auto pos = exif.findKey(Exiv2::ExifKey(p.first)); + for (const auto& p : editableTags) { + const auto pos = exif.findKey(Exiv2::ExifKey(p.first)); if (pos != exif.end() && pos->size()) { - bool edited = changeList->find(pos->key()) != changeList->end(); + const bool edited = changeList->find(pos->key()) != changeList->end(); addTag(pos->key(), pos->tagLabel(), pos->print(&exif), true, edited); } } - for (auto &tag : exif) { - bool editable = ed.find(tag.key()) != ed.end(); - if (!editable && !tag.tagLabel().empty() && tag.typeId() != Exiv2::undefined && - (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { + for (const auto& tag : exif) { + const bool editable = ed.find(tag.key()) != ed.end(); + if ( + !editable + && !tag.tagLabel().empty() + && tag.typeId() != Exiv2::undefined + && ( + tag.typeId() == Exiv2::asciiString + || tag.size() < 256 + ) + ) { addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); } } - } catch (Exiv2::AnyError &exc) { + } catch (const Exiv2::AnyError& exc) { return; } - for (auto &p : sel) { + for (const auto& p : sel) { exifTree->get_selection()->select(p); } } @@ -277,13 +286,13 @@ void ExifPanel::exifSelectionChanged () } -void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) +void ExifPanel::resetIt(const Gtk::TreeModel::const_iterator& iter) { if (!iter) { return; } - auto key = iter->get_value(exifColumns.key); + const auto key = iter->get_value(exifColumns.key); changeList->erase(key); } @@ -324,7 +333,7 @@ void ExifPanel::addPressed () Gtk::Label* tlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_SELECTTAG") + ":"); MyComboBoxText* tcombo = new MyComboBoxText (); - for (auto &p : editable_) { + for (const auto& p : editableTags) { tcombo->append(p.second); } @@ -339,11 +348,11 @@ void ExifPanel::addPressed () Glib::ustring sel; Glib::ustring val; { - Glib::RefPtr selection = exifTree->get_selection(); - std::vector rows = selection->get_selected_rows(); + const Glib::RefPtr selection = exifTree->get_selection(); + const std::vector rows = selection->get_selected_rows(); if (rows.size() == 1) { - Gtk::TreeModel::iterator iter = exifTreeModel->get_iter(rows[0]); + const Gtk::TreeModel::iterator iter = exifTreeModel->get_iter(rows[0]); if (iter->get_value(exifColumns.editable)) { sel = iter->get_value(exifColumns.key); val = iter->get_value(exifColumns.value_nopango); @@ -351,11 +360,11 @@ void ExifPanel::addPressed () } } - if (sel == "") { + if (sel.empty()) { tcombo->set_active(0); } else { - for (size_t i = 0; i < editable_.size(); ++i) { - if (editable_[i].first == sel) { + for (size_t i = 0; i < editableTags.size(); ++i) { + if (editableTags[i].first == sel) { tcombo->set_active(i); break; } @@ -375,8 +384,8 @@ void ExifPanel::addPressed () hb2->show (); if (dialog->run () == Gtk::RESPONSE_OK) { - auto key = editable_[tcombo->get_active_row_number()].first; - auto value = ventry->get_text(); + auto key = editableTags[tcombo->get_active_row_number()].first; + const auto value = ventry->get_text(); (*changeList)[key] = value; refreshTags(); notifyListener (); diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 97708ab7b..de2174f6b 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -20,11 +20,23 @@ #define _EXIFPANEL_ #include + #include -#include #include "toolpanel.h" +namespace rtengine +{ + +namespace procparams +{ + +class ExifPairs; + +} + +} + class ExifPanel : public Gtk::VBox, public ToolPanel { @@ -67,11 +79,11 @@ private: Gtk::Button* reset; Gtk::Button* resetAll; - std::vector> editable_; + const std::vector> editableTags; Gtk::TreeModel::Children addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); void refreshTags(); - void resetIt (Gtk::TreeModel::iterator iter); + void resetIt(const Gtk::TreeModel::const_iterator& iter); void resetPressed(); void resetAllPressed(); void addPressed(); diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 9e534db2f..fcdd97101 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -17,11 +17,13 @@ * along with RawTherapee. If not, see . */ #include + #include "iptcpanel.h" + #include "clipboard.h" #include "rtimage.h" -#include "../rtengine/imagedata.h" +#include "../rtengine/imagedata.h" #include "../rtengine/procparams.h" using namespace rtengine; @@ -71,11 +73,10 @@ const std::set iptc_keys = { } // namespace - IPTCPanel::IPTCPanel(): changeList(new rtengine::procparams::IPTCPairs), defChangeList(new rtengine::procparams::IPTCPairs), - embeddedData(new rtengine::procparams::IPTCPairs) + embeddedData(new rtengine::procparams::IPTCPairs) { set_spacing (4); @@ -493,13 +494,13 @@ void IPTCPanel::setImageData (const FramesMetaData* id) try { auto img = open_exiv2(id->getFileName()); img->readMetadata(); - auto &iptc = img->iptcData(); - for (auto &tag : iptc) { + auto& iptc = img->iptcData(); + for (const auto& tag : iptc) { if (iptc_keys.find(tag.key()) != iptc_keys.end()) { (*embeddedData)[tag.key()].push_back(tag.toString()); } } - } catch (Exiv2::AnyError &exc) { + } catch (const Exiv2::AnyError& exc) { embeddedData->clear(); } } diff --git a/rtgui/resize.cc b/rtgui/resize.cc index decbfb2f5..40d7ace56 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include + #include "resize.h" #include "eventmapper.h" diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index fe436b5ca..55a2ad9dd 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -18,7 +18,9 @@ */ #include + #include "shcselector.h" + #include "multilangmgr.h" #include "mycurve.h" diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 17667ea1a..ba335d215 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -15,28 +15,91 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "multilangmgr.h" -#include "thumbnail.h" -#include -#include -#include "options.h" -#include "../rtengine/mytime.h" #include #include +#include +#include + #include -#include "../rtengine/imagedata.h" -#include "../rtengine/procparams.h" + #include -#include "../rtengine/dynamicprofile.h" -#include "guiutils.h" +#include "thumbnail.h" + #include "batchqueue.h" #include "extprog.h" -#include "profilestorecombobox.h" -#include "procparamchangers.h" +#include "guiutils.h" +#include "multilangmgr.h" +#include "options.h" #include "ppversion.h" +#include "procparamchangers.h" +#include "profilestorecombobox.h" #include "version.h" +#include "../rtengine/dynamicprofile.h" +#include "../rtengine/imagedata.h" +#include "../rtengine/mytime.h" +#include "../rtengine/procparams.h" + +namespace { + +bool CPBDump( + const Glib::ustring& commFName, + const Glib::ustring& imageFName, + const Glib::ustring& profileFName, + const Glib::ustring& defaultPParams, + const CacheImageData* cfs, + bool flagMode +) +{ + const std::unique_ptr kf(new Glib::KeyFile); + + if (!kf) { + return false; + } + + // open the file in write mode + const std::unique_ptr f(g_fopen(commFName.c_str (), "wt"), &std::fclose); + + if (!f) { + printf ("CPBDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); + return false; + } + + try { + kf->set_string ("RT General", "CachePath", options.cacheBaseDir); + kf->set_string ("RT General", "AppVersion", RTVERSION); + kf->set_integer ("RT General", "ProcParamsVersion", PPVERSION); + kf->set_string ("RT General", "ImageFileName", imageFName); + kf->set_string ("RT General", "OutputProfileFileName", profileFName); + kf->set_string ("RT General", "DefaultProcParams", defaultPParams); + kf->set_boolean ("RT General", "FlaggingMode", flagMode); + + kf->set_integer ("Common Data", "FrameCount", cfs->frameCount); + kf->set_integer ("Common Data", "SampleFormat", cfs->sampleFormat); + kf->set_boolean ("Common Data", "IsHDR", cfs->isHDR); + kf->set_boolean ("Common Data", "IsPixelShift", cfs->isPixelShift); + kf->set_double ("Common Data", "FNumber", cfs->fnumber); + kf->set_double ("Common Data", "Shutter", cfs->shutter); + kf->set_double ("Common Data", "FocalLength", cfs->focalLen); + kf->set_integer ("Common Data", "ISO", cfs->iso); + kf->set_string ("Common Data", "Lens", cfs->lens); + kf->set_string ("Common Data", "Make", cfs->camMake); + kf->set_string ("Common Data", "Model", cfs->camModel); + + } catch (const Glib::KeyFileError&) { + } + + try { + fprintf (f.get(), "%s", kf->to_data().c_str()); + } catch (const Glib::KeyFileError&) { + } + + return true; +} + +} // namespace + using namespace rtengine::procparams; Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf) : @@ -219,67 +282,6 @@ const ProcParams& Thumbnail::getProcParamsU () return *pparams; // there is no valid pp to return, but we have to return something } - -namespace { - -bool CPBDump(const Glib::ustring &commFName, const Glib::ustring &imageFName, - const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, - const CacheImageData* cfs, const bool flagMode) -{ - const auto kf = new Glib::KeyFile; - - if (!kf) { - return false; - } - - FILE *f = nullptr; - - // open the file in write mode - f = g_fopen (commFName.c_str (), "wt"); - - if (f == nullptr) { - printf ("CPBDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); - delete kf; - return false; - } - - try { - - kf->set_string ("RT General", "CachePath", options.cacheBaseDir); - kf->set_string ("RT General", "AppVersion", RTVERSION); - kf->set_integer ("RT General", "ProcParamsVersion", PPVERSION); - kf->set_string ("RT General", "ImageFileName", imageFName); - kf->set_string ("RT General", "OutputProfileFileName", profileFName); - kf->set_string ("RT General", "DefaultProcParams", defaultPParams); - kf->set_boolean ("RT General", "FlaggingMode", flagMode); - - kf->set_integer ("Common Data", "FrameCount", cfs->frameCount); - kf->set_integer ("Common Data", "SampleFormat", cfs->sampleFormat); - kf->set_boolean ("Common Data", "IsHDR", cfs->isHDR); - kf->set_boolean ("Common Data", "IsPixelShift", cfs->isPixelShift); - kf->set_double ("Common Data", "FNumber", cfs->fnumber); - kf->set_double ("Common Data", "Shutter", cfs->shutter); - kf->set_double ("Common Data", "FocalLength", cfs->focalLen); - kf->set_integer ("Common Data", "ISO", cfs->iso); - kf->set_string ("Common Data", "Lens", cfs->lens); - kf->set_string ("Common Data", "Make", cfs->camMake); - kf->set_string ("Common Data", "Model", cfs->camModel); - - } catch (Glib::KeyFileError&) {} - - try { - fprintf (f, "%s", kf->to_data().c_str()); - } catch (Glib::KeyFileError&) {} - - fclose (f); - delete kf; - - return true; -} - - -} // namespace - /** @brief Create default params on demand and returns a new updatable object * * The loaded profile may be partial, but it return a complete ProcParams (i.e. without ParamsEdited) @@ -304,7 +306,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu const CacheImageData* cfs = getCacheImageData(); Glib::ustring defaultPparamsPath = options.findProfilePath(defProf); const bool create = (!hasProcParams() || force); - const bool run_cpb = false; //!options.CPBPath.empty() && !defaultPparamsPath.empty() && cfs && cfs->exifValid && create; + const bool run_cpb = false; const Glib::ustring outFName = (options.paramsLoadLocation == PLL_Input && options.saveParamsFile) ? @@ -313,16 +315,24 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu if (!run_cpb) { if (defProf == DEFPROFILE_DYNAMIC && create && cfs && cfs->exifValid) { - std::unique_ptr imageMetaData(rtengine::FramesMetaData::fromFile(fname)); - PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData.get()); - int err = pp->pparams->save(outFName); - pp->deleteInstance(); - delete pp; - if (!err) { + const auto pp_deleter = + [](PartialProfile* pp) + { + pp->deleteInstance(); + delete pp; + }; + const std::unique_ptr imageMetaData(rtengine::FramesMetaData::fromFile(fname)); + const std::unique_ptr pp( + imageMetaData + ? ProfileStore::getInstance()->loadDynamicProfile(imageMetaData.get()) + : nullptr, + pp_deleter + ); + if (pp && !pp->pparams->save(outFName)) { loadProcParams(); } } else if (create && defProf != DEFPROFILE_DYNAMIC) { - const PartialProfile *p = ProfileStore::getInstance()->getProfile(defProf); + const PartialProfile* const p = ProfileStore::getInstance()->getProfile(defProf); if (p && !p->pparams->save(outFName)) { loadProcParams(); } @@ -333,7 +343,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu CPBDump(tmpFileName, fname, outFName, defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension), cfs, flaggingMode); - + // For the filename etc. do NOT use streams, since they are not UTF8 safe Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\""); From 801e7b175e03fd3970ad9db9de08ddc092231f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Sun, 19 May 2019 22:12:27 +0200 Subject: [PATCH 003/326] `DCPMetadata` review --- rtengine/dcp.cc | 395 ++++++++++++++++++++++++++++-------------------- 1 file changed, 233 insertions(+), 162 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index c6c38077a..614c5a426 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -443,8 +443,9 @@ std::map getAliases(const Glib::ustring& profile_dir) return res; } -class DCPMetadata { - // TODO: Review +class DCPMetadata +{ +private: enum TagType { INVALID = 0, BYTE = 1, @@ -468,47 +469,46 @@ class DCPMetadata { }; public: - explicit DCPMetadata(FILE *file): order_(UNKNOWN), file_(file) {} + explicit DCPMetadata(FILE* file) : + file_(file), + order_(UNKNOWN) + { + } bool parse() { - int offset = 0; - FILE *f = file_; - - if (!f) { + if (!file_) { #ifndef NDEBUG - std::cerr << "ERROR : no file opened !" << std::endl; + std::cerr << "ERROR: No file opened." << std::endl; #endif return false; } + setlocale(LC_NUMERIC, "C"); // to set decimal point in sscanf // read tiff header - fseek(f, 0, SEEK_SET); - unsigned short bo; - fread(&bo, 1, 2, f); - order_ = ByteOrder(int(bo)); + std::fseek(file_, 0, SEEK_SET); + std::uint16_t bo; + std::fread(&bo, 1, 2, file_); + order_ = ByteOrder(bo); - get2(f, order_); - if (!offset) { - offset = get4(f, order_); - } + get2(); // Skip - // seek to IFD - fseek(f, offset, SEEK_SET); + // Seek to IFD + const std::size_t offset = get4(); + std::fseek(file_, offset, SEEK_SET); - // first read the IFD directory - int numtags = get2(f, order_); + // First read the IFD directory + const std::uint16_t numtags = get2(); - if (numtags <= 0 || numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit + if (numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit return false; } - int base = 0; - for (int i = 0; i < numtags; i++) { - Tag t; - if (parse_tag(t, f, base, order_)) { - tags_[t.id] = std::move(t); + for (std::uint16_t i = 0; i < numtags; ++i) { + Tag tag; + if (parseTag(tag)) { + tags_[tag.id] = std::move(tag); } } @@ -520,227 +520,298 @@ public: return tags_.find(id) != tags_.end(); } - std::string toString(int id) + std::string toString(int id) const { - auto it = tags_.find(id); - if (it != tags_.end()) { - auto &t = it->second; - if (t.type == ASCII) { - std::ostringstream buf; - unsigned char *value = &(t.value[0]); - buf << value; - return buf.str(); + const Tags::const_iterator tag = tags_.find(id); + if (tag != tags_.end()) { + if (tag->second.type == ASCII) { + return std::string(tag->second.value.begin(), tag->second.value.end()).c_str(); } } - return ""; + return {}; } - int toInt(int id, int ofs=0, TagType astype=INVALID) + std::int32_t toInt(int id, std::size_t offset = 0, TagType as_type = INVALID) const { - auto it = tags_.find(id); - if (it == tags_.end()) { + const Tags::const_iterator tag = tags_.find(id); + if (tag == tags_.end()) { return 0; } - auto &t = it->second; - int a; - unsigned char *value = &(t.value[0]); - - if (astype == INVALID) { - astype = t.type; + if (as_type == INVALID) { + as_type = tag->second.type; } - switch (astype) { - case SBYTE: - return reinterpret_cast(value)[ofs]; + switch (as_type) { + case SBYTE: { + if (offset < tag->second.value.size()) { + return static_cast(tag->second.value[offset]); + } + return 0; + } - case BYTE: - return value[ofs]; + case BYTE: { + if (offset < tag->second.value.size()) { + return tag->second.value[offset]; + } + return 0; + } - case SSHORT: - return int2_to_signed(sget2(value + ofs, order_)); + case SSHORT: { + if (offset + 1 < tag->second.value.size()) { + return static_cast(sget2(tag->second.value.data() + offset)); + } + return 0; + } - case SHORT: - return sget2(value + ofs, order_); + case SHORT: { + if (offset + 1 < tag->second.value.size()) { + return sget2(tag->second.value.data() + offset); + } + return 0; + } - case SLONG: - case LONG: - return sget4 (value + ofs, order_); + case SLONG: + case LONG: { + if (offset + 3 < tag->second.value.size()) { + return sget4(tag->second.value.data() + offset); + } + return 0; + } - case SRATIONAL: - case RATIONAL: - a = sget4(value + ofs + 4, order_); - return a == 0 ? 0 : int(sget4(value + ofs, order_)) / a; + case SRATIONAL: + case RATIONAL: { + if (offset + 7 < tag->second.value.size()) { + const std::uint32_t denominator = sget4(tag->second.value.data() + offset + 4); + return + denominator == 0 + ? 0 + : static_cast(sget4(tag->second.value.data() + offset)) / denominator; + } + return 0; + } - case FLOAT: - return toDouble(id, ofs); + case FLOAT: { + return toDouble(id, offset); + } - default: - return 0; + default: { + return 0; + } } } - int toShort(int id, int ofs=0) + int toShort(int id, std::size_t offset = 0) const { - return toInt(id, ofs, SHORT); + return toInt(id, offset, SHORT); } - double toDouble(int id, int ofs=0) + double toDouble(int id, std::size_t offset = 0) const { - auto it = tags_.find(id); - if (it == tags_.end()) { + const Tags::const_iterator tag = tags_.find(id); + if (tag == tags_.end()) { return 0.0; } - auto &t = it->second; + switch (tag->second.type) { + case SBYTE: { + if (offset < tag->second.value.size()) { + return static_cast(tag->second.value[offset]); + } + return 0.0; + } - union IntFloat { - uint32_t i; - float f; - } conv; + case BYTE: { + if (offset < tag->second.value.size()) { + return tag->second.value[offset]; + } + return 0.0; + } - int ud, dd; - unsigned char *value = &(t.value[0]); + case SSHORT: { + if (offset + 1 < tag->second.value.size()) { + return static_cast(sget2(tag->second.value.data() + offset)); + } + return 0.0; + } - switch (t.type) { - case SBYTE: - return int((reinterpret_cast (value))[ofs]); + case SHORT: { + if (offset + 1 < tag->second.value.size()) { + return sget2(tag->second.value.data() + offset); + } + return 0.0; + } - case BYTE: - return int(value[ofs]); + case SLONG: + case LONG: { + if (offset + 3 < tag->second.value.size()) { + return sget4(tag->second.value.data() + offset); + } + return 0.0; + } - case SSHORT: - return int2_to_signed(sget2(value + ofs, order_)); + case SRATIONAL: + case RATIONAL: { + if (offset + 7 < tag->second.value.size()) { + const std::int32_t numerator = sget4(tag->second.value.data() + offset); + const std::int32_t denominator = sget4(tag->second.value.data() + offset + 4); + return + denominator == 0 + ? 0.0 + : static_cast(numerator) / static_cast(denominator); + } + return 0.0; + } - case SHORT: - return sget2(value + ofs, order_); + case FLOAT: { + union IntFloat { + std::uint32_t i; + float f; + } conv; - case SLONG: - case LONG: - return sget4(value + ofs, order_); + conv.i = sget4(tag->second.value.data() + offset); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + } - case SRATIONAL: - case RATIONAL: - ud = sget4(value + ofs, order_); - dd = sget4(value + ofs + 4, order_); - return (dd ? double(ud)/double(dd) : 0.0); - - case FLOAT: - conv.i = sget4(value + ofs, order_); - return conv.f; // IEEE FLOATs are already C format, they just need a recast - - default: - return 0.; + default: { + return 0.0; + } } } - unsigned int getCount(int id) + unsigned int getCount(int id) const { - auto it = tags_.find(id); - if (it != tags_.end()) { - return it->second.count; + const Tags::const_iterator tag = tags_.find(id); + if (tag != tags_.end()) { + return tag->second.count; } return 0; } private: - static unsigned short sget2(unsigned char *s, ByteOrder order) + struct Tag { + int id; + std::vector value; + TagType type; + unsigned int count; + }; + + using Tags = std::unordered_map; + + std::uint16_t sget2(const std::uint8_t* s) const { - if (order == INTEL) { + if (order_ == INTEL) { return s[0] | s[1] << 8; } else { return s[0] << 8 | s[1]; } } - static int sget4(unsigned char *s, ByteOrder order) + std::uint32_t sget4(const std::uint8_t* s) const { - if (order == INTEL) { + if (order_ == INTEL) { return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; } else { return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } } - static unsigned short get2(FILE* f, ByteOrder order) + std::uint16_t get2() { - unsigned char str[2] = { 0xff, 0xff }; - fread (str, 1, 2, f); - return sget2(str, order); + std::uint16_t res = std::numeric_limits::max(); + std::fread(&res, 1, 2, file_); + return sget2(reinterpret_cast(&res)); } - static int get4(FILE *f, ByteOrder order) + std::uint32_t get4() { - unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; - fread (str, 1, 4, f); - return sget4 (str, order); - } - - static short int int2_to_signed(short unsigned int i) - { - union { - short unsigned int i; - short int s; - } u; - u.i = i; - return u.s; + std::uint32_t res = std::numeric_limits::max(); + std::fread(&res, 1, 4, file_); + return sget4(reinterpret_cast(&res)); } static int getTypeSize(TagType type) { - return ("11124811248484"[type < 14 ? type : 0] - '0'); - } + switch (type) { + case INVALID: + case BYTE: + case ASCII: + case SBYTE: + case UNDEFINED: { + return 1; + } - struct Tag { - int id; - std::vector value; - TagType type; - unsigned int count; + case SHORT: + case SSHORT: { + return 2; + } - Tag(): id(0), value(), type(INVALID), count(0) {} - }; + case LONG: + case SLONG: + case FLOAT: { + return 4; + } - bool parse_tag(Tag &t, FILE *f, int base, ByteOrder order) - { - t.id = get2(f, order); - t.type = (TagType)get2(f, order); - t.count = get4(f, order); - - if (!t.count) { - t.count = 1; + case RATIONAL: + case SRATIONAL: + case DOUBLE: { + return 8; + } } - // filter out invalid tags - // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, + return 1; + } + + bool parseTag(Tag& tag) + { + tag.id = get2(); + tag.type = TagType(get2()); + tag.count = std::max(1U, get4()); + + // Filter out invalid tags + // Note: The large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, // (only a small part of it will actually be parsed though) - if ((int)t.type < 1 || (int)t.type > 12 || t.count > 10 * 1024 * 1024) { - t.type = INVALID; + if ( + tag.type == INVALID + || tag.type > DOUBLE + || tag.count > 10 * 1024 * 1024 + ) { + tag.type = INVALID; return false; } - // store next Tag's position in file - int save = ftell(f) + 4; + // Store next Tag's position in file + const std::size_t saved_position = std::ftell(file_) + 4; - // load value field (possibly seek before) - int valuesize = t.count * getTypeSize(t.type); + // Load value field (possibly seek before) + const std::size_t value_size = tag.count * getTypeSize(tag.type); - if (valuesize > 4) { - fseek(f, get4(f, order) + base, SEEK_SET); + if (value_size > 4) { + if (std::fseek(file_, get4(), SEEK_SET) == -1) { + tag.type = INVALID; + return false; + } } - // read value - t.value.resize(valuesize + 1); - auto readSize = fread(&(t.value[0]), 1, valuesize, f); - t.value[readSize] = '\0'; + // Read value + tag.value.resize(value_size + 1); + const std::size_t read = std::fread(tag.value.data(), 1, value_size, file_); + if (read != value_size) { + tag.type = INVALID; + return false; + } + tag.value[read] = '\0'; + + // Seek back to the saved position + std::fseek(file_, saved_position, SEEK_SET); - // seek back to the saved position - fseek(f, save, SEEK_SET); return true; } - std::unordered_map tags_; + FILE* const file_; + + Tags tags_; ByteOrder order_; - FILE *file_; }; } // namespace From fa63b2f7a6a2cc949d9c8a072a88eacb57fb353e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 23 May 2019 15:34:06 +0200 Subject: [PATCH 004/326] Fix EXV_UNICODE_PATH `std::wstring` conversion --- rtengine/imagedata.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 1890739b8..6897490ac 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -41,8 +41,13 @@ extern const Settings *settings; Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) { #ifdef EXV_UNICODE_PATH - const auto* const ws = g_utf8_to_utf16(fname.c_str(), -1, NULL, NULL, NULL); - const std::wstring wfname(ws); + glong ws_size = 0; + gunichar2* const ws = g_utf8_to_utf16(fname.c_str(), -1, nullptr, &ws_size, nullptr); + std::wstring wfname; + wfname.reserve(ws_size); + for (glong i = 0; i < ws_size; ++i) { + wfname.push_back(ws[i]); + } g_free(ws); auto image = Exiv2::ImageFactory::open(wfname); #else From 55cc71608bf9e7ebb68909c948382ff3ee443d16 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 3 Sep 2019 22:10:04 +0200 Subject: [PATCH 005/326] Converting Glib's mutex (obsolete) to std::mutex (no issue) --- rtgui/guiutils.cc | 53 -------------------------------------- rtgui/threadutils.cc | 25 +++++++++--------- rtgui/threadutils.h | 28 +++++--------------- rtgui/thumbimageupdater.cc | 22 ++++++++-------- 4 files changed, 31 insertions(+), 97 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index ec0bf6588..48a01f040 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -83,59 +83,6 @@ void IdleRegister::destroy() mutex.unlock(); } -/* -gboolean giveMeAGo(void* data) { - GThreadLock *threadMutex = static_cast(data); - printf("A\n"); - Glib::Threads::Mutex::Lock GUILock(threadMutex->GUI); - printf("B\n"); - { - Glib::Threads::Mutex::Lock operationLock(threadMutex->operation); - printf("C\n"); - - threadMutex->operationCond.signal(); - printf("D\n"); - operationLock.release(); // because we're not sure that "lock" destructor happens here... - } - threadMutex->GUICond.wait(threadMutex->GUI); - printf("E\n"); - - GUILock.release(); - - return false; -} - -GThreadLock::GThreadLock() : sameThread(false) { - if (Glib::Threads::Thread::self() == mainThread) { - sameThread = true; - return; - } - - printf("10\n"); - { - Glib::Threads::Mutex::Lock operationLock(operation); - - printf("20\n"); - gdk_threads_add_idle(giveMeAGo, this); - - printf("30\n"); - operationCond.wait(operation); - printf("40\n"); - operationLock.release(); - } -} - -GThreadLock::~GThreadLock() { - if (!sameThread) { - printf("50\n"); - Glib::Threads::Mutex::Lock lock(GUI); - printf("60\n"); - GUICond.signal(); - printf("Fin\n"); - } -} -*/ - Glib::ustring escapeHtmlChars(const Glib::ustring &src) { diff --git a/rtgui/threadutils.cc b/rtgui/threadutils.cc index 7ba296081..4f8190c36 100644 --- a/rtgui/threadutils.cc +++ b/rtgui/threadutils.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include "threadutils.h" +#include #include #include @@ -67,7 +68,7 @@ void MyReaderLock::acquire () return; } - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); if (mutex.writerCount == 0) { // There's no writer operating, we can increment the writer count which will lock writers. @@ -95,7 +96,7 @@ void MyReaderLock::release () return; } - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // decrement the writer number first... --mutex.readerCount; @@ -105,7 +106,7 @@ void MyReaderLock::release () --mutex.writerCount; // ...and signal the next waiting reader/writer that it's free - mutex.cond.broadcast (); + mutex.cond.notify_one(); // notify_all ? } locked = false; @@ -117,7 +118,7 @@ void MyWriterLock::acquire () return; } - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // The writer count is not zero, so we have to wait for it to be zero again... while (mutex.writerCount != 0) { @@ -136,12 +137,12 @@ void MyWriterLock::release () return; } - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // Decrement the writer number first... if (--mutex.writerCount == 0) { // ...and if the writer count is zero again, we can wake up the next writer or reader. - mutex.cond.broadcast (); + mutex.cond.notify_one(); // notify_all ? } locked = false; @@ -170,7 +171,7 @@ void MyReaderLock::acquire (const char* file, int line) trace (file, line) << "Acquiring MyReaderLock..." << std::endl; - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); if (mutex.writerCount == 0) { // There's no writer operating, we can increment the writer count which will lock writers. @@ -211,7 +212,7 @@ void MyReaderLock::release (const char* file, int line) trace (file, line) << "Releasing MyReaderLock..." << std::endl; - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // decrement the writer number first... --mutex.readerCount; @@ -221,7 +222,7 @@ void MyReaderLock::release (const char* file, int line) --mutex.writerCount; // ...and signal the next waiting reader/writer that it's free - mutex.cond.broadcast (); + mutex.cond.notify_one(); // notify_all ? mutex.ownerThread = nullptr; mutex.lastWriterFile = ""; @@ -241,7 +242,7 @@ void MyWriterLock::acquire (const char* file, int line) trace (file, line) << "Acquiring MyWriterLock..." << std::endl; - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // The writer count is not zero, so we have to wait for it to be zero again... while (mutex.writerCount != 0) { @@ -273,12 +274,12 @@ void MyWriterLock::release (const char* file, int line) trace (file, line) << "Releasing MyWriterLock..." << std::endl; - Glib::Threads::Mutex::Lock lock (mutex.mutex); + std::lock_guard lock (mutex.mutex); // Decrement the writer number first... if (--mutex.writerCount == 0) { // ...and if the writer count is zero again, we can wake up the next writer or reader. - mutex.cond.broadcast (); + mutex.cond.notify_one(); // notify_all ? mutex.ownerThread = nullptr; mutex.lastWriterFile = ""; diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index 1215d53a1..f54cbb845 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -25,14 +25,14 @@ //#undef STRICT_MUTEX //#define STRICT_MUTEX 1 -#include - +#include +#include #include "../rtengine/noncopyable.h" #if STRICT_MUTEX && NDEBUG -using MyMutexBase = Glib::Threads::Mutex; +using MyMutexBase = std::mutex; #else -using MyMutexBase = Glib::Threads::RecMutex; +using MyMutexBase = std::recursive_mutex; #endif /** @@ -67,8 +67,6 @@ class MyMutex::MyLock : { public: explicit MyLock (MyMutex& mutex); - MyLock (MyMutex& mutex, Glib::Threads::NotLock); - MyLock (MyMutex& mutex, Glib::Threads::TryLock); ~MyLock (); @@ -92,8 +90,8 @@ public: friend class MyWriterLock; private: - Glib::Threads::Mutex mutex; - Glib::Threads::Cond cond; + std::mutex mutex; + std::condition_variable_any cond; std::size_t writerCount = 0; std::size_t readerCount = 0; @@ -168,7 +166,7 @@ inline void MyMutex::lock () inline bool MyMutex::trylock () { - if (MyMutexBase::trylock ()) { + if (MyMutexBase::try_lock ()) { #if STRICT_MUTEX && !NDEBUG checkLock (); #endif @@ -195,18 +193,6 @@ inline MyMutex::MyLock::MyLock (MyMutex& mutex) mutex.lock(); } -inline MyMutex::MyLock::MyLock (MyMutex& mutex, Glib::Threads::NotLock) - : mutex (mutex) - , locked (false) -{ -} - -inline MyMutex::MyLock::MyLock (MyMutex& mutex, Glib::Threads::TryLock) - : mutex (mutex) - , locked (mutex.trylock ()) -{ -} - inline MyMutex::MyLock::~MyLock () { if (locked) { diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index c0df751a5..590a7ae1c 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -83,9 +83,9 @@ public: Glib::ThreadPool* threadPool_; - // Need to be a Glib::Threads::Mutex because used in a Glib::Threads::Cond object... + // Need to be a std::mutex because used in a std::condition_variable_any object... // This is the only exceptions along with GThreadMutex (guiutils.cc), MyMutex is used everywhere else - Glib::Threads::Mutex mutex_; + std::mutex mutex_; JobList jobs_; @@ -93,7 +93,7 @@ public: bool inactive_waiting_; - Glib::Threads::Cond inactive_; + std::condition_variable_any inactive_; void processNextJob() @@ -101,7 +101,7 @@ public: Job j; { - Glib::Threads::Mutex::Lock lock(mutex_); + std::lock_guard lock(mutex_); // nothing to do; could be jobs have been removed if ( jobs_.empty() ) { @@ -164,10 +164,10 @@ public: } if ( --active_ == 0 ) { - Glib::Threads::Mutex::Lock lock(mutex_); + std::lock_guard lock(mutex_); if (inactive_waiting_) { inactive_waiting_ = false; - inactive_.broadcast(); + inactive_.notify_one(); // notify_all ? } } } @@ -196,7 +196,7 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg return; } - Glib::Threads::Mutex::Lock lock(impl_->mutex_); + std::lock_guard lock(impl_->mutex_); // look up if an older version is in the queue Impl::JobList::iterator i(impl_->jobs_.begin()); @@ -228,7 +228,7 @@ void ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener) DEBUG("removeJobs(%p)", listener); { - Glib::Threads::Mutex::Lock lock(impl_->mutex_); + std::lock_guard lock(impl_->mutex_); for( Impl::JobList::iterator i(impl_->jobs_.begin()); i != impl_->jobs_.end(); ) { if (i->listener_ == listener) { @@ -244,7 +244,7 @@ void ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener) while ( impl_->active_ != 0 ) { DEBUG("waiting for running jobs1"); { - Glib::Threads::Mutex::Lock lock(impl_->mutex_); + std::lock_guard lock(impl_->mutex_); impl_->inactive_waiting_ = true; impl_->inactive_.wait(impl_->mutex_); } @@ -256,7 +256,7 @@ void ThumbImageUpdater::removeAllJobs() DEBUG("stop"); { - Glib::Threads::Mutex::Lock lock(impl_->mutex_); + std::lock_guard lock(impl_->mutex_); impl_->jobs_.clear(); } @@ -264,7 +264,7 @@ void ThumbImageUpdater::removeAllJobs() while ( impl_->active_ != 0 ) { DEBUG("waiting for running jobs2"); { - Glib::Threads::Mutex::Lock lock(impl_->mutex_); + std::lock_guard lock(impl_->mutex_); impl_->inactive_waiting_ = true; impl_->inactive_.wait(impl_->mutex_); } From c6206ac3320542b76d51fea90ed5ca76aaaa7730 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 29 Dec 2019 10:55:21 +0100 Subject: [PATCH 006/326] Fix broken build, #5435 --- rtengine/profilestore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 460facb72..8cd5d2608 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include From d9799ec5de7f047ccee0496d2e9aa62fe2cd00ee Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 16 Oct 2020 12:39:17 +0200 Subject: [PATCH 007/326] Fix dcp.cc with some help from the implementation in ART --- clean.bat | 1 - rtengine/CMakeLists.txt | 1 - rtengine/dcp.cc | 660 ++++++++++++++++++---------------------- rtengine/dcp.h | 39 +-- rtengine/imageio.cc | 7 +- rtengine/rtengine.h | 6 - rtengine/rtthumbnail.h | 1 - rtgui/exifpanel.h | 1 - 8 files changed, 327 insertions(+), 389 deletions(-) diff --git a/clean.bat b/clean.bat index 52e77f954..7196af4b0 100644 --- a/clean.bat +++ b/clean.bat @@ -20,4 +20,3 @@ del .\rtdata\Makefile del .\rtengine\librtengine.so del .\rtengine\librtengine.a del .\rtgui\rawtherapee -del .\rtexif\librtexif.a diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index a4ab82f3d..43d658e66 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -1,4 +1,3 @@ -<<<<<<< HEAD if(EXTRA_INCDIR) include_directories("${EXTRA_INCDIR}") endif() diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 3c20ea0c1..7d9295c71 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -21,9 +21,7 @@ #include #include #include -#include -#include -#include +#include #include "dcp.h" @@ -35,9 +33,15 @@ #include "rawimagesource.h" #include "rt_math.h" #include "utils.h" -#include "../rtexif/rtexif.h" #include "../rtgui/options.h" +namespace rtengine +{ + +extern const Settings* settings; + +} + using namespace rtengine; namespace @@ -48,7 +52,7 @@ namespace DCPProfile::Matrix invert3x3(const DCPProfile::Matrix& a) { DCPProfile::Matrix res = a; - if (!invertMatrix(a, res)) { + if (!invertMatrix(a, res) && settings->verbose) { std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl; } return res; @@ -333,6 +337,8 @@ double xyCoordToTemperature(const std::array& white_xy) // Search for line pair coordinate is between. double last_dt = 0.0; + double last_dv = 0.0; + double last_du = 0.0; for (uint32_t index = 1; index <= 30; ++index) { // Convert slope to delta-u and delta-v, with length 1. @@ -368,11 +374,23 @@ double xyCoordToTemperature(const std::array& white_xy) // Interpolate the temperature. res = 1.0e6 / (temp_table[index - 1].r * f + temp_table[index].r * (1.0 - f)); + + // Find delta from black body point to test coordinate. + uu = u - (temp_table [index - 1].u * f + temp_table [index].u * (1.0 - f)); + vv = v - (temp_table [index - 1].v * f + temp_table [index].v * (1.0 - f)); + // Interpolate vectors along slope. + du = du * (1.0 - f) + last_du * f; + dv = dv * (1.0 - f) + last_dv * f; + len = sqrt (du * du + dv * dv); + du /= len; + dv /= len; break; } // Try next line pair. last_dt = dt; + last_du = du; + last_dv = dv; } return res; @@ -431,7 +449,6 @@ std::map getAliases(const Glib::ustring& profile_dir) class DCPMetadata { -private: enum TagType { INVALID = 0, BYTE = 1, @@ -455,17 +472,17 @@ private: }; public: - explicit DCPMetadata(FILE* file) : - file_(file), - order_(UNKNOWN) - { - } + explicit DCPMetadata(FILE *file): order_(UNKNOWN), file_(file) {} bool parse() { - if (!file_) { + int offset = 0; + FILE *f = file_; + if (!f) { #ifndef NDEBUG - std::cerr << "ERROR: No file opened." << std::endl; + if (settings->verbose) { + std::cerr << "ERROR : no file opened !" << std::endl; + } #endif return false; } @@ -473,28 +490,31 @@ public: setlocale(LC_NUMERIC, "C"); // to set decimal point in sscanf // read tiff header - std::fseek(file_, 0, SEEK_SET); - std::uint16_t bo; - std::fread(&bo, 1, 2, file_); - order_ = ByteOrder(bo); + fseek(f, 0, SEEK_SET); + unsigned short bo; + fread(&bo, 1, 2, f); + order_ = ByteOrder(int(bo)); + + get2(f, order_); + if (!offset) { + offset = get4(f, order_); + } - get2(); // Skip + // seek to IFD + fseek(f, offset, SEEK_SET); - // Seek to IFD - const std::size_t offset = get4(); - std::fseek(file_, offset, SEEK_SET); + // first read the IFD directory + int numtags = get2(f, order_); - // First read the IFD directory - const std::uint16_t numtags = get2(); - - if (numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit + if (numtags <= 0 || numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit return false; } - for (std::uint16_t i = 0; i < numtags; ++i) { - Tag tag; - if (parseTag(tag)) { - tags_[tag.id] = std::move(tag); + int base = 0; + for (int i = 0; i < numtags; i++) { + Tag t; + if (parse_tag(t, f, base, order_)) { + tags_[t.id] = std::move(t); } } @@ -505,304 +525,221 @@ public: { return tags_.find(id) != tags_.end(); } - - std::string toString(int id) const + + std::string toString(int id) { - const Tags::const_iterator tag = tags_.find(id); - if (tag != tags_.end()) { - if (tag->second.type == ASCII) { - return std::string(tag->second.value.begin(), tag->second.value.end()).c_str(); + auto it = tags_.find(id); + if (it != tags_.end()) { + auto &t = it->second; + if (t.type == ASCII) { + std::ostringstream buf; + unsigned char *value = &(t.value[0]); + buf << value; + return buf.str(); } } - return {}; + return ""; } - std::int32_t toInt(int id, std::size_t offset = 0, TagType as_type = INVALID) const + int toInt(int id, int ofs=0, TagType astype=INVALID) { - const Tags::const_iterator tag = tags_.find(id); - if (tag == tags_.end()) { + auto it = tags_.find(id); + if (it == tags_.end()) { return 0; } - if (as_type == INVALID) { - as_type = tag->second.type; + auto &t = it->second; + int a; + unsigned char *value = &(t.value[0]); + + if (astype == INVALID) { + astype = t.type; } - switch (as_type) { - case SBYTE: { - if (offset < tag->second.value.size()) { - return static_cast(tag->second.value[offset]); - } - return 0; - } - - case BYTE: { - if (offset < tag->second.value.size()) { - return tag->second.value[offset]; - } - return 0; - } - - case SSHORT: { - if (offset + 1 < tag->second.value.size()) { - return static_cast(sget2(tag->second.value.data() + offset)); - } - return 0; - } - - case SHORT: { - if (offset + 1 < tag->second.value.size()) { - return sget2(tag->second.value.data() + offset); - } - return 0; - } - - case SLONG: - case LONG: { - if (offset + 3 < tag->second.value.size()) { - return sget4(tag->second.value.data() + offset); - } - return 0; - } - - case SRATIONAL: - case RATIONAL: { - if (offset + 7 < tag->second.value.size()) { - const std::uint32_t denominator = sget4(tag->second.value.data() + offset + 4); - return - denominator == 0 - ? 0 - : static_cast(sget4(tag->second.value.data() + offset)) / denominator; - } - return 0; - } - - case FLOAT: { - return toDouble(id, offset); - } - - default: { - return 0; - } + switch (astype) { + case SBYTE: + return reinterpret_cast(value)[ofs]; + case BYTE: + return value[ofs]; + case SSHORT: + return int2_to_signed(sget2(value + ofs, order_)); + case SHORT: + return sget2(value + ofs, order_); + case SLONG: + case LONG: + return sget4 (value + ofs, order_); + case SRATIONAL: + case RATIONAL: + a = sget4(value + ofs + 4, order_); + return a == 0 ? 0 : int(sget4(value + ofs, order_)) / a; + case FLOAT: + return toDouble(id, ofs); + default: + return 0; + } } - - int toShort(int id, std::size_t offset = 0) const + + int toShort(int id, int ofs=0) { - return toInt(id, offset, SHORT); + return toInt(id, ofs, SHORT); } - - double toDouble(int id, std::size_t offset = 0) const + + double toDouble(int id, int ofs=0) { - const Tags::const_iterator tag = tags_.find(id); - if (tag == tags_.end()) { + auto it = tags_.find(id); + if (it == tags_.end()) { return 0.0; } - switch (tag->second.type) { - case SBYTE: { - if (offset < tag->second.value.size()) { - return static_cast(tag->second.value[offset]); - } - return 0.0; - } + auto &t = it->second; + + union IntFloat { + uint32_t i; + float f; + } conv; - case BYTE: { - if (offset < tag->second.value.size()) { - return tag->second.value[offset]; - } - return 0.0; - } - - case SSHORT: { - if (offset + 1 < tag->second.value.size()) { - return static_cast(sget2(tag->second.value.data() + offset)); - } - return 0.0; - } - - case SHORT: { - if (offset + 1 < tag->second.value.size()) { - return sget2(tag->second.value.data() + offset); - } - return 0.0; - } - - case SLONG: - case LONG: { - if (offset + 3 < tag->second.value.size()) { - return sget4(tag->second.value.data() + offset); - } - return 0.0; - } - - case SRATIONAL: - case RATIONAL: { - if (offset + 7 < tag->second.value.size()) { - const std::int32_t numerator = sget4(tag->second.value.data() + offset); - const std::int32_t denominator = sget4(tag->second.value.data() + offset + 4); - return - denominator == 0 - ? 0.0 - : static_cast(numerator) / static_cast(denominator); - } - return 0.0; - } - - case FLOAT: { - union IntFloat { - std::uint32_t i; - float f; - } conv; - - conv.i = sget4(tag->second.value.data() + offset); - return conv.f; // IEEE FLOATs are already C format, they just need a recast - } - - default: { - return 0.0; - } + int ud, dd; + unsigned char *value = &(t.value[0]); + + switch (t.type) { + case SBYTE: + return int((reinterpret_cast (value))[ofs]); + case BYTE: + return int(value[ofs]); + case SSHORT: + return int2_to_signed(sget2(value + ofs, order_)); + case SHORT: + return sget2(value + ofs, order_); + case SLONG: + case LONG: + return sget4(value + ofs, order_); + case SRATIONAL: + case RATIONAL: + ud = sget4(value + ofs, order_); + dd = sget4(value + ofs + 4, order_); + return (dd ? double(ud)/double(dd) : 0.0); + case FLOAT: + conv.i = sget4(value + ofs, order_); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + default: + return 0.; + } } - unsigned int getCount(int id) const + unsigned int getCount(int id) { - const Tags::const_iterator tag = tags_.find(id); - if (tag != tags_.end()) { - return tag->second.count; + auto it = tags_.find(id); + if (it != tags_.end()) { + return it->second.count; } return 0; } private: - struct Tag { - int id; - std::vector value; - TagType type; - unsigned int count; - }; - - using Tags = std::unordered_map; - - std::uint16_t sget2(const std::uint8_t* s) const + static unsigned short sget2(unsigned char *s, ByteOrder order) { - if (order_ == INTEL) { + if (order == INTEL) { return s[0] | s[1] << 8; } else { return s[0] << 8 | s[1]; } } - - std::uint32_t sget4(const std::uint8_t* s) const + + static int sget4(unsigned char *s, ByteOrder order) { - if (order_ == INTEL) { + if (order == INTEL) { return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; } else { return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } } - - std::uint16_t get2() - { - std::uint16_t res = std::numeric_limits::max(); - std::fread(&res, 1, 2, file_); - return sget2(reinterpret_cast(&res)); + + static unsigned short get2(FILE* f, ByteOrder order) + { + unsigned char str[2] = { 0xff, 0xff }; + fread (str, 1, 2, f); + return sget2(str, order); } - - std::uint32_t get4() + + static int get4(FILE *f, ByteOrder order) + { + unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; + fread (str, 1, 4, f); + return sget4 (str, order); + } + + static short int int2_to_signed(short unsigned int i) { - std::uint32_t res = std::numeric_limits::max(); - std::fread(&res, 1, 4, file_); - return sget4(reinterpret_cast(&res)); + union { + short unsigned int i; + short int s; + } u; + u.i = i; + return u.s; } static int getTypeSize(TagType type) { - switch (type) { - case INVALID: - case BYTE: - case ASCII: - case SBYTE: - case UNDEFINED: { - return 1; - } - - case SHORT: - case SSHORT: { - return 2; - } - - case LONG: - case SLONG: - case FLOAT: { - return 4; - } - - case RATIONAL: - case SRATIONAL: - case DOUBLE: { - return 8; - } - } - - return 1; + return ("11124811248484"[type < 14 ? type : 0] - '0'); } - bool parseTag(Tag& tag) + struct Tag { + int id; + std::vector value; + TagType type; + unsigned int count; + + Tag(): id(0), value(), type(INVALID), count(0) {} + }; + + bool parse_tag(Tag &t, FILE *f, int base, ByteOrder order) { - tag.id = get2(); - tag.type = TagType(get2()); - tag.count = std::max(1U, get4()); + t.id = get2(f, order); + t.type = (TagType)get2(f, order); + t.count = get4(f, order); - // Filter out invalid tags - // Note: The large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, + if (!t.count) { + t.count = 1; + } + + // filter out invalid tags + // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, // (only a small part of it will actually be parsed though) - if ( - tag.type == INVALID - || tag.type > DOUBLE - || tag.count > 10 * 1024 * 1024 - ) { - tag.type = INVALID; + if ((int)t.type < 1 || (int)t.type > 12 || t.count > 10 * 1024 * 1024) { + t.type = INVALID; return false; } - // Store next Tag's position in file - const std::size_t saved_position = std::ftell(file_) + 4; + // store next Tag's position in file + int save = ftell(f) + 4; - // Load value field (possibly seek before) - const std::size_t value_size = tag.count * getTypeSize(tag.type); + // load value field (possibly seek before) + int valuesize = t.count * getTypeSize(t.type); - if (value_size > 4) { - if (std::fseek(file_, get4(), SEEK_SET) == -1) { - tag.type = INVALID; - return false; - } + if (valuesize > 4) { + fseek(f, get4(f, order) + base, SEEK_SET); } - // Read value - tag.value.resize(value_size + 1); - const std::size_t read = std::fread(tag.value.data(), 1, value_size, file_); - if (read != value_size) { - tag.type = INVALID; - return false; - } - tag.value[read] = '\0'; - - // Seek back to the saved position - std::fseek(file_, saved_position, SEEK_SET); + // read value + t.value.resize(valuesize + 1); + auto readSize = fread(&(t.value[0]), 1, valuesize, f); + t.value[readSize] = '\0'; + // seek back to the saved position + fseek(f, save, SEEK_SET); return true; } - FILE* const file_; - - Tags tags_; + std::unordered_map tags_; ByteOrder order_; + FILE *file_; }; } // namespace -struct DCPProfileApplyState::Data { +struct DCPProfile::ApplyState::Data { float pro_photo[3][3]; float work[3][3]; bool already_pro_photo; @@ -811,12 +748,14 @@ struct DCPProfileApplyState::Data { float bl_scale; }; -DCPProfileApplyState::DCPProfileApplyState() : +DCPProfile::ApplyState::ApplyState() : data(new Data{}) { } -DCPProfileApplyState::~DCPProfileApplyState() = default; +DCPProfile::ApplyState::~ApplyState() +{ +} DCPProfile::DCPProfile(const Glib::ustring& filename) : has_color_matrix_1(false), @@ -833,22 +772,22 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : constexpr int tiff_float_size = 4; enum TagKey { - TAG_KEY_COLOR_MATRIX_1 = 50721, - TAG_KEY_COLOR_MATRIX_2 = 50722, - TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS = 50937, - TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1 = 50938, - TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2 = 50939, - TAG_KEY_PROFILE_TONE_CURVE = 50940, - TAG_KEY_PROFILE_TONE_COPYRIGHT = 50942, - TAG_KEY_CALIBRATION_ILLUMINANT_1 = 50778, - TAG_KEY_CALIBRATION_ILLUMINANT_2 = 50779, - TAG_KEY_FORWARD_MATRIX_1 = 50964, - TAG_KEY_FORWARD_MATRIX_2 = 50965, - TAG_KEY_PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant - TAG_KEY_PROFILE_LOOK_TABLE_DATA = 50982, - TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING = 51107, - TAG_KEY_PROFILE_LOOK_TABLE_ENCODING = 51108, - TAG_KEY_BASELINE_EXPOSURE_OFFSET = 51109 + COLOR_MATRIX_1 = 50721, + COLOR_MATRIX_2 = 50722, + PROFILE_HUE_SAT_MAP_DIMS = 50937, + PROFILE_HUE_SAT_MAP_DATA_1 = 50938, + PROFILE_HUE_SAT_MAP_DATA_2 = 50939, + PROFILE_TONE_CURVE = 50940, + PROFILE_TONE_COPYRIGHT = 50942, + CALIBRATION_ILLUMINANT_1 = 50778, + CALIBRATION_ILLUMINANT_2 = 50779, + FORWARD_MATRIX_1 = 50964, + FORWARD_MATRIX_2 = 50965, + PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant + PROFILE_LOOK_TABLE_DATA = 50982, + PROFILE_HUE_SAT_MAP_ENCODING = 51107, + PROFILE_LOOK_TABLE_ENCODING = 51108, + BASELINE_EXPOSURE_OFFSET = 51109 }; static const float adobe_camera_raw_default_curve[] = { @@ -1114,53 +1053,55 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : FILE* const file = g_fopen(filename.c_str(), "rb"); if (file == nullptr) { - printf ("Unable to load DCP profile '%s' !", filename.c_str()); + //printf ("Unable to load DCP profile '%s' !", filename.c_str()); return; } DCPMetadata md(file); if (!md.parse()) { - printf ("Unable to load DCP profile '%s'.", filename.c_str()); + //printf ("Unable to load DCP profile '%s'.", filename.c_str()); return; } light_source_1 = - md.find(TAG_KEY_CALIBRATION_ILLUMINANT_1) - ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_1) - : -1; + md.find(CALIBRATION_ILLUMINANT_1) ? + md.toShort(CALIBRATION_ILLUMINANT_1) : + -1; light_source_2 = - md.find(TAG_KEY_CALIBRATION_ILLUMINANT_2) - ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_2) - : -1; + md.find(CALIBRATION_ILLUMINANT_2) ? + md.toShort(CALIBRATION_ILLUMINANT_2) : + -1; temperature_1 = calibrationIlluminantToTemperature(light_source_1); temperature_2 = calibrationIlluminantToTemperature(light_source_2); - const bool has_second_hue_sat = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat + const bool has_second_hue_sat = md.find(PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat // Fetch Forward Matrices, if any - has_forward_matrix_1 = md.find(TAG_KEY_FORWARD_MATRIX_1); + has_forward_matrix_1 = md.find(FORWARD_MATRIX_1); if (has_forward_matrix_1) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_1[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_1, (col + row * 3) * 8); + forward_matrix_1[row][col] = md.toDouble(FORWARD_MATRIX_1, (col + row * 3) * 8); } } } - has_forward_matrix_2 = md.find(TAG_KEY_FORWARD_MATRIX_2); + has_forward_matrix_2 = md.find(FORWARD_MATRIX_2); if (has_forward_matrix_2) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_2[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_2, (col + row * 3) * 8); + forward_matrix_2[row][col] = md.toDouble(FORWARD_MATRIX_2, (col + row * 3) * 8); } } } // 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 (!md.find(COLOR_MATRIX_1)) { + if (settings->verbose) { + std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; + } fclose(file); return; } @@ -1169,24 +1110,24 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - color_matrix_1[row][col] = md.toDouble(TAG_KEY_COLOR_MATRIX_1, (col + row * 3) * 8); + color_matrix_1[row][col] = md.toDouble(COLOR_MATRIX_1, (col + row * 3) * 8); } } - if (md.find(TAG_KEY_PROFILE_LOOK_TABLE_DIMS)) { - look_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 0); - look_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 4); - look_info.val_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 8); + if (md.find(PROFILE_LOOK_TABLE_DIMS)) { + look_info.hue_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 0); + look_info.sat_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 4); + look_info.val_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 8); - look_info.srgb_gamma = md.find(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING) && md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING); + look_info.srgb_gamma = md.find(PROFILE_LOOK_TABLE_ENCODING) && md.toInt(PROFILE_LOOK_TABLE_ENCODING); - look_info.array_count = md.getCount(TAG_KEY_PROFILE_LOOK_TABLE_DATA) / 3; + look_info.array_count = md.getCount(PROFILE_LOOK_TABLE_DATA) / 3; look_table.resize(look_info.array_count); for (unsigned int i = 0; i < look_info.array_count; i++) { - look_table[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); - look_table[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); - look_table[i].val_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); + look_table[i].hue_shift = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); + look_table[i].sat_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); + look_table[i].val_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); } // Precalculated constants for table application @@ -1203,20 +1144,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : look_info.pc.val_step = look_info.hue_divisions * look_info.pc.hue_step; } - if (md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS)) { - delta_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 0); - delta_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 4); - delta_info.val_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 8); + if (md.find(PROFILE_HUE_SAT_MAP_DIMS)) { + delta_info.hue_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 0); + delta_info.sat_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 4); + delta_info.val_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 8); - delta_info.srgb_gamma = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING); + delta_info.srgb_gamma = md.find(PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(PROFILE_HUE_SAT_MAP_ENCODING); - delta_info.array_count = md.getCount(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1) / 3; + delta_info.array_count = md.getCount(PROFILE_HUE_SAT_MAP_DATA_1) / 3; deltas_1.resize(delta_info.array_count); for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_1[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); - deltas_1[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); - deltas_1[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); + deltas_1[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); + deltas_1[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); + deltas_1[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); } delta_info.pc.h_scale = @@ -1236,14 +1177,14 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Second matrix has_color_matrix_2 = true; - const bool cm2 = md.find(TAG_KEY_COLOR_MATRIX_2); + bool cm2 = md.find(COLOR_MATRIX_2); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { color_matrix_2[row][col] = cm2 - ? md.toDouble(TAG_KEY_COLOR_MATRIX_2, (col + row * 3) * 8) - : color_matrix_1[row][col]; + ? md.toDouble(COLOR_MATRIX_2, (col + row * 3) * 8) + : color_matrix_1[row][col]; } } @@ -1253,20 +1194,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Saturation maps. Need to be unwinded. for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_2[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); - deltas_2[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); - deltas_2[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); + deltas_2[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); + deltas_2[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); + deltas_2[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); } } } - has_baseline_exposure_offset = md.find(TAG_KEY_BASELINE_EXPOSURE_OFFSET); + has_baseline_exposure_offset = md.find(BASELINE_EXPOSURE_OFFSET); if (has_baseline_exposure_offset) { - baseline_exposure_offset = md.toDouble(TAG_KEY_BASELINE_EXPOSURE_OFFSET); + baseline_exposure_offset = md.toDouble(BASELINE_EXPOSURE_OFFSET); } // Read tone curve points, if any, but disable to RTs own profiles - if (md.find(TAG_KEY_PROFILE_TONE_CURVE)) { + if (md.find(PROFILE_TONE_CURVE)) { std::vector curve_points = { static_cast(DCT_Spline) // The first value is the curve type }; @@ -1274,9 +1215,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Push back each X/Y coordinates in a loop bool curve_is_linear = true; - for (unsigned int i = 0, n = md.getCount(TAG_KEY_PROFILE_TONE_CURVE); i < n; i += 2) { - const double x = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); - const double y = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); + for (unsigned int i = 0, n = md.getCount(PROFILE_TONE_CURVE); i < n; i += 2) { + const double x = md.toDouble(PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); + const double y = md.toDouble(PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); if (x != y) { curve_is_linear = false; @@ -1292,7 +1233,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); } } else { - if (md.find(TAG_KEY_PROFILE_TONE_COPYRIGHT) && md.toString(TAG_KEY_PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { + if (md.find(PROFILE_TONE_COPYRIGHT) && md.toString(PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { // An Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that std::vector curve_points = { static_cast(DCT_Spline) @@ -1390,31 +1331,32 @@ void DCPProfile::apply( const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, - bool apply_hue_sat_map + bool apply_hue_sat_map, + bool apply_look_table ) const { const TMatrix work_matrix = ICCStore::getInstance()->workingSpaceInverseMatrix(working_space); - const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant); // Camera RGB to XYZ D50 matrix - const std::vector delta_base = makeHueSatMap(white_balance, preferred_illuminant); if (delta_base.empty()) { apply_hue_sat_map = false; } + const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant, apply_hue_sat_map || apply_look_table); // Camera RGB to XYZ D50 matrix + if (!apply_hue_sat_map) { // The fast path: No LUT --> Calculate matrix for direct conversion raw -> working space float mat[3][3] = {}; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - double temp = 0.0; + for (int k = 0; k < 3; ++k) { - temp += work_matrix[i][k] * xyz_cam[k][j]; + mat[i][j] += work_matrix[i][k] * xyz_cam[k][j]; } - mat[i][j] = temp; + } } @@ -1440,11 +1382,11 @@ void DCPProfile::apply( for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - double temp = 0.0; + for (int k = 0; k < 3; ++k) { - temp += prophoto_xyz[i][k] * xyz_cam[k][j]; + pro_photo[i][j] += prophoto_xyz[i][k] * xyz_cam[k][j]; } - pro_photo[i][j] = temp; + } } @@ -1452,11 +1394,11 @@ void DCPProfile::apply( for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - double temp = 0.0; + for (int k = 0; k < 3; ++k) { - temp += work_matrix[i][k] * xyz_prophoto[k][j]; + work[i][j] += work_matrix[i][k] * xyz_prophoto[k][j]; } - work[i][j] = temp; + } } @@ -1498,7 +1440,7 @@ void DCPProfile::apply( } } -void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out) +void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out) { as_out.data->use_tone_curve = use_tone_curve; as_out.data->apply_look_table = apply_look_table; @@ -1527,11 +1469,9 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - double temp = 0.0; for (int k = 0; k < 3; k++) { - temp += prophoto_xyz[i][k] * mWork[k][j]; + as_out.data->pro_photo[i][j] += prophoto_xyz[i][k] * mWork[k][j]; } - as_out.data->pro_photo[i][j] = temp; } } @@ -1540,20 +1480,18 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - double temp = 0.0; for (int k = 0; k < 3; k++) { - temp += mWork[i][k] * xyz_prophoto[k][j]; + as_out.data->work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; } - as_out.data->work[i][j] = temp; } } } } -void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const +void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const ApplyState& as_in) const { -#define FCLIP(a) ((a)>0.f?((a)<65535.5f?(a):65535.5f):0.f) +#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) #define CLIP01(a) ((a)>0?((a)<1?(a):1):0) float exp_scale = as_in.data->bl_scale; @@ -1992,7 +1930,7 @@ std::vector DCPProfile::makeHueSatMap(const ColorTemp& wh return res; } -inline void DCPProfile::hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const +void DCPProfile::hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const { // Apply the HueSatMap. Ported from Adobes reference implementation. float hue_shift; @@ -2177,7 +2115,8 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) && lastdot <= sname.size() - 4 && !sname.casefold().compare(lastdot, 4, ".dcp") ) { - file_std_profiles[sname.substr(0, lastdot).casefold_collate_key()] = fname; // They will be loaded and cached on demand + const Glib::ustring cam_short_name = sname.substr(0, lastdot).uppercase(); + file_std_profiles[cam_short_name] = fname; // They will be loaded and cached on demand } } else { // Directory @@ -2188,10 +2127,11 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) for (const auto& alias : getAliases(rt_profile_dir)) { const Glib::ustring alias_name = Glib::ustring(alias.first).uppercase(); - const std::map::const_iterator real = file_std_profiles.find(Glib::ustring(alias.second).casefold_collate_key()); + const Glib::ustring real_name = Glib::ustring(alias.second).uppercase(); + const std::map::const_iterator real = file_std_profiles.find(real_name); if (real != file_std_profiles.end()) { - file_std_profiles[alias_name.casefold_collate_key()] = real->second; + file_std_profiles[alias_name] = real->second; } } } @@ -2213,20 +2153,20 @@ bool DCPStore::isValidDCPFileName(const Glib::ustring& filename) const DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const { - const auto key = filename.casefold_collate_key(); MyMutex::MyLock lock(mutex); - const std::map::const_iterator iter = profile_cache.find(key); - if (iter != profile_cache.end()) { - return iter->second; + const std::map::iterator r = profile_cache.find(filename); + + if (r != profile_cache.end()) { + return r->second; } DCPProfile* const res = new DCPProfile(filename); if (res->isValid()) { // Add profile - profile_cache[key] = res; - if (settings->verbose) { + profile_cache[filename] = res; + if (options.rtSettings.verbose) { printf("DCP profile '%s' loaded from disk\n", filename.c_str()); } return res; @@ -2238,9 +2178,13 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const DCPProfile* DCPStore::getStdProfile(const Glib::ustring& requested_cam_short_name) const { - const std::map::const_iterator iter = file_std_profiles.find(requested_cam_short_name.casefold_collate_key()); - if (iter != file_std_profiles.end()) { - return getProfile(iter->second); + const Glib::ustring name = requested_cam_short_name.uppercase(); + + // Warning: do NOT use map.find(), since it does not seem to work reliably here + for (const auto& file_std_profile : file_std_profiles) { + if (file_std_profile.first == name) { + return getProfile(file_std_profile.second); + } } // profile not found, looking if we're in loadAll=false mode diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 573349348..c818d9b6c 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -41,6 +41,20 @@ class DCPProfileApplyState; class DCPProfile final { public: + class ApplyState final + { + public: + ApplyState(); + ~ApplyState(); + + private: + struct Data; + + std::unique_ptr data; + + friend class DCPProfile; + }; + struct Illuminants { short light_source_1; short light_source_2; @@ -72,10 +86,11 @@ public: const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, - bool apply_hue_sat_map = true + bool apply_hue_sat_map, + bool apply_look_table ) const; - void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out); - void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const; + void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out); + void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const; private: struct HsbModify { @@ -136,20 +151,6 @@ private: AdobeToneCurve tone_curve; }; -class DCPProfileApplyState final -{ -public: - DCPProfileApplyState(); - ~DCPProfileApplyState(); - -private: - struct Data; - - const std::unique_ptr data; - - friend class DCPProfile; -}; - class DCPStore final : public NonCopyable { @@ -171,10 +172,10 @@ private: std::vector profileDir; // these contain standard profiles from RT. keys are all in uppercase, file path is value - std::map file_std_profiles; + std::map file_std_profiles; // Maps file name to profile as cache - mutable std::map profile_cache; + mutable std::map profile_cache; }; } diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 37ab1f6b4..4975a6854 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -29,7 +29,6 @@ #include "utils.h" #include "../rtgui/options.h" #include "../rtgui/version.h" -#include "../rtexif/rtexif.h" #ifdef WIN32 #include @@ -1177,6 +1176,10 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_ADOBE_DEFLATE); TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, (bps == 16 || bps == 32) && isFloat ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT); + /* + + TODO: Re-apply fix from #5787 + [out]() { const std::vector default_tags = rtexif::ExifManager::getDefaultTIFFTags(nullptr); @@ -1188,7 +1191,7 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u for (auto default_tag : default_tags) { delete default_tag; } - }(); + }();*/ if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, (bps == 16 || bps == 32) && isFloat ? PREDICTOR_FLOATINGPOINT : PREDICTOR_HORIZONTAL); diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index b56e3b17f..a63e52ab7 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -47,12 +47,6 @@ class LUT; using LUTu = LUT; class EditDataProvider; -namespace rtexif -{ - -class TagDirectory; - -} namespace rtengine { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index e1ebf2893..698b8f411 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -24,7 +24,6 @@ #include "image8.h" #include "imagefloat.h" #include "LUT.h" -#include "rawmetadatalocation.h" #include "../rtgui/threadutils.h" diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index ce6a6ba42..fc0cad111 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -23,7 +23,6 @@ #include #include "toolpanel.h" -#include "../rtexif/rtexif.h" namespace rtengine { From 9ee48d83f912d27e06670e38e30a5af4c8f65220 Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 16 Oct 2020 12:43:59 +0200 Subject: [PATCH 008/326] Fix references to DCPProfile::ApplyState --- rtengine/dcp.h | 1 - rtengine/dcrop.cc | 2 +- rtengine/imagesource.h | 4 ++-- rtengine/improccoordinator.cc | 2 +- rtengine/improcfun.cc | 4 ++-- rtengine/improcfun.h | 6 +++--- rtengine/rawimagesource.h | 2 +- rtengine/rtthumbnail.cc | 2 +- rtengine/simpleprocess.cc | 2 +- 9 files changed, 12 insertions(+), 13 deletions(-) diff --git a/rtengine/dcp.h b/rtengine/dcp.h index c818d9b6c..69020c23b 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -36,7 +36,6 @@ namespace rtengine class ColorTemp; class Imagefloat; -class DCPProfileApplyState; class DCPProfile final { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index d5596c8ce..ae183ba63 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -820,7 +820,7 @@ void Crop::update(int todo) } */ double rrm, ggm, bbm; - DCPProfileApplyState as; + DCPProfile::ApplyState as; DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, as); LUTu histToneCurve; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 31ba98f81..32e8e0b5d 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -42,7 +42,7 @@ namespace rtengine class ColorTemp; class DCPProfile; -class DCPProfileApplyState; +class DCPProfile::ApplyState; class Imagefloat; class RetinexgaintransmissionCurve; class RetinextransmissionCurve; @@ -140,7 +140,7 @@ public: virtual ImageMatrices* getImageMatrices () = 0; virtual bool isRAW () const = 0; - virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) + virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &as) { return nullptr; }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 30d2d6433..9a6c2e1b2 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -942,7 +942,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double ggm = 33.; double bbm = 33.; - DCPProfileApplyState as; + DCPProfile::ApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params->icm, as); ipf.rgbProc(oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation, diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 6b6dbe16d..862939b66 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2011,7 +2011,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, - double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { rgbProc(working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, @@ -2025,7 +2025,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, - DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) + DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { std::unique_ptr stop; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d3ee81701..c98e77b29 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -49,7 +49,7 @@ namespace rtengine class ColorAppearance; class ColorGradientCurve; class DCPProfile; -class DCPProfileApplyState; +class DCPProfile::ApplyState; class FlatCurve; class FramesMetaData; class LensCorrection; @@ -157,13 +157,13 @@ public: const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, - const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, - int hlcomprthresh, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 12db6be74..6db38d8e1 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -186,7 +186,7 @@ public: void getAutoExpHistogram (LUTu & histogram, int& histcompr) override; void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override; void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, std::vector &outCurve) override; - DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override; + DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &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); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index d45f1b646..2adcf956a 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1329,7 +1329,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT LabImage* labView = new LabImage (fw, fh); DCPProfile *dcpProf = nullptr; - DCPProfileApplyState as; + DCPProfile::ApplyState as; if (isRaw) { cmsHPROFILE dummy; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index d45398d66..f68ee3b76 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1001,7 +1001,7 @@ private: } autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfileApplyState as; + DCPProfile::ApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params.icm, as); LUTu histToneCurve; From badf92ba644dee87d3c8024a3ba902b76b8f6333 Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 16 Oct 2020 13:30:47 +0200 Subject: [PATCH 009/326] Fix for declared near() function, backport from ART. Various other minor changes. --- rtengine/ashift_dt.c | 3 +++ rtengine/dcp.cc | 7 +++---- rtengine/dcp.h | 3 +-- rtengine/imagedata.cc | 6 ++---- rtengine/imagesource.h | 4 ++-- rtengine/improcfun.h | 1 - 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/rtengine/ashift_dt.c b/rtengine/ashift_dt.c index ce19b6808..c7cd01ef1 100644 --- a/rtengine/ashift_dt.c +++ b/rtengine/ashift_dt.c @@ -103,6 +103,9 @@ using namespace std; //----------------------------------------------------------------------------- // RT: BEGIN COMMENT +#ifdef near +# undef near +#endif #if 0 DT_MODULE_INTROSPECTION(4, dt_iop_ashift_params_t) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 7d9295c71..8f829635b 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1059,7 +1059,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : DCPMetadata md(file); if (!md.parse()) { - //printf ("Unable to load DCP profile '%s'.", filename.c_str()); + //printf ("Unable to load DCP profile '%s' !", filename.c_str()); return; } @@ -1331,8 +1331,7 @@ void DCPProfile::apply( const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, - bool apply_hue_sat_map, - bool apply_look_table + bool apply_hue_sat_map ) const { @@ -1344,7 +1343,7 @@ void DCPProfile::apply( apply_hue_sat_map = false; } - const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant, apply_hue_sat_map || apply_look_table); // Camera RGB to XYZ D50 matrix + const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant); // Camera RGB to XYZ D50 matrix if (!apply_hue_sat_map) { // The fast path: No LUT --> Calculate matrix for direct conversion raw -> working space diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 69020c23b..d05fdb4cc 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -85,8 +85,7 @@ public: const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, - bool apply_hue_sat_map, - bool apply_look_table + bool apply_hue_sat_map ) const; void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out); void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 351303bda..3478bfc9f 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -68,11 +68,9 @@ const std::string& validateUft8(const std::string& str, const std::string& on_er return on_error; } -} - -FramesMetaData* FramesMetaData::fromFile(const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) +FramesMetaData* FramesMetaData::fromFile(const Glib::ustring& fname) { - return new FramesData(fname, std::move(rml), firstFrameOnly); + return new FramesData(fname); } FramesData::FramesData(const Glib::ustring &fname) : diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 32e8e0b5d..87ec9cdb6 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -28,6 +28,7 @@ #include "rtengine.h" #include "colortemp.h" #include "array2D.h" +#include "dcp.h" template class LUT; @@ -41,9 +42,8 @@ namespace rtengine { class ColorTemp; -class DCPProfile; -class DCPProfile::ApplyState; class Imagefloat; +class DCPProfile; class RetinexgaintransmissionCurve; class RetinextransmissionCurve; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c98e77b29..8672c7159 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -49,7 +49,6 @@ namespace rtengine class ColorAppearance; class ColorGradientCurve; class DCPProfile; -class DCPProfile::ApplyState; class FlatCurve; class FramesMetaData; class LensCorrection; From c8ef1ee6286404ae001ec55467fb04dcc887b75d Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 16 Oct 2020 16:15:10 +0200 Subject: [PATCH 010/326] Final changes, branch now buildable --- rtengine/rawimagesource.cc | 2 +- rtengine/simpleprocess.cc | 4 ++-- rtgui/controllines.cc | 2 +- rtgui/controllines.h | 5 +++-- rtgui/controlspotpanel.cc | 8 ++++---- rtgui/editwidgets.cc | 14 +++++++------- rtgui/editwidgets.h | 6 +++--- rtgui/exifpanel.cc | 7 ++++--- rtgui/filmnegative.cc | 10 +++++----- rtgui/thumbnail.cc | 9 +++------ rtgui/thumbnail.h | 1 + 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 78864d1ff..870f39d0f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -930,7 +930,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima } } -DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileApplyState &as) +DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as) { if (cmp.inputProfile == "(camera)" || cmp.inputProfile == "(none)") { return nullptr; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index f68ee3b76..f32ce35b3 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1719,11 +1719,11 @@ private: } ProfileContent pc = ICCStore::getInstance()->getContent(params.icm.outputProfile); - readyImg->setOutputProfile(pc.getData().c_str(), pc.getData().size()); + readyImg->setOutputProfile(pc.getData()); } } else { // No ICM - readyImg->setOutputProfile(nullptr, 0); + readyImg->setOutputProfile({}); } // t2.set(); diff --git a/rtgui/controllines.cc b/rtgui/controllines.cc index 573b3263f..18da514cc 100644 --- a/rtgui/controllines.cc +++ b/rtgui/controllines.cc @@ -31,7 +31,7 @@ using namespace rtengine; ControlLineManager::ControlLineManager(): EditSubscriber(ET_OBJECTS), - canvas_area(new Rectangle()), + canvas_area(new EditRectangle()), cursor(CSHandOpen), draw_mode(false), drawing_line(false), diff --git a/rtgui/controllines.h b/rtgui/controllines.h index 0ff449092..61bc17678 100644 --- a/rtgui/controllines.h +++ b/rtgui/controllines.h @@ -26,9 +26,10 @@ class Circle; class Line; class OPIcon; -class Rectangle; +class EditRectangle; class RTSurface; + struct ControlLine { static constexpr int OBJ_COUNT = 4; std::unique_ptr line; @@ -45,7 +46,7 @@ class ControlLineManager: EditSubscriber protected: /** Hidden object for capturing mouse events. */ - std::unique_ptr canvas_area; + std::unique_ptr canvas_area; rtengine::Coord drag_delta; std::vector> control_lines; CursorShape cursor; diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 9ed4c95ee..8a08c1d64 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -1852,8 +1852,8 @@ void ControlSpotPanel::addControlSpotCurve(Gtk::TreeModel::Row& row) shape_ellipse = new Ellipse(); shape_ellipse->datum = Geometry::IMAGE; shape_ellipse->radiusInImageSpace = true; - Rectangle* shape_rectangle; - shape_rectangle = new Rectangle(); + EditRectangle* shape_rectangle; + shape_rectangle = new EditRectangle(); shape_rectangle->datum = Geometry::IMAGE; EditSubscriber::visibleGeometry.push_back(centerCircle); // (curveid - 1) * 7 EditSubscriber::visibleGeometry.push_back(shape_ellipse); // (curveid - 1) * 7 + 1 @@ -1887,7 +1887,7 @@ void ControlSpotPanel::addControlSpotCurve(Gtk::TreeModel::Row& row) shape_ellipse = new Ellipse(); shape_ellipse->datum = Geometry::IMAGE; shape_ellipse->radiusInImageSpace = true; - shape_rectangle = new Rectangle(); + shape_rectangle = new EditRectangle(); shape_rectangle->datum = Geometry::IMAGE; EditSubscriber::mouseOverGeometry.push_back(centerCircle); // (curveid - 1) * 7 EditSubscriber::mouseOverGeometry.push_back(shape_ellipse); // (curveid - 1) * 7 + 1 @@ -1957,7 +1957,7 @@ void ControlSpotPanel::updateControlSpotCurve(const Gtk::TreeModel::Row& row) }; const auto updateRectangle = [&](Geometry * geometry) { - const auto rectangle = static_cast(geometry); + const auto rectangle = static_cast(geometry); rectangle->bottomRight.x = origin.x + decayX; rectangle->bottomRight.y = origin.y + decayY; rectangle->topLeft.x = origin.x - decayXL; diff --git a/rtgui/editwidgets.cc b/rtgui/editwidgets.cc index fccdb874a..6611ff519 100644 --- a/rtgui/editwidgets.cc +++ b/rtgui/editwidgets.cc @@ -471,31 +471,31 @@ void Polyline::drawToMOChannel (Cairo::RefPtr &cr, unsigned shor } } -void Rectangle::setXYWH(int left, int top, int width, int height) +void EditRectangle::setXYWH(int left, int top, int width, int height) { topLeft.set(left, top); bottomRight.set(left + width, top + height); } -void Rectangle::setXYXY(int left, int top, int right, int bottom) +void EditRectangle::setXYXY(int left, int top, int right, int bottom) { topLeft.set(left, top); bottomRight.set(right, bottom); } -void Rectangle::setXYWH(rtengine::Coord topLeft, rtengine::Coord widthHeight) +void EditRectangle::setXYWH(rtengine::Coord topLeft, rtengine::Coord widthHeight) { this->topLeft = topLeft; this->bottomRight = topLeft + widthHeight; } -void Rectangle::setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight) +void EditRectangle::setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight) { this->topLeft = topLeft; this->bottomRight = bottomRight; } -void Rectangle::drawOuterGeometry(Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void EditRectangle::drawOuterGeometry(Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if ((flags & F_VISIBLE) && state != INSENSITIVE) { RGBColor color; @@ -538,7 +538,7 @@ void Rectangle::drawOuterGeometry(Cairo::RefPtr &cr, ObjectMOBuf } } -void Rectangle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void EditRectangle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if (flags & F_VISIBLE) { if (state != INSENSITIVE) { @@ -602,7 +602,7 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuf } } -void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) +void EditRectangle::drawToMOChannel(Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { if (flags & F_HOVERABLE) { cr->set_line_width( getMouseOverLineWidth() ); diff --git a/rtgui/editwidgets.h b/rtgui/editwidgets.h index c86949cb4..7add435b9 100644 --- a/rtgui/editwidgets.h +++ b/rtgui/editwidgets.h @@ -307,14 +307,14 @@ public: void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) override; }; -class Rectangle : public Geometry +class EditRectangle : public Geometry // New class name to avoid conflict elsewhere (exiv2), would be nicer to put in namespace? { public: rtengine::Coord topLeft; rtengine::Coord bottomRight; bool filled; - Rectangle (); + EditRectangle (); void setXYWH(int left, int top, int width, int height); void setXYXY(int left, int top, int right, int bottom); @@ -528,7 +528,7 @@ inline Circle::Circle () : false) { } -inline Rectangle::Rectangle () : +inline EditRectangle::EditRectangle () : topLeft (0, 0), bottomRight (10, 10), filled (false) { } diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index f4ce89f77..a2217086d 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -175,9 +175,10 @@ void ExifPanel::setImageData (const FramesMetaData* id) Gtk::TreeModel::Children ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited) { - if (!value.validate()) { - value = "???"; - } + // TODO Re-fix #5923 if necessary + //if (!value.validate()) { + // value = "???"; + //} auto root = exifTreeModel->children(); diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index d70c2a067..c13f09320 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -124,14 +124,14 @@ FilmNegative::FilmNegative() : filmBaseSpotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::baseSpotToggled)); // Editing geometry; create the spot rectangle - Rectangle* const spotRect = new Rectangle(); + EditRectangle* const spotRect = new EditRectangle(); spotRect->filled = false; visibleGeometry.push_back(spotRect); // Stick a dummy rectangle over the whole image in mouseOverGeometry. // This is to make sure the getCursor() call is fired everywhere. - Rectangle* const imgRect = new Rectangle(); + EditRectangle* const imgRect = new EditRectangle(); imgRect->filled = true; mouseOverGeometry.push_back(imgRect); @@ -284,7 +284,7 @@ CursorShape FilmNegative::getCursor(int objectID) const bool FilmNegative::mouseOver(int modifierKey) { EditDataProvider* const provider = getEditProvider(); - Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); + EditRectangle* const spotRect = static_cast(visibleGeometry.at(0)); spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); return true; @@ -386,7 +386,7 @@ void FilmNegative::editToggled() // Stick a dummy rectangle over the whole image in mouseOverGeometry. // This is to make sure the getCursor() call is fired everywhere. - Rectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); + EditRectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); imgRect->setXYWH(0, 0, w, h); } else { refSpotCoords.clear(); @@ -408,7 +408,7 @@ void FilmNegative::baseSpotToggled() // Stick a dummy rectangle over the whole image in mouseOverGeometry. // This is to make sure the getCursor() call is fired everywhere. - Rectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); + EditRectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); imgRect->setXYWH(0, 0, w, h); } else { refSpotCoords.clear(); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index fed520acd..10eb28fae 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -41,15 +41,14 @@ #include "md5helper.h" #include "pathutils.h" #include "paramsedited.h" - +#include "ppversion.h" #include "procparamchangers.h" #include "profilestorecombobox.h" #include "version.h" -#include "../rtengine/dynamicprofile.h" -#include "../rtengine/imagedata.h" #include "../rtengine/mytime.h" -#include "../rtengine/procparams.h" + +using namespace rtengine::procparams; namespace { @@ -110,8 +109,6 @@ bool CPBDump( } // namespace -using namespace rtengine::procparams; - Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf) : fname(fname), cfs(*cf), diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 834c9c297..aa9416f26 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -26,6 +26,7 @@ #include "cacheimagedata.h" #include "threadutils.h" #include "thumbnaillistener.h" +#include "../rtengine/procparams.h" namespace rtengine { From 453fb961f203af59e0cd3790bb16fab15f41bd32 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Sun, 28 Mar 2021 18:12:47 -0700 Subject: [PATCH 011/326] Create a preferences widget for external editors The widget is intended to be embedded in the preferences dialog. It displays a list of external editors using an icon, name, and command for each editor. The name and command can be edited. Editors can be added, removed, and rearranged. A button allows one to set an editor's information by selecting from a list of installed applications. --- rtgui/externaleditorpreferences.cc | 261 +++++++++++++++++++++++++++++ rtgui/externaleditorpreferences.h | 147 ++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 rtgui/externaleditorpreferences.cc create mode 100644 rtgui/externaleditorpreferences.h diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc new file mode 100644 index 000000000..df6b6efc2 --- /dev/null +++ b/rtgui/externaleditorpreferences.cc @@ -0,0 +1,261 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "externaleditorpreferences.h" +#include "multilangmgr.h" +#include "rtimage.h" + + +ExternalEditorPreferences::ExternalEditorPreferences(): + Box(Gtk::Orientation::ORIENTATION_VERTICAL), + list_model(Gtk::ListStore::create(model_columns)), + toolbar(Gtk::Orientation::ORIENTATION_HORIZONTAL) +{ + // List view. + list_view = Gtk::make_managed(); + list_view->set_model(list_model); + list_view->append_column(*Gtk::manage(makeAppColumn())); + list_view->append_column(*Gtk::manage(makeCommandColumn())); + + for (auto &&column : list_view->get_columns()) { + column->set_sizing(Gtk::TreeViewColumnSizing::TREE_VIEW_COLUMN_FIXED); + } + + list_view->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL); + list_view->set_reorderable(); + + // List scroll area. + list_scroll_area.set_hexpand(); + list_scroll_area.set_vexpand(); + list_scroll_area.add(*list_view); + + // Toolbar buttons. + auto add_image = Gtk::make_managed("add-small.png"); + auto remove_image = Gtk::make_managed("remove-small.png"); + button_add = Gtk::make_managed(); + button_remove = Gtk::make_managed(); + button_add->set_image(*add_image); + button_remove->set_image(*remove_image); + button_app_chooser = Gtk::make_managed(M("PREFERENCES_EXTERNALEDITOR_CHANGE")); + + button_app_chooser->signal_pressed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::openAppChooserDialog)); + button_add->signal_pressed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::addEditor)); + button_remove->signal_pressed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::removeSelectedEditors)); + + list_view->get_selection()->signal_changed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::updateToolbarSensitivity)); + updateToolbarSensitivity(); + + // Toolbar. + toolbar.set_halign(Gtk::Align::ALIGN_END); + toolbar.add(*button_app_chooser); + toolbar.add(*button_add); + toolbar.add(*button_remove); + + // This widget's children. + add(list_scroll_area); + add(toolbar); + show_all(); +} + +std::vector +ExternalEditorPreferences::getEditors() const +{ + std::vector editors; + + 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_name = icon == nullptr ? "" : icon->to_string(); + editors.push_back(ExternalEditorPreferences::EditorInfo( + rowIter->get_value(model_columns.name), + rowIter->get_value(model_columns.command), + icon_name, + rowIter->get_value(model_columns.other_data) + )); + } + + return editors; +} + +void ExternalEditorPreferences::setEditors( + const std::vector &editors) +{ + list_model->clear(); + + for (const ExternalEditorPreferences::EditorInfo & editor : editors) { + auto row = *list_model->append(); + row[model_columns.name] = editor.name; + row[model_columns.icon] = editor.icon_name.empty() ? Glib::RefPtr() : Gio::Icon::create(editor.icon_name); + row[model_columns.command] = editor.command; + row[model_columns.other_data] = editor.other_data; + } +} + +void ExternalEditorPreferences::addEditor() +{ + Gtk::TreeModel::Row row; + auto selected = list_view->get_selection()->get_selected_rows(); + + if (selected.size()) { + row = *list_model->insert_after(list_model->get_iter(selected.back())); + } else { + row = *list_model->append(); + } + + row[model_columns.name] = "-"; + list_view->get_selection()->select(row); +} + +Gtk::TreeViewColumn *ExternalEditorPreferences::makeAppColumn() +{ + auto name_renderer = Gtk::make_managed(); + auto icon_renderer = Gtk::make_managed(); + auto col = Gtk::make_managed(); + + col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_NAME")); + col->set_resizable(); + col->pack_start(*icon_renderer, false); + col->pack_start(*name_renderer); + col->add_attribute(*icon_renderer, "gicon", model_columns.icon); + col->add_attribute(*name_renderer, "text", model_columns.name); + col->set_min_width(20); + + name_renderer->property_editable() = true; + name_renderer->signal_edited().connect( + sigc::mem_fun(*this, &ExternalEditorPreferences::setAppName)); + + return col; +} + +Gtk::TreeViewColumn *ExternalEditorPreferences::makeCommandColumn() +{ + auto command_renderer = Gtk::make_managed(); + auto col = Gtk::make_managed(); + + col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND")); + col->pack_start(*command_renderer); + col->add_attribute(*command_renderer, "text", model_columns.command); + + command_renderer->property_editable() = true; + command_renderer->signal_edited().connect( + sigc::mem_fun(*this, &ExternalEditorPreferences::setAppCommand)); + + return col; +} + +void ExternalEditorPreferences::onAppChooserDialogResponse( + int response_id, Gtk::AppChooserDialog *dialog) +{ + switch (response_id) { + case Gtk::RESPONSE_OK: + dialog->close(); + setApp(dialog->get_app_info()); + break; + + case Gtk::RESPONSE_CANCEL: + case Gtk::RESPONSE_CLOSE: + dialog->close(); + break; + + default: + break; + } +} + +void ExternalEditorPreferences::openAppChooserDialog() +{ + if (app_chooser_dialog.get()) { + app_chooser_dialog->refresh(); + app_chooser_dialog->show(); + return; + } + + app_chooser_dialog.reset(new Gtk::AppChooserDialog("image/tiff")); + app_chooser_dialog->signal_response().connect(sigc::bind( + sigc::mem_fun(*this, &ExternalEditorPreferences::onAppChooserDialogResponse), + app_chooser_dialog.get() + )); + app_chooser_dialog->set_modal(); + app_chooser_dialog->show(); +} + +void ExternalEditorPreferences::removeSelectedEditors() +{ + auto selection = list_view->get_selection()->get_selected_rows(); + + for (const auto &selected : selection) { + list_model->erase(list_model->get_iter(selected)); + } +} + +void ExternalEditorPreferences::setApp(const Glib::RefPtr app_info) +{ + auto selection = list_view->get_selection()->get_selected_rows(); + + for (const auto &selected : selection) { + auto row = *list_model->get_iter(selected); + row[model_columns.icon] = app_info->get_icon(); + row[model_columns.name] = app_info->get_name(); + row[model_columns.command] = app_info->get_commandline(); + } +} + +void ExternalEditorPreferences::setAppCommand( + const Glib::ustring & path, const Glib::ustring & new_text) +{ + auto row_iter = list_model->get_iter(path); + + if (!row_iter->get_value(model_columns.command).compare(new_text)) { + return; + } + + row_iter->set_value(model_columns.command, new_text); + row_iter->set_value(model_columns.icon, Glib::RefPtr(nullptr)); +} + +void ExternalEditorPreferences::setAppName( + const Glib::ustring & path, const Glib::ustring & new_text) +{ + list_model->get_iter(path)->set_value(model_columns.name, new_text); +} + +void ExternalEditorPreferences::updateToolbarSensitivity() +{ + bool selected = list_view->get_selection()->count_selected_rows(); + button_app_chooser->set_sensitive(selected); + button_remove->set_sensitive(selected); +} + +ExternalEditorPreferences::EditorInfo::EditorInfo( + Glib::ustring name, Glib::ustring command, Glib::ustring icon_name, void *other_data +) : name(name), icon_name(icon_name), command(command), other_data(other_data) +{ +} + +ExternalEditorPreferences::ModelColumns::ModelColumns() +{ + add(name); + add(icon); + add(command); + add(other_data); +} diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h new file mode 100644 index 000000000..be988e901 --- /dev/null +++ b/rtgui/externaleditorpreferences.h @@ -0,0 +1,147 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + + +/** + * Widget for editing the external editors options. + */ +class ExternalEditorPreferences : public Gtk::Box +{ +public: + /** + * Data struct containing information about an external editor. + */ + struct EditorInfo { + explicit EditorInfo( + Glib::ustring name = Glib::ustring(), + Glib::ustring command = Glib::ustring(), + Glib::ustring icon_name = Glib::ustring(), + void *other_data = nullptr + ); + /** + * Name of the external editor. + */ + Glib::ustring name; + /** + * The string representation of the icon. See Gio::Icon::to_string(). + */ + Glib::ustring icon_name; + /** + * The commandline for running the program. See + * Gio::AppInfo::get_commandline() + */ + Glib::ustring command; + /** + * Holds any other data associated with the editor. For example, it can + * be used as a tag to uniquely identify the editor. + */ + void *other_data; + }; + + ExternalEditorPreferences(); + + /** + * Creates and returns a vector representing the external editors shown in + * this widget. + */ + std::vector getEditors() const; + /** + * Populates this widget with the external editors described in the + * argument. + */ + void setEditors(const std::vector &editors); + +private: + /** + * Model representing the data fields each external editor entry has. + */ + class ModelColumns : public Gtk::TreeModelColumnRecord + { + public: + ModelColumns(); + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn> icon; + Gtk::TreeModelColumn command; + Gtk::TreeModelColumn other_data; + }; + + ModelColumns model_columns; + Glib::RefPtr list_model; // The list of editors. + Gtk::ScrolledWindow list_scroll_area; // Allows the list to be scrolled. + Gtk::TreeView *list_view; // Widget for displaying the list. + Gtk::Box toolbar; // Contains buttons for editing the list. + Gtk::Button *button_app_chooser; + Gtk::Button *button_add; + Gtk::Button *button_remove; + std::unique_ptr app_chooser_dialog; + + /** + * Inserts a new editor entry after the current selection, or at the end if + * no editor is selected. + */ + void addEditor(); + /** + * Constructs the column for displaying the external editor name (and icon). + */ + Gtk::TreeViewColumn *makeAppColumn(); + /** + * Constructs the column for displaying an editable commandline. + */ + Gtk::TreeViewColumn *makeCommandColumn(); + /** + * Called when the user is done interacting with the app chooser dialog. + * Closes the dialog and updates the selected entry if an app was chosen. + */ + void onAppChooserDialogResponse(int responseId, Gtk::AppChooserDialog *dialog); + /** + * Shows the app chooser dialog. + */ + void openAppChooserDialog(); + /** + * Removes all selected editors. + */ + void removeSelectedEditors(); + /** + * Sets the selected entries with the provided information. + */ + void setApp(const Glib::RefPtr app_info); + /** + * Updates the application command and removes the icon for the given row. + */ + void setAppCommand(const Glib::ustring & path, const Glib::ustring & new_text); + /** + * Updates the application name for the given row. + */ + void setAppName(const Glib::ustring & path, const Glib::ustring & new_text); + /** + * Sets the sensitivity of the widgets in the toolbar to reflect the current + * state of the list. For example, makes the remove button insensitive if no + * entries are selected. + */ + void updateToolbarSensitivity(); +}; From d2a280fbf361b804bbe70c4da46d21cf7827064a Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Tue, 30 Mar 2021 21:45:20 -0700 Subject: [PATCH 012/326] Update language file and cmake list Update for the external editor preferences widget. --- rtdata/languages/default | 3 +++ rtgui/CMakeLists.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 15aceb51b..2ff654ede 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1755,6 +1755,9 @@ PREFERENCES_DIRSOFTWARE;Installation directory PREFERENCES_EDITORCMDLINE;Custom command line PREFERENCES_EDITORLAYOUT;Editor layout PREFERENCES_EXTERNALEDITOR;External Editor +PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application +PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name +PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser PREFERENCES_FLATFIELDFOUND;Found diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 5f8baed47..1d4b57553 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -62,6 +62,7 @@ set(NONCLISOURCEFILES exiffiltersettings.cc exifpanel.cc exportpanel.cc + externaleditorpreferences.cc extprog.cc fattaltonemap.cc filebrowser.cc From afe20fee0e0046083cd61abe28e8f44591baf212 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 4 Apr 2021 22:16:16 -0700 Subject: [PATCH 013/326] Add Gio::Icon based RTImages --- rtgui/rtimage.cc | 102 ++++++++++++++++++++++++++++++++++++++++++++++- rtgui/rtimage.h | 8 ++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 44078ed3b..9a38c1885 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -22,12 +22,40 @@ #include #include +#include +#include #include "../rtengine/settings.h" namespace { +struct GIconKey { + Glib::RefPtr icon; + /** + * Icon size in pixels. + */ + int icon_size; + + GIconKey() {} + GIconKey(const Glib::RefPtr &icon, int icon_size): icon(icon), icon_size(icon_size) {} + + bool operator==(const GIconKey &other) const + { + bool icons_match = (icon.get() == nullptr && other.icon.get() == nullptr) || (icon.get() != nullptr && icon->equal(Glib::RefPtr::cast_const(other.icon))); + return icons_match && icon_size == other.icon_size; + } +}; + +struct GIconKeyHash { + size_t operator()(const GIconKey &key) const + { + const size_t icon_hash = key.icon ? key.icon->hash() : 0; + return icon_hash ^ std::hash()(key.icon_size); + } +}; + +std::unordered_map, GIconKeyHash> gIconPixbufCache; std::map > pixbufCache; std::map > surfaceCache; @@ -44,6 +72,8 @@ RTImage::RTImage (RTImage &other) : surface(other.surface), pixbuf(other.pixbuf) set(pixbuf); } else if (surface) { set(surface); + } else if (other.gIcon) { + changeImage(other.gIcon, other.gIconSize); } } @@ -80,13 +110,27 @@ RTImage::RTImage (Glib::RefPtr &other) if (other->get_surface()) { surface = other->get_surface(); set(surface); - } else { + } else if (other->pixbuf) { pixbuf = other->get_pixbuf(); set(pixbuf); + } else if (other->gIcon) { + changeImage(other->gIcon, other->gIconSize); } } } +RTImage::RTImage(const Glib::RefPtr &gIcon, Gtk::IconSize size) +{ + changeImage(gIcon, size); +} + +int RTImage::iconSizeToPixels(Gtk::IconSize size) const +{ + int width, height; + Gtk::IconSize::lookup(size, width, height); + return std::round(getTweakedDPI() / baseDPI * std::max(width, height)); +} + void RTImage::setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName) { Glib::ustring imageName; @@ -113,10 +157,41 @@ void RTImage::setDPInScale (const double newDPI, const int newScale) } } +void RTImage::changeImage(const Glib::RefPtr &gIcon, int size) +{ + clear(); + + pixbuf.reset(); + surface.clear(); + this->gIcon = gIcon; + + if (!gIcon) { + return; + } + + gIconSize = size; + GIconKey key(gIcon, gIconSize); + auto iterator = gIconPixbufCache.find(key); + + if (iterator == gIconPixbufCache.end()) { + auto icon_pixbuf = createPixbufFromGIcon(gIcon, gIconSize); + iterator = gIconPixbufCache.emplace(key, icon_pixbuf).first; + } + + set(iterator->second); +} + +void RTImage::changeImage(const Glib::RefPtr &gIcon, Gtk::IconSize size) +{ + changeImage(gIcon, iconSizeToPixels(size)); +} + void RTImage::changeImage (const Glib::ustring& imageName) { clear (); + gIcon.reset(); + if (imageName.empty()) { return; } @@ -150,6 +225,11 @@ int RTImage::get_width() if (pixbuf) { return pixbuf->get_width(); } + + if (gIcon) { + return this->get_pixbuf()->get_width(); + } + return -1; } @@ -161,6 +241,11 @@ int RTImage::get_height() if (pixbuf) { return pixbuf->get_height(); } + + if (gIcon) { + return this->get_pixbuf()->get_height(); + } + return -1; } @@ -178,6 +263,11 @@ void RTImage::cleanup(bool all) for (auto& entry : surfaceCache) { entry.second.clear(); } + + for (auto& entry : gIconPixbufCache) { + entry.second.reset(); + } + RTScalable::cleanup(all); } @@ -189,6 +279,10 @@ void RTImage::updateImages() for (auto& entry : surfaceCache) { entry.second = createImgSurfFromFile(entry.first); } + + for (auto& entry : gIconPixbufCache) { + entry.second = createPixbufFromGIcon(entry.first.icon, entry.first.icon_size); + } } Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fileName) @@ -197,6 +291,12 @@ Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fi return Gdk::Pixbuf::create(imgSurf, 0, 0, imgSurf->get_width(), imgSurf->get_height()); } +Glib::RefPtr RTImage::createPixbufFromGIcon(const Glib::RefPtr &icon, int size) +{ + // TODO: Listen for theme changes and update icon, remove from cache. + return Gtk::IconTheme::get_default()->lookup_icon(icon, size, Gtk::ICON_LOOKUP_FORCE_SIZE).load_icon(); +} + Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::ustring& fileName) { Cairo::RefPtr surf; diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index eb1930d28..183a83a94 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -34,6 +34,11 @@ class RTImage final : public Gtk::Image, public RTScalable protected: Cairo::RefPtr surface; Glib::RefPtr pixbuf; + Glib::RefPtr gIcon; + int gIconSize; + + void changeImage(const Glib::RefPtr &gIcon, int size); + int iconSizeToPixels(Gtk::IconSize size) const; public: RTImage (); @@ -42,9 +47,11 @@ public: explicit RTImage (Cairo::RefPtr &surf); explicit RTImage(Cairo::RefPtr other); explicit RTImage (Glib::RefPtr &other); + explicit RTImage(const Glib::RefPtr &gIcon, Gtk::IconSize size); 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::RefPtr &gIcon, Gtk::IconSize size); void changeImage (const Glib::ustring& imageName); Cairo::RefPtr get_surface(); int get_width(); @@ -58,6 +65,7 @@ public: static void setScale (const int newScale); static Glib::RefPtr createPixbufFromFile (const Glib::ustring& fileName); + static Glib::RefPtr createPixbufFromGIcon(const Glib::RefPtr &icon, int size); static Cairo::RefPtr createImgSurfFromFile (const Glib::ustring& fileName); }; From f30f094a6c014976e6930ee6f4e8aa6d007e9c06 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 10 Apr 2021 17:41:33 -0700 Subject: [PATCH 014/326] Improve pop-up common with gicons and item ops Add ability to use gicon images, insert pop-up entries in any location, and remove entries. --- rtgui/popupcommon.cc | 157 +++++++++++++++++++++++++++++++++---------- rtgui/popupcommon.h | 19 +++++- 2 files changed, 141 insertions(+), 35 deletions(-) diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 8c4c9dda1..fabc4d572 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -27,7 +27,7 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) : buttonImage (nullptr) - , menu (nullptr) + , menu(new Gtk::Menu()) , selected (-1) // -1 means that the button is invalid { button = thisButton; @@ -48,59 +48,148 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) setExpandAlignProperties(buttonGroup, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); buttonGroup->attach(*button, 0, 0, 1, 1); buttonGroup->get_style_context()->add_class("image-combo"); + + // Create the image for the button + buttonImage = Gtk::make_managed(); + setExpandAlignProperties(buttonImage, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + imageContainer->attach_next_to(*buttonImage, Gtk::POS_RIGHT, 1, 1); + buttonImage->set_no_show_all(); + + // Create the button for showing the pop-up. + arrowButton = Gtk::make_managed(); + Gtk::Image *arrowImage = Gtk::make_managed(); + arrowImage->set_from_icon_name("pan-down-symbolic", Gtk::ICON_SIZE_BUTTON); + setExpandAlignProperties(arrowButton, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); + arrowButton->add(*arrowImage); //menuSymbol); + arrowImage->show(); + buttonGroup->attach_next_to(*arrowButton, *button, Gtk::POS_RIGHT, 1, 1); + arrowButton->signal_button_release_event().connect_notify(sigc::mem_fun(*this, &PopUpCommon::showMenu)); + arrowButton->get_style_context()->add_class("Right"); + arrowButton->get_style_context()->add_class("popupbutton-arrow"); + arrowButton->set_no_show_all(); } PopUpCommon::~PopUpCommon () { - delete menu; - delete buttonImage; } bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) { - if (label.empty ()) - return false; + return insertEntry(getEntryCount(), fileName, label); +} + +bool PopUpCommon::insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label) +{ + RTImage* image = nullptr; + if (!fileName.empty()) { + image = Gtk::make_managed(fileName); + } + bool success = insertEntryImpl(position, fileName, Glib::RefPtr(), image, label); + if (!success && image) { + delete image; + } + return success; +} + +bool PopUpCommon::insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label) +{ + RTImage* image = Gtk::make_managed(gIcon, Gtk::ICON_SIZE_BUTTON); + bool success = insertEntryImpl(position, "", gIcon, image, label); + if (!success) { + delete image; + } + return success; +} + +bool PopUpCommon::insertEntryImpl(int position, const Glib::ustring& fileName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label) +{ + if (label.empty() || position < 0 || position > getEntryCount()) + return false; // Create the menu item and image - MyImageMenuItem* newItem = Gtk::manage (new MyImageMenuItem (label, fileName)); - imageFilenames.push_back (fileName); - 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); - 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); - selected = 0; - } + MyImageMenuItem *newItem = Gtk::make_managed(label, image); + imageIcons.insert(imageIcons.begin() + position, gIcon); + imageFilenames.insert(imageFilenames.begin() + position, fileName); + images.insert(images.begin() + position, newItem->getImage()); // 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); - 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); - arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); + changeImage(fileName, gIcon); + buttonImage->show(); + selected = 0; button->get_style_context()->add_class("Left"); - arrowButton->get_style_context()->add_class("Right"); - arrowButton->get_style_context()->add_class("popupbutton-arrow"); + arrowButton->show(); hasMenu = true; + } else if (position <= selected) { + selected++; } - newItem->signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, &PopUpCommon::entrySelected), images.size () - 1)); - menu->append (*newItem); - + void (PopUpCommon::*entrySelectedFunc)(Gtk::Widget *) = &PopUpCommon::entrySelected; + newItem->signal_activate ().connect (sigc::bind (sigc::mem_fun (*this, entrySelectedFunc), newItem)); + menu->insert(*newItem, position); return true; } -// TODO: 'PopUpCommon::removeEntry' method to be created... +void PopUpCommon::removeEntry(int position) +{ + if (position < 0 || position >= getEntryCount()) { + return; + } -void PopUpCommon::entrySelected (int i) + if (getEntryCount() == 1) { // Last of the entries. + // Hide the arrow button. + button->get_style_context()->remove_class("Left"); + arrowButton->hide(); + hasMenu = false; + // Remove the button image. + buttonImage->hide(); + selected = -1; + } + else if (position < selected) { + selected--; + } + else if (position == selected) { // Select a different entry before removing. + int nextSelection = position + (position == getEntryCount() - 1 ? -1 : 1); + changeImage(nextSelection); + setButtonHint(); + } + + MyImageMenuItem *menuItem = dynamic_cast(menu->get_children()[position]); + menu->remove(*menuItem); + delete menuItem; + imageIcons.erase(imageIcons.begin() + position); + imageFilenames.erase(imageFilenames.begin() + position); + images.erase(images.begin() + position); +} + +void PopUpCommon::changeImage(int position) +{ + changeImage(imageFilenames.at(position), imageIcons.at(position)); +} + +void PopUpCommon::changeImage(const Glib::ustring& fileName, const Glib::RefPtr& gIcon) +{ + if (!fileName.empty()) { + buttonImage->changeImage(fileName); + } else { + buttonImage->changeImage(gIcon, static_cast(Gtk::ICON_SIZE_BUTTON)); + } +} + +void PopUpCommon::entrySelected(Gtk::Widget* widget) +{ + int i = 0; + for (const auto & child : menu->get_children()) { + if (widget == child) { + break; + } + i++; + } + + entrySelected(i); +} + +void PopUpCommon::entrySelected(int i) { // Emit a signal if the selected item has changed if (setSelected (posToIndex(i))) @@ -130,7 +219,7 @@ bool PopUpCommon::setSelected (int entryNum) 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)); + changeImage(entryNum); selected = entryNum; setButtonHint(); return true; diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index b4cf4d7e0..59a5b8d0e 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -20,12 +20,19 @@ */ #pragma once +#include "glibmm/refptr.h" +#include #include #include #include +namespace Gio +{ +class Icon; +} + namespace Gtk { @@ -33,6 +40,7 @@ class Grid; class Menu; class Button; class ImageMenuItem; +class Widget; } @@ -53,9 +61,12 @@ public: explicit PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); + bool insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label); + bool insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label); int getEntryCount () const; bool setSelected (int entryNum); int getSelected () const; + void removeEntry(int position); void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); @@ -65,16 +76,22 @@ private: type_signal_changed messageChanged; type_signal_item_selected messageItemSelected; + std::vector> imageIcons; std::vector imageFilenames; std::vector images; Glib::ustring buttonHint; RTImage* buttonImage; Gtk::Grid* imageContainer; - Gtk::Menu* menu; + std::unique_ptr menu; Gtk::Button* button; + Gtk::Button* arrowButton; int selected; bool hasMenu; + void changeImage(int position); + void changeImage(const Glib::ustring& fileName, 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); void showMenu(GdkEventButton* event); protected: From be7aecac40e5e91ae4047dd84bcc7219b0d4615a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Apr 2021 18:24:39 -0700 Subject: [PATCH 015/326] Add multiple external editors to options --- rtgui/options.cc | 170 +++++++++++++++++++++++++++++++++++++++++++++++ rtgui/options.h | 13 ++++ 2 files changed, 183 insertions(+) diff --git a/rtgui/options.cc b/rtgui/options.cc index ce03db434..2a00af525 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -413,6 +413,8 @@ void Options::setDefaults() gimpDir = ""; psDir = ""; customEditorProg = ""; + externalEditors.clear(); + externalEditorIndex = -1; CPBKeys = CPBKT_TID; editorToSendTo = 1; favoriteDirs.clear(); @@ -808,6 +810,7 @@ void Options::readFromFile(Glib::ustring fname) } } + // TODO: Remove. if (keyFile.has_group("External Editor")) { if (keyFile.has_key("External Editor", "EditorKind")) { editorToSendTo = keyFile.get_integer("External Editor", "EditorKind"); @@ -826,6 +829,138 @@ void Options::readFromFile(Glib::ustring fname) } } + if (keyFile.has_group("External Editor")) { + if (keyFile.has_key("External Editor", "Names") + || keyFile.has_key("External Editor", "Commands") + || keyFile.has_key("External Editor", "IconNames")) { + // Multiple external editors. + + const auto & names = + !keyFile.has_key("External Editor", "Names") ? + std::vector() : + static_cast>( + keyFile.get_string_list("External Editor", "Names")); + const auto & commands = + !keyFile.has_key("External Editor", "Commands") ? + std::vector() : + static_cast>( + keyFile.get_string_list("External Editor", "Commands")); + const auto & icon_names = + !keyFile.has_key("External Editor", "IconNames") ? + std::vector() : + static_cast>( + keyFile.get_string_list("External Editor", "IconNames")); + externalEditors = std::vector(std::max(std::max( + names.size(), commands.size()), icon_names.size())); + for (unsigned i = 0; i < names.size(); i++) { + externalEditors[i].name = names[i]; + } + for (unsigned i = 0; i < commands.size(); i++) { + externalEditors[i].command = commands[i]; + } + for (unsigned i = 0; i < icon_names.size(); i++) { + externalEditors[i].icon_name = icon_names[i]; + } + + if (keyFile.has_key("External Editor", "EditorIndex")) { + int index = keyFile.get_integer("External Editor", "EditorIndex"); + externalEditorIndex = std::min( + std::max(-1, index), + static_cast(externalEditors.size()) + ); + } + } else if (keyFile.has_key("External Editor", "EditorKind")) { + // Legacy fixed external editors. Convert to flexible. + + // GIMP == 1, Photoshop == 2, Custom == 3. + editorToSendTo = keyFile.get_integer("External Editor", "EditorKind"); + + #ifdef WIN32 + Glib::ustring gimpDir = ""; + if (keyFile.has_key("External Editor", "GimpDir")) { + gimpDir = keyFile.get_string("External Editor", "GimpDir"); + } + auto executable = Glib::build_filename(options.gimpDir, "bin", "gimp-win-remote"); + if (Glib::file_test(executable, Glib::FILE_TEST_IS_EXECUTABLE)) { + if (editorToSendTo == 1) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("GIMP", executable, "gimp")); + } else { + for (auto ver = 12; ver >= 0; --ver) { + executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); + if (Glib::file_test(executable, Glib::FILE_TEST_IS_EXECUTABLE)) { + if (editorToSendTo == 1) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("GIMP", executable, "gimp")); + break; + } + } + } + + Glib::ustring psDir = ""; + if (keyFile.has_key("External Editor", "PhotoshopDir")) { + psDir = keyFile.get_string("External Editor", "PhotoshopDir"); + } + auto executable = Glib::build_filename(psDir, "Photoshop.exe"); + if (Glib::file_test(executable, Glib::FILE_TEST_IS_EXECUTABLE)) { + if (editorToSendTo == 2) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("Photoshop", executable, "")); + } + + if (keyFile.has_key("External Editor", "CustomEditor")) { + executable = keyFile.get_string("External Editor", "CustomEditor"); + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, ""); + } + #elif defined __APPLE__ + if (editorToSendTo == 1) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("GIMP", "open -a GIMP", "gimp")); + externalEditors.push_back(ExternalEditor("GIMP-dev", "open -a GIMP-dev", "gimp")); + + if (editorToSendTo == 2) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("Photoshop", "open -a Photoshop", "")); + + if (keyFile.has_key("External Editor", "CustomEditor")) { + auto executable = keyFile.get_string("External Editor", "CustomEditor"); + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, "")); + } + #else + if (Glib::find_program_in_path("gimp").compare("")) { + if (editorToSendTo == 1) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("GIMP", "gimp", "gimp")); + } else if (Glib::find_program_in_path("gimp-remote").compare("")) { + if (editorToSendTo == 1) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("GIMP", "gimp-remote", "gimp")); + } + + if (keyFile.has_key("External Editor", "CustomEditor")) { + auto executable = keyFile.get_string("External Editor", "CustomEditor"); + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, "")); + } + #endif + } + } + if (keyFile.has_group("Output")) { if (keyFile.has_key("Output", "Format")) { saveFormat.format = keyFile.get_string("Output", "Format"); @@ -2111,11 +2246,30 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_boolean("General", "Detectshape", rtSettings.detectshape); keyFile.set_boolean("General", "Fftwsigma", rtSettings.fftwsigma); + // TODO: Remove. keyFile.set_integer("External Editor", "EditorKind", editorToSendTo); keyFile.set_string("External Editor", "GimpDir", gimpDir); keyFile.set_string("External Editor", "PhotoshopDir", psDir); keyFile.set_string("External Editor", "CustomEditor", customEditorProg); + { + std::vector names; + std::vector commands; + std::vector icon_names; + + for (const auto & editor : externalEditors) { + names.push_back(editor.name); + commands.push_back(editor.command); + icon_names.push_back(editor.icon_name); + } + + keyFile.set_string_list("External Editor", "Names", names); + keyFile.set_string_list("External Editor", "Commands", commands); + keyFile.set_string_list("External Editor", "IconNames", icon_names); + + keyFile.set_integer("External Editor", "EditorIndex", externalEditorIndex); + } + keyFile.set_boolean("File Browser", "BrowseOnlyRaw", fbOnlyRaw); keyFile.set_boolean("File Browser", "BrowserShowsDate", fbShowDateTime); keyFile.set_boolean("File Browser", "BrowserShowsExif", fbShowBasicExif); @@ -2778,3 +2932,19 @@ Glib::ustring Options::getICCProfileCopyright() now.set_time_current(); return Glib::ustring::compose("Copyright RawTherapee %1, CC0", now.get_year()); } + +ExternalEditor::ExternalEditor() {} + +ExternalEditor::ExternalEditor( + const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name +): name(name), command(command), icon_name(icon_name) {} + +bool ExternalEditor::operator==(const ExternalEditor &other) const +{ + return this->name == other.name && this->command == other.command && this->icon_name == other.icon_name; +} + +bool ExternalEditor::operator!=(const ExternalEditor &other) const +{ + return !(*this == other); +} diff --git a/rtgui/options.h b/rtgui/options.h index 03b551efe..be2ba70ab 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -52,6 +52,17 @@ // Special name for the Dynamic profile #define DEFPROFILE_DYNAMIC "Dynamic" +struct ExternalEditor { + ExternalEditor(); + ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name); + Glib::ustring name; + Glib::ustring command; + Glib::ustring icon_name; + + bool operator==(const ExternalEditor & other) const; + bool operator!=(const ExternalEditor & other) const; +}; + struct SaveFormat { SaveFormat( const Glib::ustring& _format, @@ -277,6 +288,8 @@ public: Glib::ustring gimpDir; Glib::ustring psDir; Glib::ustring customEditorProg; + std::vector externalEditors; + int externalEditorIndex; Glib::ustring CPBPath; // Custom Profile Builder's path CPBKeyType CPBKeys; // Custom Profile Builder's key type int editorToSendTo; From 3efbb99ba9eedd4942a5ba34f8d8ce54fbdc07d6 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:48:54 -0700 Subject: [PATCH 016/326] Make MyImageMenuItem constructable from an RTImage --- rtgui/guiutils.cc | 19 +++++++++++++++++-- rtgui/guiutils.h | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index f415d770f..52ad2d6d4 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1466,13 +1466,28 @@ TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx } MyImageMenuItem::MyImageMenuItem(Glib::ustring label, Glib::ustring imageFileName) +{ + RTImage* itemImage = nullptr; + + if (!imageFileName.empty()) { + itemImage = Gtk::manage(new RTImage(imageFileName)); + } + + construct(label, itemImage); +} + +MyImageMenuItem::MyImageMenuItem(Glib::ustring label, RTImage* itemImage) { + construct(label, itemImage); +} + +void MyImageMenuItem::construct(Glib::ustring label, RTImage* itemImage) { 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 (itemImage) { + image = itemImage; box->attach_next_to(*image, Gtk::POS_LEFT, 1, 1); } else { image = nullptr; diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index d90d45370..2077d505d 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -489,8 +489,11 @@ private: RTImage *image; Gtk::Label *label; + void construct(Glib::ustring label, RTImage* image); + public: MyImageMenuItem (Glib::ustring label, Glib::ustring imageFileName); + MyImageMenuItem (Glib::ustring label, RTImage* image); const RTImage *getImage () const; const Gtk::Label* getLabel () const; }; From 349ceb933627955a8ea7238e2b0c1ecb904e6103 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:53:04 -0700 Subject: [PATCH 017/326] Add function for opening images with Gio::AppInfo --- rtgui/extprog.cc | 5 +++++ rtgui/extprog.h | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 57d57ecd8..939ead608 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -339,3 +339,8 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) #endif } + +bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo) +{ + return editorInfo->launch(Gio::File::create_for_path(fileName)); +} diff --git a/rtgui/extprog.h b/rtgui/extprog.h index c5e00bb1b..86dbc1674 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -24,6 +24,11 @@ #include "threadutils.h" +namespace Gio +{ + class AppInfo; +} + struct ExtProgAction { Glib::ustring filePathEXE; @@ -64,6 +69,7 @@ public: static bool openInGimp (const Glib::ustring& fileName); static bool openInPhotoshop (const Glib::ustring& fileName); static bool openInCustomEditor (const Glib::ustring& fileName); + static bool openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo); }; #define extProgStore ExtProgStore::getInstance() From 927e9500ff98ba642a9e31d4b1fcf6348bfdf752 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 17 Apr 2021 12:55:17 -0700 Subject: [PATCH 018/326] Change GUI to support multiple external editors Replace radio selector in external editor section of preferences with external editor preferences widget. Replace send-to-GIMP button with pop-up button for exporting to a selectable application. --- rtdata/languages/default | 3 +- rtgui/editorpanel.cc | 116 +++++++++++++++++++++++++++++++-------- rtgui/editorpanel.h | 12 +++- rtgui/popupcommon.cc | 2 +- rtgui/preferences.cc | 58 ++++++++++++++++++++ rtgui/preferences.h | 2 + rtgui/rtwindow.cc | 7 +++ rtgui/rtwindow.h | 2 + 8 files changed, 175 insertions(+), 27 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2ff654ede..605f0d95d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -235,6 +235,7 @@ GENERAL_NO;No GENERAL_NONE;None GENERAL_OK;OK GENERAL_OPEN;Open +GENERAL_OTHER;Other GENERAL_PORTRAIT;Portrait GENERAL_RESET;Reset GENERAL_SAVE;Save @@ -1513,7 +1514,7 @@ MAIN_BUTTON_PREFERENCES;Preferences MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s\nSave current profile (.pp3).\nShortcut: Ctrl+Shift+s MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e\nCurrent editor: MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen MAIN_FRAME_EDITOR;Editor diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 7553a7353..e5543105c 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -666,12 +666,15 @@ EditorPanel::EditorPanel (FilePanel* filePanel) 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")); - sendtogimp = Gtk::manage (new Gtk::Button ()); - sendtogimp->set_relief(Gtk::RELIEF_NONE); - sendtogimp->add (*sendToEditorButtonImage); - sendtogimp->set_tooltip_markup (M ("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); - setExpandAlignProperties (sendtogimp, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); + send_to_external = Gtk::make_managed("", false); + send_to_external->set_tooltip_text(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); + setExpandAlignProperties(send_to_external->buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); + send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER")); + updateExternalEditorWidget( + options.externalEditorIndex >= 0 ? options.externalEditorIndex : options.externalEditors.size(), + options.externalEditors + ); + send_to_external->show(); // Status box progressLabel = Gtk::manage (new MyProgressBar (300)); @@ -736,7 +739,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->attach_next_to (*vsep1, Gtk::POS_LEFT, 1, 1); if (!gimpPlugin) { - iops->attach_next_to (*sendtogimp, Gtk::POS_LEFT, 1, 1); + iops->attach_next_to(*send_to_external->buttonGroup, Gtk::POS_LEFT, 1, 1); } if (!gimpPlugin && !simpleEditor) { @@ -840,7 +843,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) tbRightPanel_1->signal_toggled().connect ( sigc::mem_fun (*this, &EditorPanel::tbRightPanel_1_toggled) ); saveimgas->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::saveAsPressed) ); queueimg->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::queueImgPressed) ); - sendtogimp->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::sendToGimpPressed) ); + send_to_external->signal_changed().connect(sigc::mem_fun(*this, &EditorPanel::sendToExternalChanged)); + send_to_external->signal_pressed().connect(sigc::mem_fun(*this, &EditorPanel::sendToExternalPressed)); toggleHistogramProfile->signal_toggled().connect( sigc::mem_fun (*this, &EditorPanel::histogramProfile_toggled) ); if (navPrev) { @@ -1673,7 +1677,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) case GDK_KEY_e: if (!gimpPlugin) { - sendToGimpPressed(); + sendToExternalPressed(); } return true; @@ -1791,7 +1795,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc, msgd.run (); saveimgas->set_sensitive (true); - sendtogimp->set_sensitive (true); + send_to_external->set_sensitive(true); isProcessing = false; } @@ -1819,7 +1823,7 @@ bool EditorPanel::idle_imageSaved (ProgressConnector *pc, rtengine::IImagef } saveimgas->set_sensitive (true); - sendtogimp->set_sensitive (true); + send_to_external->set_sensitive(true); parent->setProgressStr (""); parent->setProgress (0.); @@ -1930,7 +1934,7 @@ void EditorPanel::saveAsPressed () ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ), sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_saveImage ), ld, fnameOut, sf, pparams)); saveimgas->set_sensitive (false); - sendtogimp->set_sensitive (false); + send_to_external->set_sensitive(false); } } else { BatchQueueEntry* bqe = createBatchQueueEntry (); @@ -1961,7 +1965,7 @@ void EditorPanel::queueImgPressed () parent->addBatchQueueJob (createBatchQueueEntry ()); } -void EditorPanel::sendToGimpPressed () +void EditorPanel::sendToExternal() { if (!ipc || !openThm) { return; @@ -1975,7 +1979,29 @@ void EditorPanel::sendToGimpPressed () ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ), sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_sendToGimp ), ld, openThm->getFileName() )); saveimgas->set_sensitive (false); - sendtogimp->set_sensitive (false); + send_to_external->set_sensitive(false); +} + +void EditorPanel::sendToExternalChanged(int) +{ + int index = send_to_external->getSelected(); + if (index >= 0 && static_cast(index) == options.externalEditors.size()) { + index = -1; + } + options.externalEditorIndex = index; +} + +void EditorPanel::sendToExternalPressed() +{ + if (options.externalEditorIndex == -1) { + // "Other" external editor. Show app chooser dialog to let user pick. + Gtk::AppChooserDialog *dialog = getAppChooserDialog(); + dialog->show(); + } else { + struct ExternalEditor editor = options.externalEditors.at(options.externalEditorIndex); + external_editor_info = Gio::AppInfo::create_from_commandline(editor.command, editor.name, Gio::APP_INFO_CREATE_NONE); + sendToExternal(); + } } @@ -2078,7 +2104,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); saveimgas->set_sensitive (true); - sendtogimp->set_sensitive (true); + send_to_external->set_sensitive(true); } return false; @@ -2093,18 +2119,12 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef if (!errore) { saveimgas->set_sensitive (true); - sendtogimp->set_sensitive (true); + send_to_external->set_sensitive(true); parent->setProgressStr (""); parent->setProgress (0.); bool success = false; - if (options.editorToSendTo == 1) { - success = ExtProgStore::openInGimp (filename); - } else if (options.editorToSendTo == 2) { - success = ExtProgStore::openInPhotoshop (filename); - } else if (options.editorToSendTo == 3) { - success = ExtProgStore::openInCustomEditor (filename); - } + success = ExtProgStore::openInExternalEditor(filename, external_editor_info); if (!success) { Gtk::MessageDialog msgd (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); @@ -2117,6 +2137,36 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef return false; } +Gtk::AppChooserDialog *EditorPanel::getAppChooserDialog() +{ + if (!app_chooser_dialog.get()) { + app_chooser_dialog.reset(new Gtk::AppChooserDialog("image/tiff")); + app_chooser_dialog->signal_response().connect( + sigc::mem_fun(*this, &EditorPanel::onAppChooserDialogResponse) + ); + app_chooser_dialog->set_modal(); + } + + return app_chooser_dialog.get(); +} + +void EditorPanel::onAppChooserDialogResponse(int responseId) +{ + switch (responseId) { + case Gtk::RESPONSE_OK: + getAppChooserDialog()->close(); + external_editor_info = getAppChooserDialog()->get_app_info(); + sendToExternal(); + break; + case Gtk::RESPONSE_CANCEL: + case Gtk::RESPONSE_CLOSE: + getAppChooserDialog()->close(); + break; + default: + break; + } +} + void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { @@ -2392,6 +2442,26 @@ void EditorPanel::tbShowHideSidePanels_managestate() ShowHideSidePanelsconn.block (false); } +void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vector &editors) +{ + // Remove the editors and leave the "Other" entry. + while (send_to_external->getEntryCount() > 1) { + send_to_external->removeEntry(0); + } + // Add the editors. + for (unsigned i = 0; i < editors.size(); i++) { + const auto & name = editors[i].name.empty() ? Glib::ustring(" ") : editors[i].name; + if (!editors[i].icon_name.empty()) { + Glib::RefPtr gioIcon = Gio::Icon::create(editors[i].icon_name); + send_to_external->insertEntry(i, gioIcon, name); + } else { + send_to_external->insertEntry(i, "palette-brush.png", name); + } + } + send_to_external->setSelected(selectedIndex); + send_to_external->show(); +} + void EditorPanel::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) { } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 7675face5..0008786fa 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -43,6 +43,7 @@ class EditorPanel; class FilePanel; class MyProgressBar; class Navigator; +class PopUpButton; class Thumbnail; class ToolPanelCoordinator; @@ -162,7 +163,9 @@ public: void tbBeforeLock_toggled(); void saveAsPressed (); void queueImgPressed (); - void sendToGimpPressed (); + void sendToExternal(); + void sendToExternalChanged(int); + void sendToExternalPressed(); void openNextEditorImage (); void openPreviousEditorImage (); void syncFileBrowser (); @@ -182,6 +185,7 @@ public: { return isProcessing; } + void updateExternalEditorWidget(int selectedIndex, const std::vector &editors); void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); void updateTPVScrollbar (bool hide); void updateHistogramPosition (int oldPosition, int newPosition); @@ -201,6 +205,8 @@ private: bool idle_sendToGimp ( ProgressConnector *pc, Glib::ustring fname); bool idle_sentToGimp (ProgressConnector *pc, rtengine::IImagefloat* img, Glib::ustring filename); void histogramProfile_toggled (); + Gtk::AppChooserDialog *getAppChooserDialog(); + void onAppChooserDialogResponse(int resposneId); Glib::ustring lastSaveAsFileName; @@ -230,10 +236,12 @@ private: Gtk::Button* queueimg; Gtk::Button* saveimgas; - Gtk::Button* sendtogimp; + PopUpButton* send_to_external; Gtk::Button* navSync; Gtk::Button* navNext; Gtk::Button* navPrev; + Glib::RefPtr external_editor_info; + std::unique_ptr app_chooser_dialog; class ColorManagementToolbar; std::unique_ptr colorMgmtToolBar; diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index fabc4d572..c33ac068e 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -251,7 +251,7 @@ void PopUpCommon::setButtonHint() auto item = dynamic_cast(widget); if (item) { - hint += item->getLabel ()->get_text (); + hint += escapeHtmlChars(item->getLabel()->get_text()); } } diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 9d9603297..d4f550dd3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include +#include "externaleditorpreferences.h" #include "preferences.h" #include "multilangmgr.h" #include "splash.h" @@ -33,6 +34,8 @@ #include #endif +//#define EXT_EDITORS_RADIOS // TODO: Remove the corresponding code after testing. + namespace { void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::string &labelText, int digits, int inc0, int inc1, int maxLength, int range0, int range1, const std::string &toolTip = "") { Gtk::Box* HB = Gtk::manage ( new Gtk::Box () ); @@ -1188,6 +1191,7 @@ Gtk::Widget* Preferences::getGeneralPanel() Gtk::Frame* fdg = Gtk::manage(new Gtk::Frame(M("PREFERENCES_EXTERNALEDITOR"))); setExpandAlignProperties(fdg, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); +#ifdef EXT_EDITORS_RADIOS Gtk::Grid* externaleditorGrid = Gtk::manage(new Gtk::Grid()); externaleditorGrid->set_column_spacing(4); externaleditorGrid->set_row_spacing(4); @@ -1243,8 +1247,17 @@ Gtk::Widget* Preferences::getGeneralPanel() externaleditorGrid->attach_next_to(*edOther, *edGimp, Gtk::POS_BOTTOM, 1, 1); externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1); #endif +#endif + + externalEditors = Gtk::make_managed(); + externalEditors->set_size_request(-1, 200); +#ifdef EXT_EDITORS_RADIOS + externaleditorGrid->attach_next_to(*externalEditors, *edOther, Gtk::POS_BOTTOM, 2, 1); fdg->add(*externaleditorGrid); +#else + fdg->add(*externalEditors); +#endif 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) ); @@ -1700,6 +1713,7 @@ void Preferences::storePreferences() moptions.pseudoHiDPISupport = pseudoHiDPI->get_active(); +#ifdef EXT_EDITORS_RADIOS #ifdef WIN32 moptions.gimpDir = gimpDir->get_filename(); moptions.psDir = psDir->get_filename(); @@ -1726,6 +1740,20 @@ void Preferences::storePreferences() else if (edOther->get_active()) { moptions.editorToSendTo = 3; } +#endif + + const std::vector &editors = externalEditors->getEditors(); + moptions.externalEditors.resize(editors.size()); + moptions.externalEditorIndex = -1; + for (unsigned i = 0; i < editors.size(); i++) { + moptions.externalEditors[i] = (ExternalEditor( + editors[i].name, editors[i].command, editors[i].icon_name)); + if (editors[i].other_data) { + // The current editor was marked before the list was edited. We + // found the mark, so this is the editor that was active. + moptions.externalEditorIndex = i; + } + } moptions.CPBPath = txtCustProfBuilderPath->get_text(); moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); @@ -1981,6 +2009,7 @@ void Preferences::fillPreferences() hlThresh->set_value(moptions.highlightThreshold); shThresh->set_value(moptions.shadowThreshold); +#ifdef EXT_EDITORS_RADIOS edGimp->set_active(moptions.editorToSendTo == 1); edOther->set_active(moptions.editorToSendTo == 3); #ifdef WIN32 @@ -2009,6 +2038,18 @@ void Preferences::fillPreferences() #endif editorToSendTo->set_text(moptions.customEditorProg); +#endif + + std::vector editorInfos; + for (const auto &editor : moptions.externalEditors) { + editorInfos.push_back(ExternalEditorPreferences::EditorInfo( + editor.name, editor.command, editor.icon_name)); + } + if (moptions.externalEditorIndex >= 0) { + // Mark the current editor so we can track it. + editorInfos[moptions.externalEditorIndex].other_data = (void *)1; + } + externalEditors->setEditors(editorInfos); txtCustProfBuilderPath->set_text(moptions.CPBPath); custProfBuilderLabelType->set_active(moptions.CPBKeys); @@ -2474,6 +2515,23 @@ void Preferences::workflowUpdate() parent->updateProfiles (moptions.rtSettings.printerProfile, rtengine::RenderingIntent(moptions.rtSettings.printerIntent), moptions.rtSettings.printerBPC); } + bool changed = moptions.externalEditorIndex != options.externalEditorIndex + || moptions.externalEditors.size() != options.externalEditors.size(); + if (!changed) { + auto &editors = options.externalEditors; + auto &meditors = moptions.externalEditors; + for (unsigned i = 0; i < editors.size(); i++) { + if (editors[i] != meditors[i]) { + changed = true; + break; + } + } + } + if (changed) { + // Update the send to external editor widget. + parent->updateExternalEditorWidget(moptions.externalEditorIndex, moptions.externalEditors); + } + } void Preferences::addExtPressed() diff --git a/rtgui/preferences.h b/rtgui/preferences.h index df4e3327a..9e0730c04 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -26,6 +26,7 @@ #include "options.h" #include "../rtengine/profilestore.h" +class ExternalEditorPreferences; class RTWindow; class Splash; @@ -101,6 +102,7 @@ class Preferences final : Gtk::RadioButton* edGimp; Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; + ExternalEditorPreferences *externalEditors; MyFileChooserButton* darkFrameDir; MyFileChooserButton* flatFieldDir; MyFileChooserButton* clutsDir; diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c0042f949..0822c0aad 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -1030,6 +1030,13 @@ void RTWindow::MoveFileBrowserToEditor() } } +void RTWindow::updateExternalEditorWidget(int selectedIndex, const std::vector & editors) +{ + if (epanel) { + epanel->updateExternalEditorWidget(selectedIndex, editors); + } +} + void RTWindow::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) { if (epanel) { diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index e5e180747..32d0756b5 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -33,6 +33,7 @@ class BatchQueueEntry; class BatchQueuePanel; class EditorPanel; +class ExternalEditor; class FilePanel; class PLDBridge; class RTWindow final : @@ -114,6 +115,7 @@ public: void MoveFileBrowserToEditor(); void MoveFileBrowserToMain(); + void updateExternalEditorWidget(int selectedIndex, const std::vector &editors); void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); void updateTPVScrollbar (bool hide); void updateHistogramPosition (int oldPosition, int newPosition); From 044451868ac623bda15a5b8d1a6d02f37b5b31b4 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 17 Apr 2021 22:11:17 -0700 Subject: [PATCH 019/326] Add missing parenthesis --- rtgui/options.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 2a00af525..a967ed873 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -916,7 +916,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 3) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("-", executable, ""); + externalEditors.push_back(ExternalEditor("-", executable, "")); } #elif defined __APPLE__ if (editorToSendTo == 1) { From e6b2c9e7b06bf67b511db5ae53a172d08c8ab6fb Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 18 Apr 2021 12:33:32 -0700 Subject: [PATCH 020/326] Make options ignore empty custom editor command --- rtgui/options.cc | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index a967ed873..cf577fe7d 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -875,7 +875,7 @@ void Options::readFromFile(Glib::ustring fname) // GIMP == 1, Photoshop == 2, Custom == 3. editorToSendTo = keyFile.get_integer("External Editor", "EditorKind"); - #ifdef WIN32 +#ifdef WIN32 Glib::ustring gimpDir = ""; if (keyFile.has_key("External Editor", "GimpDir")) { gimpDir = keyFile.get_string("External Editor", "GimpDir"); @@ -903,7 +903,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "PhotoshopDir")) { psDir = keyFile.get_string("External Editor", "PhotoshopDir"); } - auto executable = Glib::build_filename(psDir, "Photoshop.exe"); + executable = Glib::build_filename(psDir, "Photoshop.exe"); if (Glib::file_test(executable, Glib::FILE_TEST_IS_EXECUTABLE)) { if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); @@ -913,12 +913,14 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "CustomEditor")) { executable = keyFile.get_string("External Editor", "CustomEditor"); - if (editorToSendTo == 3) { - externalEditorIndex = externalEditors.size(); + if (!executable.empty()) { + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, "")); } - externalEditors.push_back(ExternalEditor("-", executable, "")); } - #elif defined __APPLE__ +#elif defined __APPLE__ if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } @@ -932,12 +934,14 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "CustomEditor")) { auto executable = keyFile.get_string("External Editor", "CustomEditor"); - if (editorToSendTo == 3) { - externalEditorIndex = externalEditors.size(); + if (!executable.empty()) { + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, "")); } - externalEditors.push_back(ExternalEditor("-", executable, "")); } - #else +#else if (Glib::find_program_in_path("gimp").compare("")) { if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); @@ -952,12 +956,14 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "CustomEditor")) { auto executable = keyFile.get_string("External Editor", "CustomEditor"); - if (editorToSendTo == 3) { - externalEditorIndex = externalEditors.size(); + if (!executable.empty()) { + if (editorToSendTo == 3) { + externalEditorIndex = externalEditors.size(); + } + externalEditors.push_back(ExternalEditor("-", executable, "")); } - externalEditors.push_back(ExternalEditor("-", executable, "")); } - #endif +#endif } } From d9fe87569dabbbc5ee561c93e230b75e88ea3ee7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 18 Apr 2021 17:23:40 -0700 Subject: [PATCH 021/326] Cache most recent send-to-editor temp file Caches the name of the most recently generated temporary file used for exporting to external editors and uses that file if the processing parameters are identical and the file exists. This can dramatically improve speed when exporting to multiple different editors. --- rtgui/editorpanel.cc | 22 ++++++++++++++++++---- rtgui/editorpanel.h | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index e5543105c..021333503 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1974,6 +1974,14 @@ void EditorPanel::sendToExternal() // develop image rtengine::procparams::ProcParams pparams; ipc->getParams (&pparams); + + if (!cached_exported_filename.empty() && pparams == cached_exported_pparams && Glib::file_test(cached_exported_filename, Glib::FILE_TEST_IS_REGULAR)) { + idle_sentToGimp(nullptr, nullptr, cached_exported_filename); + return; + } + + cached_exported_pparams = pparams; + cached_exported_filename.clear(); rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); ProgressConnector *ld = new ProgressConnector(); ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ), @@ -2112,12 +2120,18 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagefloat* img, Glib::ustring filename) { - delete img; - int errore = pc->returnValue(); + if (img) { + delete img; + cached_exported_filename = filename; + } + int errore = 0; setProgressState(false); - delete pc; + if (pc) { + errore = pc->returnValue(); + delete pc; + } - if (!errore) { + if ((!img && Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR)) || (img && !errore)) { saveimgas->set_sensitive (true); send_to_external->set_sensitive(true); parent->setProgressStr (""); diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 0008786fa..1e6eaaa1f 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -243,6 +243,9 @@ private: Glib::RefPtr external_editor_info; std::unique_ptr app_chooser_dialog; + rtengine::procparams::ProcParams cached_exported_pparams; + Glib::ustring cached_exported_filename; + class ColorManagementToolbar; std::unique_ptr colorMgmtToolBar; From 9fcf45dca5e52ff9133e7c53d1b8e6795a680b37 Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Tue, 27 Apr 2021 21:35:43 +0200 Subject: [PATCH 022/326] Several fixes and changes made by Floessie earlier --- rtengine/dcp.cc | 518 +++++++++++++++++++++----------------- rtengine/hilite_recon.cc | 12 +- rtengine/histmatching.cc | 2 +- rtengine/iplocallab.cc | 17 +- rtengine/simpleprocess.cc | 2 +- rtgui/exifpanel.cc | 1 - rtgui/thumbnail.cc | 5 +- 7 files changed, 307 insertions(+), 250 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 8f829635b..feca2422a 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -449,6 +449,7 @@ std::map getAliases(const Glib::ustring& profile_dir) class DCPMetadata { +private: enum TagType { INVALID = 0, BYTE = 1, @@ -472,16 +473,18 @@ class DCPMetadata }; public: - explicit DCPMetadata(FILE *file): order_(UNKNOWN), file_(file) {} + explicit DCPMetadata(FILE *file) : + file_(file), + order_(UNKNOWN) + { + } bool parse() { - int offset = 0; - FILE *f = file_; - if (!f) { + if (!file_) { #ifndef NDEBUG if (settings->verbose) { - std::cerr << "ERROR : no file opened !" << std::endl; + std::cerr << "ERROR: No file opened." << std::endl; } #endif return false; @@ -490,31 +493,28 @@ public: setlocale(LC_NUMERIC, "C"); // to set decimal point in sscanf // read tiff header - fseek(f, 0, SEEK_SET); - unsigned short bo; - fread(&bo, 1, 2, f); - order_ = ByteOrder(int(bo)); + std::fseek(file_, 0, SEEK_SET); + std::uint16_t bo; + std::fread(&bo, 1, 2, file_); + order_ = ByteOrder(bo); - get2(f, order_); - if (!offset) { - offset = get4(f, order_); - } + get2(); // Skip - // seek to IFD - fseek(f, offset, SEEK_SET); + // Seek to IFD + const std::size_t offset = get4(); + std::fseek(file_, offset, SEEK_SET); - // first read the IFD directory - int numtags = get2(f, order_); + // First read the IFD directory + const std::uint16_t numtags = get2(); - if (numtags <= 0 || numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit + if (numtags > 1000) { // KodakIfd has lots of tags, thus 1000 as the limit return false; } - int base = 0; - for (int i = 0; i < numtags; i++) { - Tag t; - if (parse_tag(t, f, base, order_)) { - tags_[t.id] = std::move(t); + for (std::uint16_t i = 0; i < numtags; ++i) { + Tag tag; + if (parseTag(tag)) { + tags_[tag.id] = std::move(tag); } } @@ -526,215 +526,283 @@ public: return tags_.find(id) != tags_.end(); } - std::string toString(int id) + std::string toString(int id) const { - auto it = tags_.find(id); - if (it != tags_.end()) { - auto &t = it->second; - if (t.type == ASCII) { - std::ostringstream buf; - unsigned char *value = &(t.value[0]); - buf << value; - return buf.str(); + const Tags::const_iterator tag = tags_.find(id); + if (tag != tags_.end()) { + if (tag->second.type == ASCII) { + return std::string(tag->second.value.begin(), tag->second.value.end()).c_str(); } } - return ""; + return {}; } - int toInt(int id, int ofs=0, TagType astype=INVALID) + std::int32_t toInt(int id, std::size_t offset = 0, TagType as_type = INVALID) const { - auto it = tags_.find(id); - if (it == tags_.end()) { + const Tags::const_iterator tag = tags_.find(id); + if (tag == tags_.end()) { return 0; } - auto &t = it->second; - int a; - unsigned char *value = &(t.value[0]); - - if (astype == INVALID) { - astype = t.type; + if (as_type == INVALID) { + as_type = tag->second.type; } - switch (astype) { - case SBYTE: - return reinterpret_cast(value)[ofs]; - case BYTE: - return value[ofs]; - case SSHORT: - return int2_to_signed(sget2(value + ofs, order_)); - case SHORT: - return sget2(value + ofs, order_); - case SLONG: - case LONG: - return sget4 (value + ofs, order_); - case SRATIONAL: - case RATIONAL: - a = sget4(value + ofs + 4, order_); - return a == 0 ? 0 : int(sget4(value + ofs, order_)) / a; - case FLOAT: - return toDouble(id, ofs); - default: - return 0; - + switch (as_type) { + case SBYTE: { + if (offset < tag->second.value.size()) { + return static_cast(tag->second.value[offset]); + } + return 0; + } + case BYTE: { + if (offset < tag->second.value.size()) { + return tag->second.value[offset]; + } + return 0; + } + case SSHORT: { + if (offset + 1 < tag->second.value.size()) { + return static_cast(sget2(tag->second.value.data() + offset)); + } + return 0; + } + case SHORT: { + if (offset + 1 < tag->second.value.size()) { + return sget2(tag->second.value.data() + offset); + } + return 0; + } + case SLONG: + case LONG: { + if (offset + 3 < tag->second.value.size()) { + return sget4(tag->second.value.data() + offset); + } + return 0; + } + case SRATIONAL: + case RATIONAL: { + if (offset + 7 < tag->second.value.size()) { + const std::uint32_t denominator = sget4(tag->second.value.data() + offset + 4); + return + denominator == 0 + ? 0 + : static_cast(sget4(tag->second.value.data() + offset)) / denominator; + } + return 0; + } + case FLOAT: { + return toDouble(id, offset); + } + default: { + return 0; + } } } - int toShort(int id, int ofs=0) + int toShort(int id, std::size_t offset = 0) const { - return toInt(id, ofs, SHORT); + return toInt(id, offset, SHORT); } - double toDouble(int id, int ofs=0) + double toDouble(int id, std::size_t offset = 0) const { - auto it = tags_.find(id); - if (it == tags_.end()) { + const Tags::const_iterator tag = tags_.find(id); + if (tag == tags_.end()) { return 0.0; } - - auto &t = it->second; - union IntFloat { - uint32_t i; - float f; - } conv; - - int ud, dd; - unsigned char *value = &(t.value[0]); - - switch (t.type) { - case SBYTE: - return int((reinterpret_cast (value))[ofs]); - case BYTE: - return int(value[ofs]); - case SSHORT: - return int2_to_signed(sget2(value + ofs, order_)); - case SHORT: - return sget2(value + ofs, order_); - case SLONG: - case LONG: - return sget4(value + ofs, order_); - case SRATIONAL: - case RATIONAL: - ud = sget4(value + ofs, order_); - dd = sget4(value + ofs + 4, order_); - return (dd ? double(ud)/double(dd) : 0.0); - case FLOAT: - conv.i = sget4(value + ofs, order_); - return conv.f; // IEEE FLOATs are already C format, they just need a recast - default: - return 0.; - + switch (tag->second.type) { + case SBYTE: { + if (offset < tag->second.value.size()) { + return static_cast(tag->second.value[offset]); + } + return 0.0; + } + case BYTE: { + if (offset < tag->second.value.size()) { + return tag->second.value[offset]; + } + return 0.0; + } + case SSHORT: { + if (offset + 1 < tag->second.value.size()) { + return static_cast(sget2(tag->second.value.data() + offset)); + } + return 0.0; + } + case SHORT: { + if (offset + 1 < tag->second.value.size()) { + return sget2(tag->second.value.data() + offset); + } + return 0.0; + } + case SLONG: + case LONG: { + if (offset + 3 < tag->second.value.size()) { + return sget4(tag->second.value.data() + offset); + } + return 0.0; + } + case SRATIONAL: + case RATIONAL: { + if (offset + 7 < tag->second.value.size()) { + const std::int32_t numerator = sget4(tag->second.value.data() + offset); + const std::int32_t denominator = sget4(tag->second.value.data() + offset + 4); + return + denominator == 0 + ? 0.0 + : static_cast(numerator) / static_cast(denominator); + } + return 0.0; + } + case FLOAT: { + union IntFloat { + std::uint32_t i; + float f; + } conv; + conv.i = sget4(tag->second.value.data() + offset); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + } + default: { + return 0.0; + } } } - unsigned int getCount(int id) + unsigned int getCount(int id) const { - auto it = tags_.find(id); - if (it != tags_.end()) { - return it->second.count; + const Tags::const_iterator tag = tags_.find(id); + if (tag != tags_.end()) { + return tag->second.count; } return 0; } private: - static unsigned short sget2(unsigned char *s, ByteOrder order) + struct Tag { + int id; + std::vector value; + TagType type; + unsigned int count; + }; + + using Tags = std::unordered_map; + + std::uint16_t sget2(const std::uint8_t* s) const { - if (order == INTEL) { + if (order_ == INTEL) { return s[0] | s[1] << 8; } else { return s[0] << 8 | s[1]; } } - static int sget4(unsigned char *s, ByteOrder order) + std::uint32_t sget4(const std::uint8_t* s) const { - if (order == INTEL) { + if (order_ == INTEL) { return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; } else { return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } } - static unsigned short get2(FILE* f, ByteOrder order) + std::uint16_t get2() { - unsigned char str[2] = { 0xff, 0xff }; - fread (str, 1, 2, f); - return sget2(str, order); + std::uint16_t res = std::numeric_limits::max(); + std::fread(&res, 1, 2, file_); + return sget2(reinterpret_cast(&res)); } - static int get4(FILE *f, ByteOrder order) + std::uint32_t get4() { - unsigned char str[4] = { 0xff, 0xff, 0xff, 0xff }; - fread (str, 1, 4, f); - return sget4 (str, order); - } - - static short int int2_to_signed(short unsigned int i) - { - union { - short unsigned int i; - short int s; - } u; - u.i = i; - return u.s; + std::uint32_t res = std::numeric_limits::max(); + std::fread(&res, 1, 4, file_); + return sget4(reinterpret_cast(&res)); } static int getTypeSize(TagType type) { - return ("11124811248484"[type < 14 ? type : 0] - '0'); + switch (type) { + case INVALID: + case BYTE: + case ASCII: + case SBYTE: + case UNDEFINED: { + return 1; + } + + case SHORT: + case SSHORT: { + return 2; + } + + case LONG: + case SLONG: + case FLOAT: { + return 4; + } + + case RATIONAL: + case SRATIONAL: + case DOUBLE: { + return 8; + } + } + + return 1; } - struct Tag { - int id; - std::vector value; - TagType type; - unsigned int count; - - Tag(): id(0), value(), type(INVALID), count(0) {} - }; - - bool parse_tag(Tag &t, FILE *f, int base, ByteOrder order) + bool parseTag(Tag& tag) { - t.id = get2(f, order); - t.type = (TagType)get2(f, order); - t.count = get4(f, order); + tag.id = get2(); + tag.type = TagType(get2()); + tag.count = std::max(1U, get4()); - if (!t.count) { - t.count = 1; - } - - // filter out invalid tags - // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, + // Filter out invalid tags + // Note: The large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, // (only a small part of it will actually be parsed though) - if ((int)t.type < 1 || (int)t.type > 12 || t.count > 10 * 1024 * 1024) { - t.type = INVALID; + if ( + tag.type == INVALID + || tag.type > DOUBLE + || tag.count > 10 * 1024 * 1024 + ) { + tag.type = INVALID; return false; } - // store next Tag's position in file - int save = ftell(f) + 4; + // Store next Tag's position in file + const std::size_t saved_position = std::ftell(file_) + 4; - // load value field (possibly seek before) - int valuesize = t.count * getTypeSize(t.type); + // Load value field (possibly seek before) + const std::size_t value_size = tag.count * getTypeSize(tag.type); - if (valuesize > 4) { - fseek(f, get4(f, order) + base, SEEK_SET); + if (value_size > 4) { + if (std::fseek(file_, get4(), SEEK_SET) == -1) { + tag.type = INVALID; + return false; + } } - // read value - t.value.resize(valuesize + 1); - auto readSize = fread(&(t.value[0]), 1, valuesize, f); - t.value[readSize] = '\0'; + // Read value + tag.value.resize(value_size + 1); + const std::size_t read = std::fread(tag.value.data(), 1, value_size, file_); + if (read != value_size) { + tag.type = INVALID; + return false; + } + tag.value[read] = '\0'; - // seek back to the saved position - fseek(f, save, SEEK_SET); + // Seek back to the saved position + std::fseek(file_, saved_position, SEEK_SET); + return true; } - - std::unordered_map tags_; + + FILE* const file_; + + Tags tags_; ByteOrder order_; - FILE *file_; }; } // namespace @@ -772,22 +840,22 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : constexpr int tiff_float_size = 4; enum TagKey { - COLOR_MATRIX_1 = 50721, - COLOR_MATRIX_2 = 50722, - PROFILE_HUE_SAT_MAP_DIMS = 50937, - PROFILE_HUE_SAT_MAP_DATA_1 = 50938, - PROFILE_HUE_SAT_MAP_DATA_2 = 50939, - PROFILE_TONE_CURVE = 50940, - PROFILE_TONE_COPYRIGHT = 50942, - CALIBRATION_ILLUMINANT_1 = 50778, - CALIBRATION_ILLUMINANT_2 = 50779, - FORWARD_MATRIX_1 = 50964, - FORWARD_MATRIX_2 = 50965, - PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant - PROFILE_LOOK_TABLE_DATA = 50982, - PROFILE_HUE_SAT_MAP_ENCODING = 51107, - PROFILE_LOOK_TABLE_ENCODING = 51108, - BASELINE_EXPOSURE_OFFSET = 51109 + TAG_KEY_COLOR_MATRIX_1 = 50721, + TAG_KEY_COLOR_MATRIX_2 = 50722, + TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS = 50937, + TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1 = 50938, + TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2 = 50939, + TAG_KEY_PROFILE_TONE_CURVE = 50940, + TAG_KEY_PROFILE_TONE_COPYRIGHT = 50942, + TAG_KEY_CALIBRATION_ILLUMINANT_1 = 50778, + TAG_KEY_CALIBRATION_ILLUMINANT_2 = 50779, + TAG_KEY_FORWARD_MATRIX_1 = 50964, + TAG_KEY_FORWARD_MATRIX_2 = 50965, + TAG_KEY_PROFILE_LOOK_TABLE_DIMS = 50981, // ProfileLookup is the low quality variant + TAG_KEY_PROFILE_LOOK_TABLE_DATA = 50982, + TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING = 51107, + TAG_KEY_PROFILE_LOOK_TABLE_ENCODING = 51108, + TAG_KEY_BASELINE_EXPOSURE_OFFSET = 51109 }; static const float adobe_camera_raw_default_curve[] = { @@ -1059,46 +1127,46 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : DCPMetadata md(file); if (!md.parse()) { - //printf ("Unable to load DCP profile '%s' !", filename.c_str()); + printf ("Unable to load DCP profile '%s'.", filename.c_str()); return; } light_source_1 = - md.find(CALIBRATION_ILLUMINANT_1) ? - md.toShort(CALIBRATION_ILLUMINANT_1) : - -1; + md.find(TAG_KEY_CALIBRATION_ILLUMINANT_1) + ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_1) + : -1; light_source_2 = - md.find(CALIBRATION_ILLUMINANT_2) ? - md.toShort(CALIBRATION_ILLUMINANT_2) : - -1; + md.find(TAG_KEY_CALIBRATION_ILLUMINANT_2) + ? md.toShort(TAG_KEY_CALIBRATION_ILLUMINANT_2) + : -1; temperature_1 = calibrationIlluminantToTemperature(light_source_1); temperature_2 = calibrationIlluminantToTemperature(light_source_2); - const bool has_second_hue_sat = md.find(PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat + const bool has_second_hue_sat = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2); // Some profiles have two matrices, but just one huesat // Fetch Forward Matrices, if any - has_forward_matrix_1 = md.find(FORWARD_MATRIX_1); + has_forward_matrix_1 = md.find(TAG_KEY_FORWARD_MATRIX_1); if (has_forward_matrix_1) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_1[row][col] = md.toDouble(FORWARD_MATRIX_1, (col + row * 3) * 8); + forward_matrix_1[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_1, (col + row * 3) * 8); } } } - has_forward_matrix_2 = md.find(FORWARD_MATRIX_2); + has_forward_matrix_2 = md.find(TAG_KEY_FORWARD_MATRIX_2); if (has_forward_matrix_2) { for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - forward_matrix_2[row][col] = md.toDouble(FORWARD_MATRIX_2, (col + row * 3) * 8); + forward_matrix_2[row][col] = md.toDouble(TAG_KEY_FORWARD_MATRIX_2, (col + row * 3) * 8); } } } // Color Matrix (one is always there) - if (!md.find(COLOR_MATRIX_1)) { + if (!md.find(TAG_KEY_COLOR_MATRIX_1)) { if (settings->verbose) { std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; } @@ -1110,24 +1178,24 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - color_matrix_1[row][col] = md.toDouble(COLOR_MATRIX_1, (col + row * 3) * 8); + color_matrix_1[row][col] = md.toDouble(TAG_KEY_COLOR_MATRIX_1, (col + row * 3) * 8); } } - if (md.find(PROFILE_LOOK_TABLE_DIMS)) { - look_info.hue_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 0); - look_info.sat_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 4); - look_info.val_divisions = md.toInt(PROFILE_LOOK_TABLE_DIMS, 8); + if (md.find(TAG_KEY_PROFILE_LOOK_TABLE_DIMS)) { + look_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 0); + look_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 4); + look_info.val_divisions = md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_DIMS, 8); - look_info.srgb_gamma = md.find(PROFILE_LOOK_TABLE_ENCODING) && md.toInt(PROFILE_LOOK_TABLE_ENCODING); + look_info.srgb_gamma = md.find(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING) && md.toInt(TAG_KEY_PROFILE_LOOK_TABLE_ENCODING); - look_info.array_count = md.getCount(PROFILE_LOOK_TABLE_DATA) / 3; + look_info.array_count = md.getCount(TAG_KEY_PROFILE_LOOK_TABLE_DATA) / 3; look_table.resize(look_info.array_count); for (unsigned int i = 0; i < look_info.array_count; i++) { - look_table[i].hue_shift = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); - look_table[i].sat_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); - look_table[i].val_scale = md.toDouble(PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); + look_table[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3) * tiff_float_size); + look_table[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 1) * tiff_float_size); + look_table[i].val_scale = md.toDouble(TAG_KEY_PROFILE_LOOK_TABLE_DATA, (i * 3 + 2) * tiff_float_size); } // Precalculated constants for table application @@ -1144,20 +1212,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : look_info.pc.val_step = look_info.hue_divisions * look_info.pc.hue_step; } - if (md.find(PROFILE_HUE_SAT_MAP_DIMS)) { - delta_info.hue_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 0); - delta_info.sat_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 4); - delta_info.val_divisions = md.toInt(PROFILE_HUE_SAT_MAP_DIMS, 8); + if (md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS)) { + delta_info.hue_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 0); + delta_info.sat_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 4); + delta_info.val_divisions = md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_DIMS, 8); - delta_info.srgb_gamma = md.find(PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(PROFILE_HUE_SAT_MAP_ENCODING); + delta_info.srgb_gamma = md.find(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING) && md.toInt(TAG_KEY_PROFILE_HUE_SAT_MAP_ENCODING); - delta_info.array_count = md.getCount(PROFILE_HUE_SAT_MAP_DATA_1) / 3; + delta_info.array_count = md.getCount(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1) / 3; deltas_1.resize(delta_info.array_count); for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_1[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); - deltas_1[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); - deltas_1[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); + deltas_1[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3) * tiff_float_size); + deltas_1[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 1) * tiff_float_size); + deltas_1[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_1, (i * 3 + 2) * tiff_float_size); } delta_info.pc.h_scale = @@ -1177,14 +1245,14 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Second matrix has_color_matrix_2 = true; - bool cm2 = md.find(COLOR_MATRIX_2); + const bool cm2 = md.find(TAG_KEY_COLOR_MATRIX_2); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { color_matrix_2[row][col] = cm2 - ? md.toDouble(COLOR_MATRIX_2, (col + row * 3) * 8) - : color_matrix_1[row][col]; + ? md.toDouble(TAG_KEY_COLOR_MATRIX_2, (col + row * 3) * 8) + : color_matrix_1[row][col]; } } @@ -1194,20 +1262,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Saturation maps. Need to be unwinded. for (unsigned int i = 0; i < delta_info.array_count; ++i) { - deltas_2[i].hue_shift = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); - deltas_2[i].sat_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); - deltas_2[i].val_scale = md.toDouble(PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); + deltas_2[i].hue_shift = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3) * tiff_float_size); + deltas_2[i].sat_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 1) * tiff_float_size); + deltas_2[i].val_scale = md.toDouble(TAG_KEY_PROFILE_HUE_SAT_MAP_DATA_2, (i * 3 + 2) * tiff_float_size); } } } - has_baseline_exposure_offset = md.find(BASELINE_EXPOSURE_OFFSET); + has_baseline_exposure_offset = md.find(TAG_KEY_BASELINE_EXPOSURE_OFFSET); if (has_baseline_exposure_offset) { - baseline_exposure_offset = md.toDouble(BASELINE_EXPOSURE_OFFSET); + baseline_exposure_offset = md.toDouble(TAG_KEY_BASELINE_EXPOSURE_OFFSET); } // Read tone curve points, if any, but disable to RTs own profiles - if (md.find(PROFILE_TONE_CURVE)) { + if (md.find(TAG_KEY_PROFILE_TONE_CURVE)) { std::vector curve_points = { static_cast(DCT_Spline) // The first value is the curve type }; @@ -1215,9 +1283,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Push back each X/Y coordinates in a loop bool curve_is_linear = true; - for (unsigned int i = 0, n = md.getCount(PROFILE_TONE_CURVE); i < n; i += 2) { - const double x = md.toDouble(PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); - const double y = md.toDouble(PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); + for (unsigned int i = 0, n = md.getCount(TAG_KEY_PROFILE_TONE_CURVE); i < n; i += 2) { + const double x = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 0) * tiff_float_size); + const double y = md.toDouble(TAG_KEY_PROFILE_TONE_CURVE, (i + 1) * tiff_float_size); if (x != y) { curve_is_linear = false; @@ -1233,7 +1301,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : tone_curve.Set(DiagonalCurve(curve_points, CURVES_MIN_POLY_POINTS)); } } else { - if (md.find(PROFILE_TONE_COPYRIGHT) && md.toString(PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { + if (md.find(TAG_KEY_PROFILE_TONE_COPYRIGHT) && md.toString(TAG_KEY_PROFILE_TONE_COPYRIGHT).find("Adobe Systems") != std::string::npos) { // An Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that std::vector curve_points = { static_cast(DCT_Spline) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index a45e5d345..86fdd6800 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -1175,27 +1175,27 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue {2.0f, 3.0f, 0.001f} }; - const float rad1 = vals[blur][0]; - const float rad2 = vals[blur][1]; + const float radius1 = vals[blur][0]; + const float radius2 = vals[blur][1]; const float th = vals[blur][2]; - guidedFilter(guide, mask, mask, rad1, th, true, 1); + guidedFilter(guide, mask, mask, radius1, th, true, 1); if (plistener) { progress += 0.03; plistener->setProgress(progress); } if (blur > 0) { //no use of 2nd guidedFilter if Blur = 0 (slider to 1)..speed-up and very small differences. - guidedFilter(guide, rbuf, rbuf, rad2, 0.01f * 65535.f, true, 1); + guidedFilter(guide, rbuf, rbuf, radius2, 0.01f * 65535.f, true, 1); if (plistener) { progress += 0.03; plistener->setProgress(progress); } - guidedFilter(guide, gbuf, gbuf, rad2, 0.01f * 65535.f, true, 1); + guidedFilter(guide, gbuf, gbuf, radius2, 0.01f * 65535.f, true, 1); if (plistener) { progress += 0.03; plistener->setProgress(progress); } - guidedFilter(guide, bbuf, bbuf, rad2, 0.01f * 65535.f, true, 1); + guidedFilter(guide, bbuf, bbuf, radius2, 0.01f * 65535.f, true, 1); if (plistener) { progress += 0.03; plistener->setProgress(progress); diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 386c6faec..d9c57bc84 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -279,7 +279,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st { eSensorType sensor_type; int w = 0, h = 0; - std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, true, true)); + const std::unique_ptr thumb(Thumbnail::loadQuickFromRaw(getFileName(), sensor_type, w, h, 1, false, true, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: no thumbnail found, generating a neutral curve" << std::endl; diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 7ff84b632..c97c0c3a6 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2148,20 +2148,11 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, //calculate La - Absolute luminance shooting const FramesMetaData* metaData = imgsrc->getMetaData(); - int imgNum = 0; - - if (imgsrc->isRAW()) { - if (imgsrc->getSensorType() == ST_BAYER) { - imgNum = rtengine::LIM(params->raw.bayersensor.imageNum, 0, metaData->getFrameCount() - 1); - } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { - //imgNum = rtengine::LIM(params->raw.xtranssensor.imageNum, 0, metaData->getFrameCount() - 1); - } - } - float fnum = metaData->getFNumber(imgNum); // F number - float fiso = metaData->getISOSpeed(imgNum) ; // ISO - float fspeed = metaData->getShutterSpeed(imgNum) ; // Speed - double fcomp = metaData->getExpComp(imgNum); // Compensation +/- + float fnum = metaData->getFNumber(); // F number + float fiso = metaData->getISOSpeed() ; // ISO + float fspeed = metaData->getShutterSpeed() ; // Speed + double fcomp = metaData->getExpComp(); // Compensation +/- double adap; if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 53e581468..87b97807c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1282,7 +1282,7 @@ private: } autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfileApplyState as; + DCPProfile::ApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params.icm, as); LUTu histToneCurve; diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 844291a24..f452c2491 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -42,7 +42,6 @@ ExifPanel::ExifPanel() : } { set_orientation(Gtk::ORIENTATION_VERTICAL); - recursiveOp = true; exifTree = Gtk::manage (new Gtk::TreeView()); scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 598fc5efe..b05605350 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -46,9 +46,6 @@ #include "profilestorecombobox.h" #include "version.h" -#include "../rtengine/mytime.h" - -using namespace rtengine::procparams; namespace { @@ -109,6 +106,8 @@ bool CPBDump( } // namespace +using namespace rtengine::procparams; + Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf) : fname(fname), cfs(*cf), From 4044f67c0ff73dd793bd62908a198754978ef6a6 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 5 Jul 2021 11:01:51 -0700 Subject: [PATCH 023/326] Align External Editor > Output directory to top Prevents the frame from expanding vertically. --- rtgui/preferences.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d19481ea1..786262896 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1271,7 +1271,7 @@ Gtk::Widget* Preferences::getGeneralPanel() editor_bypass_output_profile = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE"))); { Gtk::Frame *f = Gtk::manage(new Gtk::Frame(M("PREFERENCES_EXTEDITOR_DIR"))); - setExpandAlignProperties(f, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + setExpandAlignProperties(f, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); Gtk::Box *vb = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); vb->pack_start(*editor_dir_temp); vb->pack_start(*editor_dir_current); From c62597545374b3427ae137a103584aa3f81afc7a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jul 2021 21:38:52 -0700 Subject: [PATCH 024/326] Surround Windows commands in quotes When external editors are launched in Windows OS, the command is surrounded by quotes. This commit fixes the translation of commands for use by the multiple custom external editors feature so that the translated commands are also surrounded by quotes. --- rtgui/options.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 88406452b..3bb3bb08f 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -912,7 +912,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", executable, "gimp")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", "gimp")); } else { for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); @@ -920,7 +920,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", executable, "gimp")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", "gimp")); break; } } @@ -935,7 +935,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", executable, "")); + externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", "")); } if (keyFile.has_key("External Editor", "CustomEditor")) { @@ -944,7 +944,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 3) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("-", executable, "")); + externalEditors.push_back(ExternalEditor("-", "\"" + executable + "\"", "")); } } #elif defined __APPLE__ From 02e3e0129453a37fa666ff85c793469a6b4fd6f8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jul 2021 21:45:39 -0700 Subject: [PATCH 025/326] Use correct GIMP and Photoshop icons for Windows Icon names in Windows are typically the executable path followed by the string ",0". --- rtgui/options.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 3bb3bb08f..6a944faa6 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -912,7 +912,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", "gimp")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); } else { for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); @@ -920,7 +920,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", "gimp")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); break; } } @@ -935,7 +935,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", "")); + externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", executable + ",0")); } if (keyFile.has_key("External Editor", "CustomEditor")) { From c4a8554db3da65d50497703ccd4951dbb16a86b9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jul 2021 22:13:27 -0700 Subject: [PATCH 026/326] Catch exceptions when launching external editor Catch all Glib::Errors and print the error code and message to stderr. --- rtgui/extprog.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 148eee944..e4cf63733 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -342,5 +342,13 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo) { - return editorInfo->launch(Gio::File::create_for_path(fileName)); + try { + return editorInfo->launch(Gio::File::create_for_path(fileName)); + } catch (const Glib::Error &e) { + std::cerr + << "Error launching external editor.\n" + << "Error code #" << e.code() << ": " << e.what() + << std::endl; + return false; + } } From a0711ebc8c528e2b79706f4421c6181f1c71cce8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Jul 2021 16:03:13 -0700 Subject: [PATCH 027/326] Fix tmp image reuse when exporting different image If two images have identical processing parameters, then sending one to an external editor followed by sending the other one will cause the first temporary image to be reused. This commit associates the image in the editor with the "cached" temporary image so that the temporary image only gets used if the editor image matches. --- rtgui/editorpanel.cc | 3 ++- rtgui/editorpanel.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 5c61e672e..e52dab5db 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1980,11 +1980,12 @@ void EditorPanel::sendToExternal() pparams.icm.outputProfile = rtengine::procparams::ColorManagementParams::NoProfileString; } - if (!cached_exported_filename.empty() && pparams == cached_exported_pparams && Glib::file_test(cached_exported_filename, Glib::FILE_TEST_IS_REGULAR)) { + if (!cached_exported_filename.empty() && cached_exported_image == ipc->getInitialImage() && pparams == cached_exported_pparams && Glib::file_test(cached_exported_filename, Glib::FILE_TEST_IS_REGULAR)) { idle_sentToGimp(nullptr, nullptr, cached_exported_filename); return; } + cached_exported_image = ipc->getInitialImage(); cached_exported_pparams = pparams; cached_exported_filename.clear(); rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 1e6eaaa1f..1372a2171 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -243,6 +243,7 @@ private: Glib::RefPtr external_editor_info; std::unique_ptr app_chooser_dialog; + rtengine::InitialImage *cached_exported_image; rtengine::procparams::ProcParams cached_exported_pparams; Glib::ustring cached_exported_filename; From db7d56c253433e94d892f5bbeaa5226008a410f5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Jul 2021 17:45:20 -0700 Subject: [PATCH 028/326] Synchronize send to external editor buttons Keep all buttons updated when using a multiple editor tabs mode. --- rtgui/editorpanel.cc | 32 ++++++++++++++++++++++++++++++++ rtgui/editorpanel.h | 10 ++++++++++ rtgui/editwindow.cc | 2 ++ rtgui/editwindow.h | 2 ++ 4 files changed, 46 insertions(+) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index e52dab5db..6649fc970 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2003,6 +2003,9 @@ void EditorPanel::sendToExternalChanged(int) index = -1; } options.externalEditorIndex = index; + if (externalEditorChangedSignal) { + externalEditorChangedSignal->emit(); + } } void EditorPanel::sendToExternalPressed() @@ -2069,6 +2072,23 @@ void EditorPanel::syncFileBrowser() // synchronize filebrowser with image in E } } +ExternalEditorChangedSignal * EditorPanel::getExternalEditorChangedSignal() +{ + return externalEditorChangedSignal; +} + +void EditorPanel::setExternalEditorChangedSignal(ExternalEditorChangedSignal *signal) +{ + if (externalEditorChangedSignal) { + externalEditorChangedSignalConnection.disconnect(); + } + externalEditorChangedSignal = signal; + if (signal) { + externalEditorChangedSignalConnection = signal->connect( + sigc::mem_fun(*this, &EditorPanel::updateExternalEditorSelection)); + } +} + void EditorPanel::histogramProfile_toggled() { options.rtSettings.HistogramWorking = toggleHistogramProfile->get_active(); @@ -2203,6 +2223,18 @@ void EditorPanel::onAppChooserDialogResponse(int responseId) } } +void EditorPanel::updateExternalEditorSelection() +{ + int index = send_to_external->getSelected(); + if (index >= 0 && static_cast(index) == options.externalEditors.size()) { + index = -1; + } + if (options.externalEditorIndex != index) { + send_to_external->setSelected( + options.externalEditorIndex >= 0 ? options.externalEditorIndex : options.externalEditors.size()); + } +} + void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 1372a2171..1bbb95a6e 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -38,6 +38,8 @@ template class array2D; } +using ExternalEditorChangedSignal = sigc::signal; + class BatchQueueEntry; class EditorPanel; class FilePanel; @@ -66,6 +68,7 @@ class EditorPanel final : public rtengine::NonCopyable { public: + explicit EditorPanel (FilePanel* filePanel = nullptr); ~EditorPanel () override; @@ -170,6 +173,10 @@ public: void openPreviousEditorImage (); void syncFileBrowser (); + // Signals. + ExternalEditorChangedSignal * getExternalEditorChangedSignal(); + void setExternalEditorChangedSignal(ExternalEditorChangedSignal *signal); + void tbTopPanel_1_visible (bool visible); bool CheckSidePanelsVisibility(); void tbShowHideSidePanels_managestate(); @@ -207,6 +214,7 @@ private: void histogramProfile_toggled (); Gtk::AppChooserDialog *getAppChooserDialog(); void onAppChooserDialogResponse(int resposneId); + void updateExternalEditorSelection(); Glib::ustring lastSaveAsFileName; @@ -242,6 +250,8 @@ private: Gtk::Button* navPrev; Glib::RefPtr external_editor_info; std::unique_ptr app_chooser_dialog; + ExternalEditorChangedSignal *externalEditorChangedSignal; + sigc::connection externalEditorChangedSignalConnection; rtengine::InitialImage *cached_exported_image; rtengine::procparams::ProcParams cached_exported_pparams; diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index d0e53d730..0584edf77 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -250,6 +250,7 @@ void EditWindow::addEditorPanel (EditorPanel* ep, const std::string &name) { ep->setParent (parent); ep->setParentWindow(this); + ep->setExternalEditorChangedSignal(&externalEditorChangedSignal); // construct closeable tab for the image Gtk::Box* hb = Gtk::manage (new Gtk::Box ()); @@ -288,6 +289,7 @@ void EditWindow::remEditorPanel (EditorPanel* ep) return; // Will crash if destroyed while loading } + ep->setExternalEditorChangedSignal(nullptr); epanels.erase (ep->getFileName()); filesEdited.erase (ep->getFileName ()); parent->fpanel->refreshEditedState (filesEdited); diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index b8eeaee82..27d4598c1 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -39,6 +39,8 @@ private: std::set filesEdited; std::map epanels; + sigc::signal externalEditorChangedSignal; + bool isFullscreen; bool isClosed; bool isMinimized; From 9423ebc97c4839c40ca8e9a75b22f1f0f028e6c0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 14 Aug 2021 11:32:25 -0700 Subject: [PATCH 029/326] Fix crash when changing external editors Initialize a pointer to nullptr. --- rtgui/editorpanel.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 6649fc970..775e6a935 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -470,7 +470,9 @@ public: EditorPanel::EditorPanel (FilePanel* filePanel) : catalogPane (nullptr), realized (false), tbBeforeLock (nullptr), iHistoryShow (nullptr), iHistoryHide (nullptr), iTopPanel_1_Show (nullptr), iTopPanel_1_Hide (nullptr), iRightPanel_1_Show (nullptr), iRightPanel_1_Hide (nullptr), - iBeforeLockON (nullptr), iBeforeLockOFF (nullptr), previewHandler (nullptr), beforePreviewHandler (nullptr), + iBeforeLockON (nullptr), iBeforeLockOFF (nullptr), + externalEditorChangedSignal (nullptr), + previewHandler (nullptr), beforePreviewHandler (nullptr), beforeIarea (nullptr), beforeBox (nullptr), afterBox (nullptr), beforeLabel (nullptr), afterLabel (nullptr), beforeHeaderBox (nullptr), afterHeaderBox (nullptr), parent (nullptr), parentWindow (nullptr), openThm (nullptr), selectedFrame(0), isrc (nullptr), ipc (nullptr), beforeIpc (nullptr), err (0), isProcessing (false), From d3e524a491c900adac72ef10fde01c5c5c626127 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 14 Aug 2021 16:05:11 -0700 Subject: [PATCH 030/326] Fix crash when adding an external editor On some platforms, the app chooser dialog causes a crash after selecting an application. The application information returned by the dialog may also trigger crashes when accessed. See https://gitlab.gnome.org/GNOME/glib/-/issues/1104 and https://gitlab.gnome.org/GNOME/glibmm/-/issues/94. This commit overrides gtkmm's app chooser dialog to work around these bugs. --- rtgui/CMakeLists.txt | 1 + rtgui/editorpanel.cc | 7 +-- rtgui/editorpanel.h | 5 +- rtgui/externaleditorpreferences.cc | 4 +- rtgui/externaleditorpreferences.h | 7 +-- rtgui/rtappchooserdialog.cc | 77 ++++++++++++++++++++++++++++++ rtgui/rtappchooserdialog.h | 39 +++++++++++++++ 7 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 rtgui/rtappchooserdialog.cc create mode 100644 rtgui/rtappchooserdialog.h diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index ed6a0b364..3ca04dc2b 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -135,6 +135,7 @@ set(NONCLISOURCEFILES retinex.cc rgbcurves.cc rotate.cc + rtappchooserdialog.cc rtimage.cc rtscalable.cc rtsurface.cc diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 775e6a935..6cb90a444 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -39,6 +39,7 @@ #include "procparamchangers.h" #include "placesbrowser.h" #include "pathutils.h" +#include "rtappchooserdialog.h" #include "thumbnail.h" #include "toolpanelcoord.h" @@ -2014,7 +2015,7 @@ void EditorPanel::sendToExternalPressed() { if (options.externalEditorIndex == -1) { // "Other" external editor. Show app chooser dialog to let user pick. - Gtk::AppChooserDialog *dialog = getAppChooserDialog(); + RTAppChooserDialog *dialog = getAppChooserDialog(); dialog->show(); } else { struct ExternalEditor editor = options.externalEditors.at(options.externalEditorIndex); @@ -2195,10 +2196,10 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef return false; } -Gtk::AppChooserDialog *EditorPanel::getAppChooserDialog() +RTAppChooserDialog *EditorPanel::getAppChooserDialog() { if (!app_chooser_dialog.get()) { - app_chooser_dialog.reset(new Gtk::AppChooserDialog("image/tiff")); + app_chooser_dialog.reset(new RTAppChooserDialog("image/tiff")); app_chooser_dialog->signal_response().connect( sigc::mem_fun(*this, &EditorPanel::onAppChooserDialogResponse) ); diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 1bbb95a6e..e822f1677 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -46,6 +46,7 @@ class FilePanel; class MyProgressBar; class Navigator; class PopUpButton; +class RTAppChooserDialog; class Thumbnail; class ToolPanelCoordinator; @@ -212,7 +213,7 @@ private: bool idle_sendToGimp ( ProgressConnector *pc, Glib::ustring fname); bool idle_sentToGimp (ProgressConnector *pc, rtengine::IImagefloat* img, Glib::ustring filename); void histogramProfile_toggled (); - Gtk::AppChooserDialog *getAppChooserDialog(); + RTAppChooserDialog *getAppChooserDialog(); void onAppChooserDialogResponse(int resposneId); void updateExternalEditorSelection(); @@ -249,7 +250,7 @@ private: Gtk::Button* navNext; Gtk::Button* navPrev; Glib::RefPtr external_editor_info; - std::unique_ptr app_chooser_dialog; + std::unique_ptr app_chooser_dialog; ExternalEditorChangedSignal *externalEditorChangedSignal; sigc::connection externalEditorChangedSignalConnection; diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index df6b6efc2..b64cdcf9f 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -164,7 +164,7 @@ Gtk::TreeViewColumn *ExternalEditorPreferences::makeCommandColumn() } void ExternalEditorPreferences::onAppChooserDialogResponse( - int response_id, Gtk::AppChooserDialog *dialog) + int response_id, RTAppChooserDialog *dialog) { switch (response_id) { case Gtk::RESPONSE_OK: @@ -190,7 +190,7 @@ void ExternalEditorPreferences::openAppChooserDialog() return; } - app_chooser_dialog.reset(new Gtk::AppChooserDialog("image/tiff")); + app_chooser_dialog.reset(new RTAppChooserDialog("image/tiff")); app_chooser_dialog->signal_response().connect(sigc::bind( sigc::mem_fun(*this, &ExternalEditorPreferences::onAppChooserDialogResponse), app_chooser_dialog.get() diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index be988e901..dbd0f1648 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -18,7 +18,6 @@ */ #pragma once -#include #include #include #include @@ -26,6 +25,8 @@ #include #include +#include "rtappchooserdialog.h" + /** * Widget for editing the external editors options. @@ -98,7 +99,7 @@ private: Gtk::Button *button_app_chooser; Gtk::Button *button_add; Gtk::Button *button_remove; - std::unique_ptr app_chooser_dialog; + std::unique_ptr app_chooser_dialog; /** * Inserts a new editor entry after the current selection, or at the end if @@ -117,7 +118,7 @@ private: * Called when the user is done interacting with the app chooser dialog. * Closes the dialog and updates the selected entry if an app was chosen. */ - void onAppChooserDialogResponse(int responseId, Gtk::AppChooserDialog *dialog); + void onAppChooserDialogResponse(int responseId, RTAppChooserDialog *dialog); /** * Shows the app chooser dialog. */ diff --git a/rtgui/rtappchooserdialog.cc b/rtgui/rtappchooserdialog.cc new file mode 100644 index 000000000..50a71ee38 --- /dev/null +++ b/rtgui/rtappchooserdialog.cc @@ -0,0 +1,77 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "rtappchooserdialog.h" + +#if !(defined WIN32 || defined __APPLE__) +#define GTKMM_APPCHOOSERDIALOG +#endif + +RTAppChooserDialog::~RTAppChooserDialog() {} + +#ifdef GTKMM_APPCHOOSERDIALOG // Use Gtk::AppChooserDialog directly. + +RTAppChooserDialog::RTAppChooserDialog(const Glib::ustring &content_type) : + Gtk::AppChooserDialog(content_type) +{ +} + +Glib::RefPtr RTAppChooserDialog::get_app_info() +{ + return Gtk::AppChooserDialog::get_app_info(); +} + +Glib::RefPtr RTAppChooserDialog::get_app_info() const +{ + return Gtk::AppChooserDialog::get_app_info(); +} + +#else // Work around bugs with GLib and glibmm. + +RTAppChooserDialog::RTAppChooserDialog(const Glib::ustring &content_type) : + Gtk::AppChooserDialog(content_type) +{ + // GTK calls a faulty GLib function to update the most recently selected + // application after an application is selected. This removes all signal + // handlers to prevent the function call. + auto signal_id = g_signal_lookup("response", GTK_TYPE_APP_CHOOSER_DIALOG); + while (true) { + auto handler_id = g_signal_handler_find(gobj(), G_SIGNAL_MATCH_ID, signal_id, GQuark(), nullptr, nullptr, nullptr); + if (!handler_id) { + break; + } + g_signal_handler_disconnect(gobj(), handler_id); + } +} + +Glib::RefPtr RTAppChooserDialog::get_app_info() +{ + // glibmm wrapping of GAppInfo does not work on some platforms. Manually + // wrap it here. + GAppInfo *gAppInfo = gtk_app_chooser_get_app_info(GTK_APP_CHOOSER(gobj())); + return Glib::wrap(gAppInfo, true); +} + +Glib::RefPtr RTAppChooserDialog::get_app_info() const +{ + GAppInfo *gAppInfo = gtk_app_chooser_get_app_info(GTK_APP_CHOOSER( + const_cast(gobj()))); + return Glib::wrap(gAppInfo, true); +} + +#endif diff --git a/rtgui/rtappchooserdialog.h b/rtgui/rtappchooserdialog.h new file mode 100644 index 000000000..9d0e3b041 --- /dev/null +++ b/rtgui/rtappchooserdialog.h @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include +#include +#include +#include + +/** + * Custom version of gtkmm's Gtk::AppChooserDialog to work around crashes + * (https://gitlab.gnome.org/GNOME/glib/-/issues/1104 and + * https://gitlab.gnome.org/GNOME/glibmm/-/issues/94). + */ +class RTAppChooserDialog : public Gtk::AppChooserDialog +{ +public: + RTAppChooserDialog(const Glib::ustring &content_type); + ~RTAppChooserDialog(); + + Glib::RefPtr get_app_info(); + Glib::RefPtr get_app_info() const; +}; From 672d6302f37aefae0e8341761a54d31042035210 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 14 Aug 2021 17:11:07 -0700 Subject: [PATCH 031/326] Fix storage of external editor icons De-serialize and serialize icons instead of using their names. --- rtgui/editorpanel.cc | 18 +++++++++++++-- rtgui/externaleditorpreferences.cc | 32 ++++++++++++++++++++++----- rtgui/externaleditorpreferences.h | 6 ++--- rtgui/options.cc | 35 ++++++++++++++++-------------- rtgui/options.h | 4 ++-- rtgui/preferences.cc | 4 ++-- rtgui/rtimage.cc | 7 +++++- 7 files changed, 75 insertions(+), 31 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 6cb90a444..987852891 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2522,8 +2522,22 @@ void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vecto // Add the editors. for (unsigned i = 0; i < editors.size(); i++) { const auto & name = editors[i].name.empty() ? Glib::ustring(" ") : editors[i].name; - if (!editors[i].icon_name.empty()) { - Glib::RefPtr gioIcon = Gio::Icon::create(editors[i].icon_name); + if (!editors[i].icon_serialized.empty()) { + Glib::RefPtr gioIcon; + GError *e = nullptr; + GVariant *icon_variant = g_variant_parse( + nullptr, editors[i].icon_serialized.c_str(), nullptr, nullptr, &e); + + if (e) { + std::cerr + << "Error loading external editor icon from \"" + << editors[i].icon_serialized << "\": " << e->message + << std::endl; + gioIcon = Glib::RefPtr(); + } else { + gioIcon = Gio::Icon::deserialize(Glib::VariantBase(icon_variant)); + } + send_to_external->insertEntry(i, gioIcon, name); } else { send_to_external->insertEntry(i, "palette-brush.png", name); diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index b64cdcf9f..61bf8dc3a 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + #include "externaleditorpreferences.h" #include "multilangmgr.h" #include "rtimage.h" @@ -85,11 +87,11 @@ ExternalEditorPreferences::getEditors() const for (auto rowIter = children.begin(); rowIter != children.end(); rowIter++) { const Gio::Icon *const icon = rowIter->get_value(model_columns.icon).get(); - const auto &icon_name = icon == nullptr ? "" : icon->to_string(); + const auto &icon_serialized = icon == nullptr ? "" : icon->serialize().print(); editors.push_back(ExternalEditorPreferences::EditorInfo( rowIter->get_value(model_columns.name), rowIter->get_value(model_columns.command), - icon_name, + icon_serialized, rowIter->get_value(model_columns.other_data) )); } @@ -104,8 +106,28 @@ void ExternalEditorPreferences::setEditors( for (const ExternalEditorPreferences::EditorInfo & editor : editors) { auto row = *list_model->append(); + Glib::RefPtr icon; + + // Get icon. + if (editor.icon_serialized.empty()) { + icon = Glib::RefPtr(); + } else { + GError *e = nullptr; + GVariant *icon_variant = g_variant_parse( + nullptr, editor.icon_serialized.c_str(), nullptr, nullptr, &e); + if (e) { + std::cerr + << "Error loading external editor icon from \"" + << editor.icon_serialized << "\": " << e->message + << std::endl; + icon = Glib::RefPtr(); + } else { + icon = Gio::Icon::deserialize(Glib::VariantBase(icon_variant)); + } + } + row[model_columns.name] = editor.name; - row[model_columns.icon] = editor.icon_name.empty() ? Glib::RefPtr() : Gio::Icon::create(editor.icon_name); + row[model_columns.icon] = icon; row[model_columns.command] = editor.command; row[model_columns.other_data] = editor.other_data; } @@ -247,8 +269,8 @@ void ExternalEditorPreferences::updateToolbarSensitivity() } ExternalEditorPreferences::EditorInfo::EditorInfo( - Glib::ustring name, Glib::ustring command, Glib::ustring icon_name, void *other_data -) : name(name), icon_name(icon_name), command(command), other_data(other_data) + Glib::ustring name, Glib::ustring command, Glib::ustring icon_serialized, void *other_data +) : name(name), icon_serialized(icon_serialized), command(command), other_data(other_data) { } diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index dbd0f1648..5761d8b63 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -41,7 +41,7 @@ public: explicit EditorInfo( Glib::ustring name = Glib::ustring(), Glib::ustring command = Glib::ustring(), - Glib::ustring icon_name = Glib::ustring(), + Glib::ustring icon_serialized = Glib::ustring(), void *other_data = nullptr ); /** @@ -49,9 +49,9 @@ public: */ Glib::ustring name; /** - * The string representation of the icon. See Gio::Icon::to_string(). + * The string representation of the icon. See Gio::Icon::serialize(). */ - Glib::ustring icon_name; + Glib::ustring icon_serialized; /** * The commandline for running the program. See * Gio::AppInfo::get_commandline() diff --git a/rtgui/options.cc b/rtgui/options.cc index 6a944faa6..53cedea95 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -859,7 +859,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_group("External Editor")) { if (keyFile.has_key("External Editor", "Names") || keyFile.has_key("External Editor", "Commands") - || keyFile.has_key("External Editor", "IconNames")) { + || keyFile.has_key("External Editor", "IconsSerialized")) { // Multiple external editors. const auto & names = @@ -872,21 +872,21 @@ void Options::readFromFile(Glib::ustring fname) std::vector() : static_cast>( keyFile.get_string_list("External Editor", "Commands")); - const auto & icon_names = - !keyFile.has_key("External Editor", "IconNames") ? + const auto & icons_serialized = + !keyFile.has_key("External Editor", "IconsSerialized") ? std::vector() : static_cast>( - keyFile.get_string_list("External Editor", "IconNames")); + keyFile.get_string_list("External Editor", "IconsSerialized")); externalEditors = std::vector(std::max(std::max( - names.size(), commands.size()), icon_names.size())); + names.size(), commands.size()), icons_serialized.size())); for (unsigned i = 0; i < names.size(); i++) { externalEditors[i].name = names[i]; } for (unsigned i = 0; i < commands.size(); i++) { externalEditors[i].command = commands[i]; } - for (unsigned i = 0; i < icon_names.size(); i++) { - externalEditors[i].icon_name = icon_names[i]; + for (unsigned i = 0; i < icons_serialized.size(); i++) { + externalEditors[i].icon_serialized = icons_serialized[i]; } if (keyFile.has_key("External Editor", "EditorIndex")) { @@ -903,6 +903,9 @@ void Options::readFromFile(Glib::ustring fname) editorToSendTo = keyFile.get_integer("External Editor", "EditorKind"); #ifdef WIN32 + auto getIconSerialized = [](const Glib::ustring &executable) { + return Glib::ustring::compose("('themed', <['%1,0', '%1,0-symbolic']>)", executable); + }; Glib::ustring gimpDir = ""; if (keyFile.has_key("External Editor", "GimpDir")) { gimpDir = keyFile.get_string("External Editor", "GimpDir"); @@ -912,7 +915,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); } else { for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); @@ -920,7 +923,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); break; } } @@ -935,7 +938,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", getIconSerialized(executable))); } if (keyFile.has_key("External Editor", "CustomEditor")) { @@ -2296,17 +2299,17 @@ void Options::saveToFile(Glib::ustring fname) { std::vector names; std::vector commands; - std::vector icon_names; + std::vector icons_serialized; for (const auto & editor : externalEditors) { names.push_back(editor.name); commands.push_back(editor.command); - icon_names.push_back(editor.icon_name); + icons_serialized.push_back(editor.icon_serialized); } keyFile.set_string_list("External Editor", "Names", names); keyFile.set_string_list("External Editor", "Commands", commands); - keyFile.set_string_list("External Editor", "IconNames", icon_names); + keyFile.set_string_list("External Editor", "IconsSerialized", icons_serialized); keyFile.set_integer("External Editor", "EditorIndex", externalEditorIndex); } @@ -2978,12 +2981,12 @@ Glib::ustring Options::getICCProfileCopyright() ExternalEditor::ExternalEditor() {} ExternalEditor::ExternalEditor( - const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name -): name(name), command(command), icon_name(icon_name) {} + const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized +): name(name), command(command), icon_serialized(icon_serialized) {} bool ExternalEditor::operator==(const ExternalEditor &other) const { - return this->name == other.name && this->command == other.command && this->icon_name == other.icon_name; + return this->name == other.name && this->command == other.command && this->icon_serialized == other.icon_serialized; } bool ExternalEditor::operator!=(const ExternalEditor &other) const diff --git a/rtgui/options.h b/rtgui/options.h index 38d3f3d76..d6b546d40 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -54,10 +54,10 @@ struct ExternalEditor { ExternalEditor(); - ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name); + ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized); Glib::ustring name; Glib::ustring command; - Glib::ustring icon_name; + Glib::ustring icon_serialized; bool operator==(const ExternalEditor & other) const; bool operator!=(const ExternalEditor & other) const; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 786262896..a8f5c64a3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1793,7 +1793,7 @@ void Preferences::storePreferences() moptions.externalEditorIndex = -1; for (unsigned i = 0; i < editors.size(); i++) { moptions.externalEditors[i] = (ExternalEditor( - editors[i].name, editors[i].command, editors[i].icon_name)); + editors[i].name, editors[i].command, editors[i].icon_serialized)); if (editors[i].other_data) { // The current editor was marked before the list was edited. We // found the mark, so this is the editor that was active. @@ -2100,7 +2100,7 @@ void Preferences::fillPreferences() std::vector editorInfos; for (const auto &editor : moptions.externalEditors) { editorInfos.push_back(ExternalEditorPreferences::EditorInfo( - editor.name, editor.command, editor.icon_name)); + editor.name, editor.command, editor.icon_serialized)); } if (moptions.externalEditorIndex >= 0) { // Mark the current editor so we can track it. diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 9a38c1885..98e61b897 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -294,7 +294,12 @@ Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fi Glib::RefPtr RTImage::createPixbufFromGIcon(const Glib::RefPtr &icon, int size) { // TODO: Listen for theme changes and update icon, remove from cache. - return Gtk::IconTheme::get_default()->lookup_icon(icon, size, Gtk::ICON_LOOKUP_FORCE_SIZE).load_icon(); + Gtk::IconInfo iconInfo = Gtk::IconTheme::get_default()->lookup_icon(icon, size, Gtk::ICON_LOOKUP_FORCE_SIZE); + try { + return iconInfo.load_icon(); + } catch (Glib::Exception &e) { + return Glib::RefPtr(); + } } Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::ustring& fileName) From 732316dcafc1fdb16ea27c0c5af1707dffcd80b4 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 5 Oct 2021 21:49:42 -0700 Subject: [PATCH 032/326] Fix initial generation of external editor icons In Windows, escape backslashes and quotes in the serialized GVariants of the icons. --- rtgui/options.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 53cedea95..a6b693f53 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -904,7 +904,16 @@ void Options::readFromFile(Glib::ustring fname) #ifdef WIN32 auto getIconSerialized = [](const Glib::ustring &executable) { - return Glib::ustring::compose("('themed', <['%1,0', '%1,0-symbolic']>)", executable); + // Backslashes and quotes must be escaped in the text representation of GVariant strings. + // See https://www.freedesktop.org/software/gstreamer-sdk/data/docs/2012.5/glib/gvariant-text.html#gvariant-text-strings + Glib::ustring exec_escaped = ""; + for (const auto character : executable) { + if (character == '\\' || character == '\'') { + exec_escaped += '\\'; + } + exec_escaped += character; + } + return Glib::ustring::compose("('themed', <['%1,0', '%1,0-symbolic']>)", exec_escaped); }; Glib::ustring gimpDir = ""; if (keyFile.has_key("External Editor", "GimpDir")) { From 0f894656a0a9c751efc5a6f45bcb1d7932e1c16f Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 21 Nov 2021 17:47:41 -0800 Subject: [PATCH 033/326] Add favorites customizer to preferences UI --- rtdata/languages/default | 5 + rtgui/CMakeLists.txt | 1 + rtgui/preferences.cc | 12 + rtgui/preferences.h | 4 + rtgui/toollocationpref.cc | 596 ++++++++++++++++++++++++++++++++++++++ rtgui/toollocationpref.h | 34 +++ rtgui/toolpanelcoord.cc | 250 ++++++++++++++++ rtgui/toolpanelcoord.h | 78 +++++ 8 files changed, 980 insertions(+) create mode 100644 rtgui/toollocationpref.cc create mode 100644 rtgui/toollocationpref.h diff --git a/rtdata/languages/default b/rtdata/languages/default index 747dfa863..525fa2d09 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1891,6 +1891,7 @@ PREFERENCES_STARTUPIMDIR;Image Directory at Startup PREFERENCES_TAB_BROWSER;File Browser PREFERENCES_TAB_COLORMGR;Color Management PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules +PREFERENCES_TAB_FAVORITES;Favorites PREFERENCES_TAB_GENERAL;General PREFERENCES_TAB_IMPROC;Image Processing PREFERENCES_TAB_PERFORMANCE;Performance @@ -1899,6 +1900,10 @@ 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_FAVORITE;Favorite +PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel +PREFERENCES_TOOLPANEL_TOOL;Tool PREFERENCES_TP_LABEL;Tool panel: PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 7976bdc7a..cfb06ff0f 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -160,6 +160,7 @@ set(NONCLISOURCEFILES thumbnail.cc tonecurve.cc toolbar.cc + toollocationpref.cc toolpanel.cc toolpanelcoord.cc vibrance.cc diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c6c2eb61b..556201732 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -29,6 +29,7 @@ #include #include "rtimage.h" #include "rtwindow.h" +#include "toollocationpref.h" #ifdef _OPENMP #include #endif @@ -65,6 +66,7 @@ Preferences::Preferences(RTWindow *rtwindow) , parent(rtwindow) , newFont(false) , newCPFont(false) + , toolLocationPreference(nullptr) { moptions.copyFrom(&options); @@ -102,6 +104,7 @@ Preferences::Preferences(RTWindow *rtwindow) nb->append_page(*getGeneralPanel(), M("PREFERENCES_TAB_GENERAL")); nb->append_page(*getImageProcessingPanel(), M("PREFERENCES_TAB_IMPROC")); + nb->append_page(*getFavoritesPanel(), M("PREFERENCES_TAB_FAVORITES")); nb->append_page(*getDynamicProfilePanel(), M("PREFERENCES_TAB_DYNAMICPROFILE")); nb->append_page(*getFileBrowserPanel(), M("PREFERENCES_TAB_BROWSER")); nb->append_page(*getColorManPanel(), M("PREFERENCES_TAB_COLORMGR")); @@ -492,6 +495,13 @@ void Preferences::behSetRadioToggled(const Glib::ustring& path) behAddSetRadioToggled(path, false); } +Gtk::Widget *Preferences::getFavoritesPanel() +{ + if (!toolLocationPreference) { + toolLocationPreference = Gtk::make_managed(moptions); + } + return toolLocationPreference; +} Gtk::Widget *Preferences::getDynamicProfilePanel() { @@ -1938,6 +1948,8 @@ void Preferences::storePreferences() moptions.cropGuides = Options::CropGuidesMode(cropGuidesCombo->get_active_row_number()); moptions.cropAutoFit = cropAutoFitCB->get_active(); + + toolLocationPreference->updateOptions(); } void Preferences::fillPreferences() diff --git a/rtgui/preferences.h b/rtgui/preferences.h index dfe1e008d..18d7a0581 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -28,6 +28,7 @@ class RTWindow; class Splash; +class ToolLocationPreference; class Preferences final : public Gtk::Dialog, @@ -244,6 +245,8 @@ class Preferences final : bool newFont; bool newCPFont; + ToolLocationPreference *toolLocationPreference; + void fillPreferences (); void storePreferences (); void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); @@ -278,6 +281,7 @@ class Preferences final : Gtk::Widget *getGeneralPanel(); Gtk::Widget *getImageProcessingPanel(); + Gtk::Widget *getFavoritesPanel(); Gtk::Widget *getDynamicProfilePanel(); Gtk::Widget *getFileBrowserPanel(); Gtk::Widget *getColorManPanel(); diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc new file mode 100644 index 000000000..719a72a66 --- /dev/null +++ b/rtgui/toollocationpref.cc @@ -0,0 +1,596 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "guiutils.h" +#include "options.h" +#include "toollocationpref.h" +#include "toolpanelcoord.h" + +using Tool = ToolPanelCoordinator::Tool; + +std::string getToolName(Tool tool) +{ + switch (tool) { + case Tool::TONE_CURVE: + return "tonecurve"; + case Tool::SHADOWS_HIGHLIGHTS: + return "shadowshighlights"; + case Tool::IMPULSE_DENOISE: + return "impulsedenoise"; + case Tool::DEFRINGE_TOOL: + return "defringe"; + case Tool::SPOT: + return "spot"; + case Tool::DIR_PYR_DENOISE: + return "dirpyrdenoise"; + case Tool::EPD: + return "epd"; + case Tool::SHARPENING_TOOL: + return "sharpening"; + case Tool::LOCAL_CONTRAST: + return "localcontrast"; + case Tool::SHARPEN_EDGE: + return "sharpenedge"; + case Tool::SHARPEN_MICRO: + return "sharpenmicro"; + case Tool::L_CURVE: + return "labcurves"; + case Tool::RGB_CURVES: + return "rgbcurves"; + case Tool::COLOR_TONING: + return "colortoning"; + case Tool::LENS_GEOM: + return "lensgeom"; + case Tool::LENS_PROF: + return "lensprof"; + case Tool::DISTORTION: + return "distortion"; + case Tool::ROTATE: + return "rotate"; + case Tool::VIBRANCE: + return "vibrance"; + case Tool::COLOR_APPEARANCE: + return "colorappearance"; + case Tool::WHITE_BALANCE: + return "whitebalance"; + case Tool::VIGNETTING: + return "vignetting"; + case Tool::RETINEX_TOOL: + return "retinex"; + case Tool::GRADIENT: + return "gradient"; + case Tool::LOCALLAB: + return "locallab"; + case Tool::PC_VIGNETTE: + return "pcvignette"; + case Tool::PERSPECTIVE: + return "perspective"; + case Tool::CA_CORRECTION: + return "cacorrection"; + case Tool::CH_MIXER: + return "chmixer"; + case Tool::BLACK_WHITE: + return "blackwhite"; + case Tool::RESIZE_TOOL: + return "resize"; + case Tool::PR_SHARPENING: + return "prsharpening"; + case Tool::CROP_TOOL: + return "crop"; + case Tool::ICM: + return "icm"; + case Tool::WAVELET: + return "wavelet"; + case Tool::DIR_PYR_EQUALIZER: + return "dirpyrdenoise"; + case Tool::HSV_EQUALIZER: + return "hsvequalizer"; + case Tool::FILM_SIMULATION: + return "filmsimulation"; + case Tool::SOFT_LIGHT: + return "softlight"; + case Tool::DEHAZE: + return "dehaze"; + case Tool::SENSOR_BAYER: + return "sensorbayer"; + case Tool::SENSOR_XTRANS: + return "sensorxtrans"; + case Tool::BAYER_PROCESS: + return "bayerprocess"; + case Tool::XTRANS_PROCESS: + return "xtransprocess"; + case Tool::BAYER_PREPROCESS: + return "bayerpreprocess"; + case Tool::PREPROCESS: + return "preprocess"; + case Tool::DARKFRAME_TOOL: + return "darkframe"; + case Tool::FLATFIELD_TOOL: + return "flatfield"; + case Tool::RAW_CA_CORRECTION: + return "rawcacorrection"; + case Tool::RAW_EXPOSURE: + return "rawexposure"; + case Tool::PREPROCESS_WB: + return "preprocesswb"; + case Tool::BAYER_RAW_EXPOSURE: + return "bayerrawexposure"; + case Tool::XTRANS_RAW_EXPOSURE: + return "xtransrawexposure"; + case Tool::FATTAL: + return "fattal"; + case Tool::FILM_NEGATIVE: + return "filmnegative"; + case Tool::PD_SHARPENING: + return "capturesharpening"; + }; + return ""; +}; + +class FavoritesColumns : public Gtk::TreeModelColumnRecord +{ +public: + Gtk::TreeModelColumn toolName; + Gtk::TreeModelColumn tool; + + FavoritesColumns() + { + add(toolName); + add(tool); + } +}; + +class ToolListColumns : public Gtk::TreeModelColumnRecord +{ +public: + Gtk::TreeModelColumn toolName; + Gtk::TreeModelColumn tool; + Gtk::TreeModelColumn isFavorite; + Gtk::TreeModelColumn isEditable; + + ToolListColumns() + { + add(toolName); + add(tool); + add(isFavorite); + add(isEditable); + } +}; + +struct ToolLocationPreference::Impl { + static std::unordered_map toolNamesReverseMap; + + Options &options; + + // Tool list. + ToolListColumns toolListColumns; + Glib::RefPtr toolListModelPtr; + Gtk::CellRendererToggle toolListCellRendererFavorite; + Gtk::CellRendererText toolListCellRendererToolName; + Gtk::TreeViewColumn toolListViewColumnFavorite; + Gtk::TreeViewColumn toolListViewColumnToolName; + Gtk::TreeView *toolListViewPtr; + + // Favorites list. + FavoritesColumns favoritesColumns; + Glib::RefPtr favoritesModelPtr; + Gtk::CellRendererText favoritesCellRendererToolName; + Gtk::TreeViewColumn favoritesViewColumnToolName; + Gtk::TreeView *favoritesViewPtr; + + explicit Impl(Options &options); + + void addToolListRowGroup( + const std::vector &tools, + const Gtk::TreeIter &parentRowIter, + const std::unordered_set &favorites); + void favoriteToggled(const Glib::ustring &row_path); + Tool getToolFromName(const std::string &name) const; + void initFavoritesRows(const std::vector &favorites); + void initToolListRows(const std::vector &favorites); + std::vector toolNamesToTools( + const std::vector &tool_names) const; + void updateOptions(); +}; + +std::unordered_map + ToolLocationPreference::Impl::toolNamesReverseMap; + +Glib::ustring getToolPanelTitleKey(ToolPanelCoordinator::Panel panel) +{ + switch (panel) { + case ToolPanelCoordinator::Panel::FAVORITE: + return "MAIN_TAB_FAVORITES"; + case ToolPanelCoordinator::Panel::EXPOSURE: + return "MAIN_TAB_EXPOSURE"; + case ToolPanelCoordinator::Panel::DETAILS: + return "MAIN_TAB_DETAIL"; + case ToolPanelCoordinator::Panel::COLOR: + return "MAIN_TAB_COLOR"; + case ToolPanelCoordinator::Panel::ADVANCED: + return "MAIN_TAB_ADVANCED"; + case ToolPanelCoordinator::Panel::LOCALLAB: + return "MAIN_TAB_LOCALLAB"; + case ToolPanelCoordinator::Panel::TRANSFORM_PANEL: + return "MAIN_TAB_TRANSFORM"; + case ToolPanelCoordinator::Panel::RAW: + return "MAIN_TAB_RAW"; + } + return ""; +} + +Glib::ustring getToolTitleKey(Tool tool) +{ + using Tool = Tool; + switch (tool) { + case Tool::TONE_CURVE: + return "TP_EXPOSURE_LABEL"; + case Tool::SHADOWS_HIGHLIGHTS: + return "TP_SHADOWSHLIGHTS_LABEL"; + case Tool::IMPULSE_DENOISE: + return "TP_IMPULSEDENOISE_LABEL"; + case Tool::DEFRINGE_TOOL: + return "TP_DEFRINGE_LABEL"; + case Tool::SPOT: + return "TP_SPOT_LABEL"; + case Tool::DIR_PYR_DENOISE: + return "TP_DIRPYRDENOISE_LABEL"; + case Tool::EPD: + return "TP_EPD_LABEL"; + case Tool::SHARPENING_TOOL: + return "TP_SHARPENING_LABEL"; + case Tool::LOCAL_CONTRAST: + return "TP_LOCALCONTRAST_LABEL"; + case Tool::SHARPEN_EDGE: + return "TP_SHARPENEDGE_LABEL"; + case Tool::SHARPEN_MICRO: + return "TP_SHARPENMICRO_LABEL"; + case Tool::L_CURVE: + return "TP_LABCURVE_LABEL"; + case Tool::RGB_CURVES: + return "TP_RGBCURVES_LABEL"; + case Tool::COLOR_TONING: + return "TP_COLORTONING_LABEL"; + case Tool::LENS_GEOM: + return "TP_LENSGEOM_LABEL"; + case Tool::LENS_PROF: + return "TP_LENSPROFILE_LABEL"; + case Tool::DISTORTION: + return "TP_DISTORTION_LABEL"; + case Tool::ROTATE: + return "TP_ROTATE_LABEL"; + case Tool::VIBRANCE: + return "TP_VIBRANCE_LABEL"; + case Tool::COLOR_APPEARANCE: + return "TP_COLORAPP_LABEL"; + case Tool::WHITE_BALANCE: + return "TP_WBALANCE_LABEL"; + case Tool::VIGNETTING: + return "TP_VIGNETTING_LABEL"; + case Tool::RETINEX_TOOL: + return "TP_RETINEX_LABEL"; + case Tool::GRADIENT: + return "TP_GRADIENT_LABEL"; + case Tool::LOCALLAB: + return "TP_LOCALLAB_LABEL"; + case Tool::PC_VIGNETTE: + return "TP_PCVIGNETTE_LABEL"; + case Tool::PERSPECTIVE: + return "TP_PERSPECTIVE_LABEL"; + case Tool::CA_CORRECTION: + return "TP_CACORRECTION_LABEL"; + case Tool::CH_MIXER: + return "TP_CHMIXER_LABEL"; + case Tool::BLACK_WHITE: + return "TP_BWMIX_LABEL"; + case Tool::RESIZE_TOOL: + return "TP_RESIZE_LABEL"; + case Tool::PR_SHARPENING: + return "TP_PRSHARPENING_LABEL"; + case Tool::CROP_TOOL: + return "TP_CROP_LABEL"; + case Tool::ICM: + return "TP_ICM_LABEL"; + case Tool::WAVELET: + return "TP_WAVELET_LABEL"; + case Tool::DIR_PYR_EQUALIZER: + return "TP_DIRPYRDENOISE_LABEL"; + case Tool::HSV_EQUALIZER: + return "TP_HSVEQUALIZER_LABEL"; + case Tool::FILM_SIMULATION: + return "TP_FILMSIMULATION_LABEL"; + case Tool::SOFT_LIGHT: + return "TP_SOFTLIGHT_LABEL"; + case Tool::DEHAZE: + return "TP_DEHAZE_LABEL"; + case Tool::SENSOR_BAYER: + return "TP_RAW_SENSOR_BAYER_LABEL"; + case Tool::SENSOR_XTRANS: + return "TP_RAW_SENSOR_XTRANS_LABEL"; + case Tool::BAYER_PROCESS: + return "TP_RAW_LABEL"; + case Tool::XTRANS_PROCESS: + return "TP_RAW_LABEL"; + case Tool::BAYER_PREPROCESS: + return "TP_PREPROCESS_LABEL"; + case Tool::PREPROCESS: + return "TP_PREPROCESS_LABEL"; + case Tool::DARKFRAME_TOOL: + return "TP_DARKFRAME_LABEL"; + case Tool::FLATFIELD_TOOL: + return "TP_FLATFIELD_LABEL"; + case Tool::RAW_CA_CORRECTION: + return "TP_RAWCACORR_LABEL"; + case Tool::RAW_EXPOSURE: + return "TP_EXPOS_WHITEPOINT_LABEL"; + case Tool::PREPROCESS_WB: + return "TP_PREPROCWB_LABEL"; + case Tool::BAYER_RAW_EXPOSURE: + return "TP_EXPOS_BLACKPOINT_LABEL"; + case Tool::XTRANS_RAW_EXPOSURE: + return "TP_EXPOS_BLACKPOINT_LABEL"; + case Tool::FATTAL: + return "TP_TM_FATTAL_LABEL"; + case Tool::FILM_NEGATIVE: + return "TP_FILMNEGATIVE_LABEL"; + case Tool::PD_SHARPENING: + return "TP_PDSHARPENING_LABEL"; + }; + return ""; +} + +ToolLocationPreference::Impl::Impl(Options &options) : + options(options), + + toolListModelPtr(Gtk::TreeStore::create(toolListColumns)), + toolListViewColumnFavorite( + Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_FAVORITE"))), + toolListViewColumnToolName( + Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), + toolListViewPtr(Gtk::make_managed()), + + favoritesModelPtr(Gtk::ListStore::create(favoritesColumns)), + favoritesViewColumnToolName( + Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), + favoritesViewPtr(Gtk::make_managed()) +{ + const std::vector favorites = toolNamesToTools(options.favorites); + + // Tool list. + toolListViewPtr->set_model(toolListModelPtr); + 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.set_renderer( + toolListCellRendererFavorite, toolListColumns.isFavorite); + toolListViewColumnFavorite.add_attribute( + toolListCellRendererFavorite, "visible", toolListColumns.isEditable); + toolListCellRendererFavorite.signal_toggled().connect( + sigc::mem_fun(*this, &ToolLocationPreference::Impl::favoriteToggled)); + initToolListRows(favorites); + toolListViewPtr->expand_all(); + + // Favorites list. + favoritesViewPtr->set_model(favoritesModelPtr); + favoritesViewPtr->append_column(favoritesViewColumnToolName); + favoritesViewPtr->set_reorderable(true); + favoritesViewColumnToolName.pack_start(favoritesCellRendererToolName); + favoritesViewColumnToolName.set_renderer( + favoritesCellRendererToolName, favoritesColumns.toolName); + initFavoritesRows(favorites); +} + +void ToolLocationPreference::Impl::favoriteToggled(const Glib::ustring &row_path) +{ + auto row_iter = toolListModelPtr->get_iter(row_path); + const bool is_favorite = !row_iter->get_value(toolListColumns.isFavorite); + const Tool tool = row_iter->get_value(toolListColumns.tool); + + // Update favorite column in the tool list. + row_iter->set_value(toolListColumns.isFavorite, is_favorite); + + // Update the favorites list. + if (is_favorite) { + // Add to favorites list. + auto new_favorite_row_iter = favoritesModelPtr->append(); + new_favorite_row_iter->set_value( + favoritesColumns.toolName, + M(getToolTitleKey(tool))); + new_favorite_row_iter->set_value(favoritesColumns.tool, tool); + } else { + // Remove from favorites list. + const auto favorites_rows = favoritesModelPtr->children(); + auto row = favorites_rows.begin(); + while ( + row != favorites_rows.end() && + row->get_value(favoritesColumns.tool) != tool) { + row++; + } + if (row != favorites_rows.end()) { + favoritesModelPtr->erase(row); + } + } +} + +Tool ToolLocationPreference::Impl::getToolFromName(const std::string &name) const +{ + if (toolNamesReverseMap.empty()) { + // Create the name to tool mapping. + + const auto panels = ToolPanelCoordinator::getDefaultToolLayout(); + std::vector unprocessed_tool_trees; + + // Get the root tools from each panel. + for (const auto &panel_tools : panels) { + for (const auto &tool : panel_tools.second) { + unprocessed_tool_trees.push_back(&tool); + } + } + + // Process all the tools, including their children. + while (unprocessed_tool_trees.size() > 0) { + const ToolPanelCoordinator::ToolTree *tool_tree = + unprocessed_tool_trees.back(); + unprocessed_tool_trees.pop_back(); + toolNamesReverseMap[getToolName(tool_tree->id)] = tool_tree->id; + for (const auto &child_tree : tool_tree->children) { + unprocessed_tool_trees.push_back(&child_tree); + } + } + } + + return toolNamesReverseMap.at(name); +} + +void ToolLocationPreference::Impl::initFavoritesRows( + const std::vector &favorites) +{ + for (const auto tool : favorites) { + auto favorite_row_iter = favoritesModelPtr->append(); + favorite_row_iter->set_value( + favoritesColumns.toolName, + M(getToolTitleKey(tool))); + favorite_row_iter->set_value(favoritesColumns.tool, tool); + } +} + +void ToolLocationPreference::Impl::addToolListRowGroup( + const std::vector &tools, + const Gtk::TreeIter &parentRowIter, + const std::unordered_set &favorites) +{ + for (const ToolPanelCoordinator::ToolTree &tool : tools) { + auto tool_row_iter = toolListModelPtr->append(parentRowIter->children()); + tool_row_iter->set_value( + toolListColumns.toolName, + M(getToolTitleKey(tool.id))); + tool_row_iter->set_value(toolListColumns.tool, tool.id); + tool_row_iter->set_value( + toolListColumns.isFavorite, + favorites.count(tool.id) > 0); + tool_row_iter->set_value( + toolListColumns.isEditable, + ToolPanelCoordinator::isFavoritable(tool.id)); + addToolListRowGroup(tool.children, tool_row_iter, favorites); + } +}; + +void ToolLocationPreference::Impl::initToolListRows(const std::vector &favorites) +{ + const auto panel_tools = ToolPanelCoordinator::getDefaultToolLayout(); + std::unordered_set favorites_set; + + for (const auto &tool : favorites) { + favorites_set.insert(tool); + } + + for (const auto panel : { + ToolPanelCoordinator::Panel::EXPOSURE, + ToolPanelCoordinator::Panel::DETAILS, + ToolPanelCoordinator::Panel::COLOR, + ToolPanelCoordinator::Panel::ADVANCED, + ToolPanelCoordinator::Panel::LOCALLAB, + ToolPanelCoordinator::Panel::TRANSFORM_PANEL, + ToolPanelCoordinator::Panel::RAW, + }) { + auto tool_group_iter = toolListModelPtr->append(); + tool_group_iter->set_value( + toolListColumns.toolName, + M(getToolPanelTitleKey(panel))); + addToolListRowGroup(panel_tools.at(panel), tool_group_iter, favorites_set); + } +} + +std::vector ToolLocationPreference::Impl::toolNamesToTools( + const std::vector &tool_names) const +{ + std::vector tool_set; + + for (auto &&tool_name : tool_names) { + Tool tool; + try { + tool = getToolFromName(tool_name); + } catch (const std::exception &e) { + continue; + } + tool_set.push_back(tool); + } + + return tool_set; +} + +void ToolLocationPreference::Impl::updateOptions() +{ + const auto favorites_rows = favoritesModelPtr->children(); + options.favorites.resize(favorites_rows.size()); + for (unsigned i = 0; i < favorites_rows.size(); i++) { + const Tool tool = favorites_rows[i].get_value(favoritesColumns.tool); + options.favorites[i] = getToolName(tool); + } +} + +ToolLocationPreference::ToolLocationPreference(Options &options) : + impl(new Impl(options)) +{ + // Layout grid. + Gtk::Grid *layout_grid = Gtk::make_managed(); + layout_grid->set_column_spacing(4); + layout_grid->set_row_spacing(4); + add(*layout_grid); + + // Tool list. + Gtk::Frame *tool_list_frame = Gtk::make_managed( + M("PREFERENCES_TOOLPANEL_AVAILABLETOOLS")); + Gtk::ScrolledWindow *tool_list_scrolled_window = + Gtk::make_managed(); + tool_list_scrolled_window->property_hscrollbar_policy() = + Gtk::PolicyType::POLICY_NEVER; + layout_grid->attach_next_to(*tool_list_frame, Gtk::PositionType::POS_RIGHT); + tool_list_frame->add(*tool_list_scrolled_window); + tool_list_scrolled_window->add(*impl->toolListViewPtr); + impl->toolListViewPtr->set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_MINIMUM); + setExpandAlignProperties( + tool_list_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); + + // Favorites list. + Gtk::Frame *favorites_frame = Gtk::make_managed( + M("PREFERENCES_TOOLPANEL_FAVORITESPANEL")); + Gtk::ScrolledWindow *favorites_list_scrolled_window = + Gtk::make_managed(); + favorites_list_scrolled_window->property_hscrollbar_policy() = + Gtk::PolicyType::POLICY_NEVER; + layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT); + favorites_frame->add(*favorites_list_scrolled_window); + favorites_list_scrolled_window->add(*impl->favoritesViewPtr); + setExpandAlignProperties( + favorites_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); + + this->show_all(); +} + +void ToolLocationPreference::updateOptions() +{ + impl->updateOptions(); +} diff --git a/rtgui/toollocationpref.h b/rtgui/toollocationpref.h new file mode 100644 index 000000000..815df6839 --- /dev/null +++ b/rtgui/toollocationpref.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +class Options; + +class ToolLocationPreference : public Gtk::Box +{ +private: + struct Impl; + std::unique_ptr impl; + +public: + explicit ToolLocationPreference(Options &options); + void updateOptions(); +}; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 00fcb208d..586d4755f 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -32,6 +32,241 @@ using namespace rtengine::procparams; +using Tool = ToolPanelCoordinator::Tool; +using ToolTree = struct ToolPanelCoordinator::ToolTree; + +const std::vector EXPOSURE_PANEL_TOOLS = { + { + .id = Tool::TONE_CURVE, + }, + { + .id = Tool::SHADOWS_HIGHLIGHTS, + }, + { + .id = Tool::EPD, + }, + { + .id = Tool::FATTAL, + }, + { + .id = Tool::PC_VIGNETTE, + }, + { + .id = Tool::GRADIENT, + }, + { + .id = Tool::L_CURVE, + }, +}; + +const std::vector DETAILS_PANEL_TOOLS = { + { + .id = Tool::SPOT, + }, + { + .id = Tool::SHARPENING_TOOL, + }, + { + .id = Tool::LOCAL_CONTRAST, + }, + { + .id = Tool::SHARPEN_EDGE, + }, + { + .id = Tool::SHARPEN_MICRO, + }, + { + .id = Tool::IMPULSE_DENOISE, + }, + { + .id = Tool::DIR_PYR_DENOISE, + }, + { + .id = Tool::DEFRINGE_TOOL, + }, + { + .id = Tool::DIR_PYR_EQUALIZER, + }, + { + .id = Tool::DEHAZE, + }, +}; + +const std::vector COLOR_PANEL_TOOLS = { + { + .id = Tool::WHITE_BALANCE, + }, + { + .id = Tool::VIBRANCE, + }, + { + .id = Tool::CH_MIXER, + }, + { + .id = Tool::BLACK_WHITE, + }, + { + .id = Tool::HSV_EQUALIZER, + }, + { + .id = Tool::FILM_SIMULATION, + }, + { + .id = Tool::FILM_NEGATIVE, + }, + { + .id = Tool::SOFT_LIGHT, + }, + { + .id = Tool::RGB_CURVES, + }, + { + .id = Tool::COLOR_TONING, + }, + { + .id = Tool::ICM, + }, +}; + +const std::vector ADVANCED_PANEL_TOOLS = { + { + .id = Tool::RETINEX_TOOL, + }, + { + .id = Tool::COLOR_APPEARANCE, + }, + { + .id = Tool::WAVELET, + }, +}; + +const std::vector LOCALLAB_PANEL_TOOLS = { + { + .id = Tool::LOCALLAB, + }, +}; + +const std::vector TRANSFORM_PANEL_TOOLS = { + { + .id = Tool::CROP_TOOL, + }, + { + .id = Tool::RESIZE_TOOL, + .children = { + { + .id = Tool::PR_SHARPENING, + }, + }, + }, + { + .id = Tool::LENS_GEOM, + .children = { + { + .id = Tool::ROTATE, + }, + { + .id = Tool::PERSPECTIVE, + }, + { + .id = Tool::LENS_PROF, + }, + { + .id = Tool::DISTORTION, + }, + { + .id = Tool::CA_CORRECTION, + }, + { + .id = Tool::VIGNETTING, + }, + }, + }, +}; + +const std::vector RAW_PANEL_TOOLS = { + { + .id = Tool::SENSOR_BAYER, + .children = { + { + { + .id = Tool::BAYER_PROCESS, + }, + { + .id = Tool::BAYER_RAW_EXPOSURE, + }, + { + .id = Tool::BAYER_PREPROCESS, + }, + { + .id = Tool::RAW_CA_CORRECTION, + }, + }, + }, + }, + { + .id = Tool::SENSOR_XTRANS, + .children = { + { + { + .id = Tool::XTRANS_PROCESS, + }, + { + .id = Tool::XTRANS_RAW_EXPOSURE, + }, + }, + }, + }, + { + .id = Tool::RAW_EXPOSURE, + }, + { + .id = Tool::PREPROCESS_WB, + }, + { + .id = Tool::PREPROCESS, + }, + { + .id = Tool::DARKFRAME_TOOL, + }, + { + .id = Tool::FLATFIELD_TOOL, + }, + { + .id = Tool::PD_SHARPENING, + }, +}; + +const std::unordered_map> PANEL_TOOLS = { + { + ToolPanelCoordinator::Panel::EXPOSURE, + EXPOSURE_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::DETAILS, + DETAILS_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::COLOR, + COLOR_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::ADVANCED, + ADVANCED_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::LOCALLAB, + LOCALLAB_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::TRANSFORM_PANEL, + TRANSFORM_PANEL_TOOLS + }, + { + ToolPanelCoordinator::Panel::RAW, + RAW_PANEL_TOOLS + }, +}; + ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr), photoLoadedOnce(false) { @@ -288,6 +523,21 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit prevPage = toolPanelNotebook->get_nth_page(0); } +const std::unordered_map> ToolPanelCoordinator::getDefaultToolLayout() +{ + return PANEL_TOOLS; +} + +bool ToolPanelCoordinator::isFavoritable(Tool tool) +{ + switch (tool) { + case Tool::PR_SHARPENING: + return false; + default: + return true; + } +} + void ToolPanelCoordinator::notebookPageChanged(Gtk::Widget* page, guint page_num) { // Locallab spot curves are set visible if at least one photo has been loaded (to avoid diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 13686d6e3..c4215ee2a 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -223,12 +223,90 @@ private: Gtk::Widget* prevPage; public: + enum class Panel { + FAVORITE, + EXPOSURE, + DETAILS, + COLOR, + ADVANCED, + LOCALLAB, + TRANSFORM_PANEL, + RAW, + }; + + enum class Tool { + TONE_CURVE, + SHADOWS_HIGHLIGHTS, + IMPULSE_DENOISE, + DEFRINGE_TOOL, + SPOT, + DIR_PYR_DENOISE, + EPD, + SHARPENING_TOOL, + LOCAL_CONTRAST, + SHARPEN_EDGE, + SHARPEN_MICRO, + L_CURVE, + RGB_CURVES, + COLOR_TONING, + LENS_GEOM, + LENS_PROF, + DISTORTION, + ROTATE, + VIBRANCE, + COLOR_APPEARANCE, + WHITE_BALANCE, + VIGNETTING, + RETINEX_TOOL, + GRADIENT, + LOCALLAB, + PC_VIGNETTE, + PERSPECTIVE, + CA_CORRECTION, + CH_MIXER, + BLACK_WHITE, + RESIZE_TOOL, + PR_SHARPENING, + CROP_TOOL, + ICM, + WAVELET, + DIR_PYR_EQUALIZER, + HSV_EQUALIZER, + FILM_SIMULATION, + SOFT_LIGHT, + DEHAZE, + SENSOR_BAYER, + SENSOR_XTRANS, + BAYER_PROCESS, + XTRANS_PROCESS, + BAYER_PREPROCESS, + PREPROCESS, + DARKFRAME_TOOL, + FLATFIELD_TOOL, + RAW_CA_CORRECTION, + RAW_EXPOSURE, + PREPROCESS_WB, + BAYER_RAW_EXPOSURE, + XTRANS_RAW_EXPOSURE, + FATTAL, + FILM_NEGATIVE, + PD_SHARPENING, + }; + + struct ToolTree { + Tool id; + std::vector children; + }; + CoarsePanel* coarse; Gtk::Notebook* toolPanelNotebook; ToolPanelCoordinator(bool batch = false); ~ToolPanelCoordinator () override; + static const std::unordered_map> getDefaultToolLayout(); + static bool isFavoritable(Tool tool); + bool getChangedState() { return hasChanged; From 23214ae5cd99905fef97e192561886b0210288bb Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 22 Nov 2021 21:38:14 -0800 Subject: [PATCH 034/326] Clean up code Fix compile warning, remove GTK functions not present in version 3.16, and make code more concise. --- rtgui/preferences.cc | 2 +- rtgui/toollocationpref.cc | 26 ++++++++++++-------------- rtgui/toolpanelcoord.cc | 2 +- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 556201732..de3553aee 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -498,7 +498,7 @@ void Preferences::behSetRadioToggled(const Glib::ustring& path) Gtk::Widget *Preferences::getFavoritesPanel() { if (!toolLocationPreference) { - toolLocationPreference = Gtk::make_managed(moptions); + toolLocationPreference = Gtk::manage(new ToolLocationPreference(moptions)); } return toolLocationPreference; } diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 719a72a66..ccbc9310a 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -364,17 +364,16 @@ ToolLocationPreference::Impl::Impl(Options &options) : Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_FAVORITE"))), toolListViewColumnToolName( Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), - toolListViewPtr(Gtk::make_managed()), + toolListViewPtr(Gtk::manage(new Gtk::TreeView(toolListModelPtr))), favoritesModelPtr(Gtk::ListStore::create(favoritesColumns)), favoritesViewColumnToolName( Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), - favoritesViewPtr(Gtk::make_managed()) + favoritesViewPtr(Gtk::manage(new Gtk::TreeView(favoritesModelPtr))) { const std::vector favorites = toolNamesToTools(options.favorites); // Tool list. - toolListViewPtr->set_model(toolListModelPtr); toolListViewPtr->append_column(toolListViewColumnToolName); toolListViewColumnToolName.pack_start(toolListCellRendererToolName); toolListViewColumnToolName.set_expand(); @@ -386,14 +385,13 @@ ToolLocationPreference::Impl::Impl(Options &options) : toolListViewColumnFavorite.set_renderer( toolListCellRendererFavorite, toolListColumns.isFavorite); toolListViewColumnFavorite.add_attribute( - toolListCellRendererFavorite, "visible", toolListColumns.isEditable); + toolListCellRendererFavorite.property_visible(), toolListColumns.isEditable); toolListCellRendererFavorite.signal_toggled().connect( sigc::mem_fun(*this, &ToolLocationPreference::Impl::favoriteToggled)); initToolListRows(favorites); toolListViewPtr->expand_all(); // Favorites list. - favoritesViewPtr->set_model(favoritesModelPtr); favoritesViewPtr->append_column(favoritesViewColumnToolName); favoritesViewPtr->set_reorderable(true); favoritesViewColumnToolName.pack_start(favoritesCellRendererToolName); @@ -555,19 +553,19 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : impl(new Impl(options)) { // Layout grid. - Gtk::Grid *layout_grid = Gtk::make_managed(); + Gtk::Grid *layout_grid = Gtk::manage(new Gtk::Grid()); layout_grid->set_column_spacing(4); layout_grid->set_row_spacing(4); add(*layout_grid); // Tool list. - Gtk::Frame *tool_list_frame = Gtk::make_managed( - M("PREFERENCES_TOOLPANEL_AVAILABLETOOLS")); + Gtk::Frame *tool_list_frame = Gtk::manage(new Gtk::Frame( + M("PREFERENCES_TOOLPANEL_AVAILABLETOOLS"))); Gtk::ScrolledWindow *tool_list_scrolled_window = - Gtk::make_managed(); + Gtk::manage(new Gtk::ScrolledWindow()); tool_list_scrolled_window->property_hscrollbar_policy() = Gtk::PolicyType::POLICY_NEVER; - layout_grid->attach_next_to(*tool_list_frame, Gtk::PositionType::POS_RIGHT); + 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); impl->toolListViewPtr->set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_MINIMUM); @@ -575,13 +573,13 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : tool_list_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); // Favorites list. - Gtk::Frame *favorites_frame = Gtk::make_managed( - M("PREFERENCES_TOOLPANEL_FAVORITESPANEL")); + Gtk::Frame *favorites_frame = Gtk::manage(new Gtk::Frame( + M("PREFERENCES_TOOLPANEL_FAVORITESPANEL"))); Gtk::ScrolledWindow *favorites_list_scrolled_window = - Gtk::make_managed(); + Gtk::manage(new Gtk::ScrolledWindow()); favorites_list_scrolled_window->property_hscrollbar_policy() = Gtk::PolicyType::POLICY_NEVER; - layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT); + layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); favorites_frame->add(*favorites_list_scrolled_window); favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 586d4755f..23b297d20 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -33,7 +33,7 @@ using namespace rtengine::procparams; using Tool = ToolPanelCoordinator::Tool; -using ToolTree = struct ToolPanelCoordinator::ToolTree; +using ToolTree = ToolPanelCoordinator::ToolTree; const std::vector EXPOSURE_PANEL_TOOLS = { { From ac19ea45076498c388526d2bc9b1b182487f3d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Wed, 24 Nov 2021 15:32:04 +0100 Subject: [PATCH 035/326] Fix `enum class` key in hashed containers --- rtgui/guiutils.h | 12 ++++++++++++ rtgui/toollocationpref.cc | 7 ++++--- rtgui/toolpanelcoord.cc | 10 +++++----- rtgui/toolpanelcoord.h | 4 +++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 126cf672b..21e775c36 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -20,6 +20,7 @@ #include #include +#include #include @@ -74,6 +75,17 @@ private: MyMutex mutex; }; +struct ScopedEnumHash { + template::value && !std::is_convertible::value, int>::type = 0> + size_t operator ()(T val) const noexcept + { + using type = typename std::underlying_type::type; + + return std::hash{}(static_cast(val)); + } +}; + + // TODO: The documentation says gdk_threads_enter and gdk_threads_leave should be replaced // by g_main_context_invoke(), g_idle_add() and related functions, but this will require more extensive changes. // We silence those warnings until then so that we notice the others. diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index ccbc9310a..c0bb6bea3 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -24,6 +24,7 @@ #include "toolpanelcoord.h" using Tool = ToolPanelCoordinator::Tool; +using Favorites = std::unordered_set; std::string getToolName(Tool tool) { @@ -200,7 +201,7 @@ struct ToolLocationPreference::Impl { void addToolListRowGroup( const std::vector &tools, const Gtk::TreeIter &parentRowIter, - const std::unordered_set &favorites); + const Favorites &favorites); void favoriteToggled(const Glib::ustring &row_path); Tool getToolFromName(const std::string &name) const; void initFavoritesRows(const std::vector &favorites); @@ -477,7 +478,7 @@ void ToolLocationPreference::Impl::initFavoritesRows( void ToolLocationPreference::Impl::addToolListRowGroup( const std::vector &tools, const Gtk::TreeIter &parentRowIter, - const std::unordered_set &favorites) + const Favorites &favorites) { for (const ToolPanelCoordinator::ToolTree &tool : tools) { auto tool_row_iter = toolListModelPtr->append(parentRowIter->children()); @@ -498,7 +499,7 @@ void ToolLocationPreference::Impl::addToolListRowGroup( void ToolLocationPreference::Impl::initToolListRows(const std::vector &favorites) { const auto panel_tools = ToolPanelCoordinator::getDefaultToolLayout(); - std::unordered_set favorites_set; + Favorites favorites_set; for (const auto &tool : favorites) { favorites_set.insert(tool); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 23b297d20..fa2203958 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -236,7 +236,7 @@ const std::vector RAW_PANEL_TOOLS = { }, }; -const std::unordered_map> PANEL_TOOLS = { +const ToolPanelCoordinator::ToolLayout PANEL_TOOLS = { { ToolPanelCoordinator::Panel::EXPOSURE, EXPOSURE_PANEL_TOOLS @@ -378,7 +378,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); @@ -424,7 +424,7 @@ 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++) { @@ -455,7 +455,7 @@ 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); @@ -523,7 +523,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit prevPage = toolPanelNotebook->get_nth_page(0); } -const std::unordered_map> ToolPanelCoordinator::getDefaultToolLayout() +const ToolPanelCoordinator::ToolLayout& ToolPanelCoordinator::getDefaultToolLayout() { return PANEL_TOOLS; } diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index c4215ee2a..94e5a8717 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -298,13 +298,15 @@ public: std::vector children; }; + using ToolLayout = std::unordered_map, ScopedEnumHash>; + CoarsePanel* coarse; Gtk::Notebook* toolPanelNotebook; ToolPanelCoordinator(bool batch = false); ~ToolPanelCoordinator () override; - static const std::unordered_map> getDefaultToolLayout(); + static const ToolLayout& getDefaultToolLayout(); static bool isFavoritable(Tool tool); bool getChangedState() From c6a45ae765c842ab75aa9f936c35756ce1cc97de Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 25 Nov 2021 14:58:42 -0800 Subject: [PATCH 036/326] Move helper functions into anonymous namespace Move some functions in toollocationpref.cc. --- rtgui/toollocationpref.cc | 143 ++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 69 deletions(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index c0bb6bea3..3e874627c 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -26,6 +26,9 @@ using Tool = ToolPanelCoordinator::Tool; using Favorites = std::unordered_set; +namespace +{ + std::string getToolName(Tool tool) { switch (tool) { @@ -145,75 +148,6 @@ std::string getToolName(Tool tool) return ""; }; -class FavoritesColumns : public Gtk::TreeModelColumnRecord -{ -public: - Gtk::TreeModelColumn toolName; - Gtk::TreeModelColumn tool; - - FavoritesColumns() - { - add(toolName); - add(tool); - } -}; - -class ToolListColumns : public Gtk::TreeModelColumnRecord -{ -public: - Gtk::TreeModelColumn toolName; - Gtk::TreeModelColumn tool; - Gtk::TreeModelColumn isFavorite; - Gtk::TreeModelColumn isEditable; - - ToolListColumns() - { - add(toolName); - add(tool); - add(isFavorite); - add(isEditable); - } -}; - -struct ToolLocationPreference::Impl { - static std::unordered_map toolNamesReverseMap; - - Options &options; - - // Tool list. - ToolListColumns toolListColumns; - Glib::RefPtr toolListModelPtr; - Gtk::CellRendererToggle toolListCellRendererFavorite; - Gtk::CellRendererText toolListCellRendererToolName; - Gtk::TreeViewColumn toolListViewColumnFavorite; - Gtk::TreeViewColumn toolListViewColumnToolName; - Gtk::TreeView *toolListViewPtr; - - // Favorites list. - FavoritesColumns favoritesColumns; - Glib::RefPtr favoritesModelPtr; - Gtk::CellRendererText favoritesCellRendererToolName; - Gtk::TreeViewColumn favoritesViewColumnToolName; - Gtk::TreeView *favoritesViewPtr; - - explicit Impl(Options &options); - - void addToolListRowGroup( - const std::vector &tools, - const Gtk::TreeIter &parentRowIter, - const Favorites &favorites); - void favoriteToggled(const Glib::ustring &row_path); - Tool getToolFromName(const std::string &name) const; - void initFavoritesRows(const std::vector &favorites); - void initToolListRows(const std::vector &favorites); - std::vector toolNamesToTools( - const std::vector &tool_names) const; - void updateOptions(); -}; - -std::unordered_map - ToolLocationPreference::Impl::toolNamesReverseMap; - Glib::ustring getToolPanelTitleKey(ToolPanelCoordinator::Panel panel) { switch (panel) { @@ -357,6 +291,77 @@ Glib::ustring getToolTitleKey(Tool tool) return ""; } +} + +class FavoritesColumns : public Gtk::TreeModelColumnRecord +{ +public: + Gtk::TreeModelColumn toolName; + Gtk::TreeModelColumn tool; + + FavoritesColumns() + { + add(toolName); + add(tool); + } +}; + +class ToolListColumns : public Gtk::TreeModelColumnRecord +{ +public: + Gtk::TreeModelColumn toolName; + Gtk::TreeModelColumn tool; + Gtk::TreeModelColumn isFavorite; + Gtk::TreeModelColumn isEditable; + + ToolListColumns() + { + add(toolName); + add(tool); + add(isFavorite); + add(isEditable); + } +}; + +struct ToolLocationPreference::Impl { + static std::unordered_map toolNamesReverseMap; + + Options &options; + + // Tool list. + ToolListColumns toolListColumns; + Glib::RefPtr toolListModelPtr; + Gtk::CellRendererToggle toolListCellRendererFavorite; + Gtk::CellRendererText toolListCellRendererToolName; + Gtk::TreeViewColumn toolListViewColumnFavorite; + Gtk::TreeViewColumn toolListViewColumnToolName; + Gtk::TreeView *toolListViewPtr; + + // Favorites list. + FavoritesColumns favoritesColumns; + Glib::RefPtr favoritesModelPtr; + Gtk::CellRendererText favoritesCellRendererToolName; + Gtk::TreeViewColumn favoritesViewColumnToolName; + Gtk::TreeView *favoritesViewPtr; + + explicit Impl(Options &options); + + void addToolListRowGroup( + const std::vector &tools, + const Gtk::TreeIter &parentRowIter, + const Favorites &favorites); + void favoriteToggled(const Glib::ustring &row_path); + Tool getToolFromName(const std::string &name) const; + void initFavoritesRows(const std::vector &favorites); + void initToolListRows(const std::vector &favorites); + std::vector toolNamesToTools( + const std::vector &tool_names) const; + void updateOptions(); +}; + +std::unordered_map + ToolLocationPreference::Impl::toolNamesReverseMap; + ToolLocationPreference::Impl::Impl(Options &options) : options(options), From fde15eaebb85a16f5c068ff46e54d8f9d5b48d6e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 25 Nov 2021 15:35:02 -0800 Subject: [PATCH 037/326] Improve look of favorites preferences Set a fixed width for the lists, embed the preferences in a horizontally-scrollable window, and open the preferences window on the general tab. --- rtgui/preferences.cc | 8 +++++++- rtgui/preferences.h | 1 + rtgui/toollocationpref.cc | 9 ++------- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index de3553aee..39726c791 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -67,6 +67,7 @@ Preferences::Preferences(RTWindow *rtwindow) , newFont(false) , newCPFont(false) , toolLocationPreference(nullptr) + , swFavorites(nullptr) { moptions.copyFrom(&options); @@ -500,7 +501,12 @@ Gtk::Widget *Preferences::getFavoritesPanel() if (!toolLocationPreference) { toolLocationPreference = Gtk::manage(new ToolLocationPreference(moptions)); } - return toolLocationPreference; + if (!swFavorites) { + swFavorites = Gtk::manage(new Gtk::ScrolledWindow()); + swFavorites->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER); + swFavorites->add(*toolLocationPreference); + } + return swFavorites; } Gtk::Widget *Preferences::getDynamicProfilePanel() diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 18d7a0581..33ca44eca 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -272,6 +272,7 @@ class Preferences final : Gtk::ScrolledWindow *swGeneral; Gtk::ScrolledWindow *swImageProcessing; + Gtk::ScrolledWindow *swFavorites; Gtk::ScrolledWindow *swDynamicProfile; Gtk::ScrolledWindow *swFileBrowser; Gtk::ScrolledWindow *swColorMan; diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 3e874627c..d0a8cdf34 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -569,12 +569,10 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : M("PREFERENCES_TOOLPANEL_AVAILABLETOOLS"))); Gtk::ScrolledWindow *tool_list_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); - tool_list_scrolled_window->property_hscrollbar_policy() = - Gtk::PolicyType::POLICY_NEVER; + tool_list_scrolled_window->set_min_content_width(550); 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); - impl->toolListViewPtr->set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_MINIMUM); setExpandAlignProperties( tool_list_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); @@ -583,15 +581,12 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : M("PREFERENCES_TOOLPANEL_FAVORITESPANEL"))); Gtk::ScrolledWindow *favorites_list_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); - favorites_list_scrolled_window->property_hscrollbar_policy() = - Gtk::PolicyType::POLICY_NEVER; + favorites_list_scrolled_window->set_min_content_width(400); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); favorites_frame->add(*favorites_list_scrolled_window); favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( favorites_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); - - this->show_all(); } void ToolLocationPreference::updateOptions() From 4fe39a82a5e024777e7b6d314158b1dbb8182ed1 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 26 Nov 2021 15:46:24 -0800 Subject: [PATCH 038/326] Add buttons for reordering favorites --- rtgui/toollocationpref.cc | 194 +++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 3 deletions(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index d0a8cdf34..2330759a4 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -20,6 +20,7 @@ #include "guiutils.h" #include "options.h" +#include "rtimage.h" #include "toollocationpref.h" #include "toolpanelcoord.h" @@ -291,7 +292,28 @@ Glib::ustring getToolTitleKey(Tool tool) return ""; } -} +class ListEditButtons : public Gtk::Box +{ +private: + Gtk::TreeView &list; + Glib::RefPtr listStore; + Gtk::Button buttonUp; + Gtk::Button buttonDown; + Gtk::Button buttonRemove; + + sigc::signal> signalRowsPreErase; + + void onButtonDownPressed(); + void onButtonRemovePressed(); + void onButtonUpPressed(); + void onListSelectionChanged(); + void updateButtonSensitivity(); + +public: + explicit ListEditButtons(Gtk::TreeView &list, Glib::RefPtr listStore); + + sigc::signal> getSignalRowsPreErase(); +}; class FavoritesColumns : public Gtk::TreeModelColumnRecord { @@ -323,6 +345,148 @@ public: } }; +ListEditButtons::ListEditButtons(Gtk::TreeView &list, Glib::RefPtr listStore) : + Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL), + list(list), + listStore(listStore) +{ + assert(list.get_model() == listStore); + + // Set button images. + RTImage *image_button_up = Gtk::manage(new RTImage("arrow-up-small.png")); + RTImage *image_button_down = Gtk::manage(new RTImage("arrow-down-small.png")); + RTImage *image_button_remove = Gtk::manage(new RTImage("remove-small.png")); + buttonUp.set_image(*image_button_up); + buttonDown.set_image(*image_button_down); + buttonRemove.set_image(*image_button_remove); + + // Connect signals for changing button sensitivity. + const auto on_list_sel_changed_fun = sigc::mem_fun( + *this, &ListEditButtons::onListSelectionChanged); + const auto on_row_deleted_fun = sigc::hide(on_list_sel_changed_fun); + const auto on_row_inserted_fun = sigc::hide(on_row_deleted_fun); + list.get_selection()->signal_changed().connect(on_list_sel_changed_fun); + listStore->signal_row_deleted().connect(on_row_deleted_fun); + listStore->signal_row_inserted().connect(on_row_inserted_fun); + + // Connect signals for buttons. + buttonUp.signal_pressed().connect(sigc::mem_fun( + *this, &ListEditButtons::onButtonUpPressed)); + buttonDown.signal_pressed().connect(sigc::mem_fun( + *this, &ListEditButtons::onButtonDownPressed)); + buttonRemove.signal_pressed().connect(sigc::mem_fun( + *this, &ListEditButtons::onButtonRemovePressed)); + + updateButtonSensitivity(); + + add(buttonUp); + add(buttonDown); + add(buttonRemove); +} + +void ListEditButtons::onButtonDownPressed() +{ + const auto list_children = listStore->children(); + const std::vector selected = + list.get_selection()->get_selected_rows(); + + if (selected.size() != 1) { // Only one can be selected. + return; + } + + auto selected_row_iter = listStore->get_iter(selected[0]); + auto next_row_iter = selected_row_iter; + next_row_iter++; + + if (next_row_iter == list_children.end()) { // Can't be last row. + return; + } + + listStore->iter_swap(selected_row_iter, next_row_iter); + updateButtonSensitivity(); +} + +void ListEditButtons::onButtonRemovePressed() +{ + const std::vector selected_paths = + list.get_selection()->get_selected_rows(); + std::vector selected; + + // Get row references, which are valid until the row is removed. + for (const auto & row_path : selected_paths) { + selected.push_back(Gtk::TreeModel::RowReference(listStore, row_path)); + } + + signalRowsPreErase.emit(selected_paths); + + for (const auto & row_ref : selected) { + const auto row_path = row_ref.get_path(); + if (row_path) { + listStore->erase(listStore->get_iter(row_path)); + } + } + + updateButtonSensitivity(); +} + +void ListEditButtons::onButtonUpPressed() +{ + const auto list_children = listStore->children(); + const std::vector selected = + list.get_selection()->get_selected_rows(); + + if (selected.size() != 1) { // Only one can be selected. + return; + } + + auto selected_row_iter = listStore->get_iter(selected[0]); + + if (selected_row_iter == list_children.begin()) { // Can't be first row. + return; + } + + auto prev_row_iter = selected_row_iter; + prev_row_iter--; + listStore->iter_swap(selected_row_iter, prev_row_iter); + updateButtonSensitivity(); +} + +void ListEditButtons::onListSelectionChanged() +{ + updateButtonSensitivity(); +} + +void ListEditButtons::updateButtonSensitivity() +{ + assert(list.get_model() == listStore); + + const std::vector selected = + list.get_selection()->get_selected_rows(); + + // Update sensitivity of the move up/down buttons. + if (selected.size() != 1) { + // Items can only be moved if one row is selected. + buttonDown.set_sensitive(false); + buttonUp.set_sensitive(false); + } else { + auto selected_row_iter = list.get_model()->get_iter(selected[0]); + const auto list_children = listStore->children(); + buttonUp.set_sensitive(!selected_row_iter->equal(list_children.begin())); + buttonDown.set_sensitive(!(++selected_row_iter)->equal(list_children.end())); + } + + // Update sensitivity of the remove button. + buttonRemove.set_sensitive(selected.size() > 0); +} + +sigc::signal> +ListEditButtons::getSignalRowsPreErase() +{ + return signalRowsPreErase; +} + +} + struct ToolLocationPreference::Impl { static std::unordered_map toolNamesReverseMap; @@ -336,6 +500,7 @@ struct ToolLocationPreference::Impl { Gtk::TreeViewColumn toolListViewColumnFavorite; Gtk::TreeViewColumn toolListViewColumnToolName; Gtk::TreeView *toolListViewPtr; + std::unordered_map toolListToolToRowIterMap; // Favorites list. FavoritesColumns favoritesColumns; @@ -343,6 +508,7 @@ struct ToolLocationPreference::Impl { Gtk::CellRendererText favoritesCellRendererToolName; Gtk::TreeViewColumn favoritesViewColumnToolName; Gtk::TreeView *favoritesViewPtr; + ListEditButtons favoritesListEditButtons; explicit Impl(Options &options); @@ -354,6 +520,7 @@ struct ToolLocationPreference::Impl { Tool getToolFromName(const std::string &name) const; void initFavoritesRows(const std::vector &favorites); void initToolListRows(const std::vector &favorites); + void onFavoritesRowsPreRemove(const std::vector paths); std::vector toolNamesToTools( const std::vector &tool_names) const; void updateOptions(); @@ -375,7 +542,8 @@ ToolLocationPreference::Impl::Impl(Options &options) : favoritesModelPtr(Gtk::ListStore::create(favoritesColumns)), favoritesViewColumnToolName( Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), - favoritesViewPtr(Gtk::manage(new Gtk::TreeView(favoritesModelPtr))) + favoritesViewPtr(Gtk::manage(new Gtk::TreeView(favoritesModelPtr))), + favoritesListEditButtons(*favoritesViewPtr, favoritesModelPtr) { const std::vector favorites = toolNamesToTools(options.favorites); @@ -403,6 +571,10 @@ ToolLocationPreference::Impl::Impl(Options &options) : favoritesViewColumnToolName.pack_start(favoritesCellRendererToolName); favoritesViewColumnToolName.set_renderer( favoritesCellRendererToolName, favoritesColumns.toolName); + favoritesListEditButtons.getSignalRowsPreErase().connect(sigc::mem_fun( + *this, &ToolLocationPreference::Impl::onFavoritesRowsPreRemove)); + favoritesViewPtr->get_selection()->set_mode( + Gtk::SelectionMode::SELECTION_MULTIPLE); initFavoritesRows(favorites); } @@ -497,6 +669,7 @@ void ToolLocationPreference::Impl::addToolListRowGroup( tool_row_iter->set_value( toolListColumns.isEditable, ToolPanelCoordinator::isFavoritable(tool.id)); + toolListToolToRowIterMap[tool.id] = tool_row_iter; addToolListRowGroup(tool.children, tool_row_iter, favorites); } }; @@ -527,6 +700,18 @@ void ToolLocationPreference::Impl::initToolListRows(const std::vector &fav } } +void ToolLocationPreference::Impl::onFavoritesRowsPreRemove( + const std::vector paths) +{ + // Unset the favorite column in the tools list for tools about to be removed + // from the favorites list. + for (const auto &path : paths) { + const auto &row_iter = toolListToolToRowIterMap.at( + favoritesModelPtr->get_iter(path)->get_value(favoritesColumns.tool)); + row_iter->set_value(toolListColumns.isFavorite, false); + } +} + std::vector ToolLocationPreference::Impl::toolNamesToTools( const std::vector &tool_names) const { @@ -579,11 +764,14 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : // Favorites list. Gtk::Frame *favorites_frame = Gtk::manage(new Gtk::Frame( M("PREFERENCES_TOOLPANEL_FAVORITESPANEL"))); + 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(400); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); - favorites_frame->add(*favorites_list_scrolled_window); + favorites_box->pack_start(*favorites_list_scrolled_window, false, false); + favorites_box->pack_start(impl->favoritesListEditButtons, false, false); + favorites_frame->add(*favorites_box); favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( favorites_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); From 16a9e3932fb8379537bb1d435631faf0d4334bb2 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 26 Nov 2021 16:39:50 -0800 Subject: [PATCH 039/326] Fix compilation error Add hasher to unordered_map with an enum class key. --- rtgui/toollocationpref.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 2330759a4..0dda56806 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -500,7 +500,8 @@ struct ToolLocationPreference::Impl { Gtk::TreeViewColumn toolListViewColumnFavorite; Gtk::TreeViewColumn toolListViewColumnToolName; Gtk::TreeView *toolListViewPtr; - std::unordered_map toolListToolToRowIterMap; + std::unordered_map + toolListToolToRowIterMap; // Favorites list. FavoritesColumns favoritesColumns; From 9a67dd726e4c85d3a468466b62de3fa37b42f5ee Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 26 Nov 2021 21:01:37 -0800 Subject: [PATCH 040/326] Comment code for tool location preferences --- rtgui/toollocationpref.cc | 106 ++++++++++++++++++++++++++++++++++++++ rtgui/toollocationpref.h | 11 ++++ 2 files changed, 117 insertions(+) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 0dda56806..32cd73e97 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -30,6 +30,12 @@ using Favorites = std::unordered_set; namespace { +/** + * Gets the tool name for the tool's ToolPanel as a string. + * + * @param tool The name as a raw string, or an empty string if the tool is + * unknown. + */ std::string getToolName(Tool tool) { switch (tool) { @@ -149,6 +155,9 @@ std::string getToolName(Tool tool) return ""; }; +/** + * Returns the language key for the panel's title. + */ Glib::ustring getToolPanelTitleKey(ToolPanelCoordinator::Panel panel) { switch (panel) { @@ -172,6 +181,9 @@ Glib::ustring getToolPanelTitleKey(ToolPanelCoordinator::Panel panel) return ""; } +/** + * Returns the language key for the tool's title. + */ Glib::ustring getToolTitleKey(Tool tool) { using Tool = Tool; @@ -292,6 +304,13 @@ Glib::ustring getToolTitleKey(Tool tool) return ""; } +/** + * A widget with buttons (packed vertically) for modifying a list store with a + * tree view. + * + * Includes buttons for moving single rows up or down and a button for removing + * selected rows. + */ class ListEditButtons : public Gtk::Box { private: @@ -310,15 +329,34 @@ private: void updateButtonSensitivity(); public: + /** + * Constructs an edit buttons widget for modifying the provided list store. + * + * @param list The tree view for which selections are made in. The tree + * view's model MUST be the list store. + * @param listStore The list store that the widget will modify. + */ explicit ListEditButtons(Gtk::TreeView &list, Glib::RefPtr listStore); + /** + * Returns the signal that gets emitted right before this widget removes + * rows from its list store. + * + * The signal contains a vector of tree model paths of the rows that will be + * erased. + */ sigc::signal> getSignalRowsPreErase(); }; +/** + * Model columns for the favorites list. + */ class FavoritesColumns : public Gtk::TreeModelColumnRecord { public: + /** The tool's display name. */ Gtk::TreeModelColumn toolName; + /** The tool. */ Gtk::TreeModelColumn tool; FavoritesColumns() @@ -328,12 +366,19 @@ public: } }; +/** + * Model columns for the available tools list. + */ class ToolListColumns : public Gtk::TreeModelColumnRecord { public: + /** The tool's display name. */ Gtk::TreeModelColumn toolName; + /** The tool. */ Gtk::TreeModelColumn tool; + /** Is the tool added to favorites. */ Gtk::TreeModelColumn isFavorite; + /** Can the tool be added to favorites. */ Gtk::TreeModelColumn isEditable; ToolListColumns() @@ -394,6 +439,7 @@ void ListEditButtons::onButtonDownPressed() return; } + // Get the selected row and next row. auto selected_row_iter = listStore->get_iter(selected[0]); auto next_row_iter = selected_row_iter; next_row_iter++; @@ -402,6 +448,7 @@ void ListEditButtons::onButtonDownPressed() return; } + // Move the selected row down and update the buttons. listStore->iter_swap(selected_row_iter, next_row_iter); updateButtonSensitivity(); } @@ -419,6 +466,7 @@ void ListEditButtons::onButtonRemovePressed() signalRowsPreErase.emit(selected_paths); + // Remove the selected rows. for (const auto & row_ref : selected) { const auto row_path = row_ref.get_path(); if (row_path) { @@ -445,6 +493,7 @@ void ListEditButtons::onButtonUpPressed() return; } + // Swap selected row with the previous row. auto prev_row_iter = selected_row_iter; prev_row_iter--; listStore->iter_swap(selected_row_iter, prev_row_iter); @@ -469,6 +518,8 @@ void ListEditButtons::updateButtonSensitivity() buttonDown.set_sensitive(false); buttonUp.set_sensitive(false); } else { + // Up button cannot be used on the first row. Down button cannot be used + // on the last row. auto selected_row_iter = list.get_model()->get_iter(selected[0]); const auto list_children = listStore->children(); buttonUp.set_sensitive(!selected_row_iter->equal(list_children.begin())); @@ -511,19 +562,68 @@ struct ToolLocationPreference::Impl { Gtk::TreeView *favoritesViewPtr; ListEditButtons favoritesListEditButtons; + /** + * Constructs an implementation that gets values from and updates the + * provided options object. + */ explicit Impl(Options &options); + /** + * Adds the tools in the tool tree as a child in the provided row. + * + * @param tools The tool tree. + * @param parentRowIter An iterator to the row under which to add the tools. + * @param favorites The tools which are currently marked as favorites. + */ void addToolListRowGroup( const std::vector &tools, const Gtk::TreeIter &parentRowIter, const Favorites &favorites); + /** + * Toggles the tool list favorite column and updates the favorites list. + * + * @param row_path Path to the tool list model row. + */ void favoriteToggled(const Glib::ustring &row_path); + /** + * Gets the tool with the provided tool name. + * + * @param name The tool name as a raw string. + * @return The tool. + */ Tool getToolFromName(const std::string &name) const; + /** + * Initializes the favorites list. + * + * @param favorites Tools that are currently marked as favorites. + */ void initFavoritesRows(const std::vector &favorites); + /** + * Initializes the available tools list. + * + * @param favorites Tools that are currently marked as favorites. + */ void initToolListRows(const std::vector &favorites); + /** + * Updates the favorites column of the available tools list when tools are + * about to be removed from the favorites list. + * + * @param paths Paths in the favorites list pointing to the rows that are + * about to be removed. + */ void onFavoritesRowsPreRemove(const std::vector paths); + /** + * Converts tool names to their corresponding tools. + * + * @param tool_names The tool names that need to be converted. + * @return The tools. + */ std::vector toolNamesToTools( const std::vector &tool_names) const; + /** + * Updates the options object associated with this object with the current + * favorites preferences. + */ void updateOptions(); }; @@ -533,6 +633,7 @@ std::unordered_map ToolLocationPreference::Impl::Impl(Options &options) : options(options), + // Tool list. toolListModelPtr(Gtk::TreeStore::create(toolListColumns)), toolListViewColumnFavorite( Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_FAVORITE"))), @@ -540,6 +641,7 @@ ToolLocationPreference::Impl::Impl(Options &options) : Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), toolListViewPtr(Gtk::manage(new Gtk::TreeView(toolListModelPtr))), + // Favorites list. favoritesModelPtr(Gtk::ListStore::create(favoritesColumns)), favoritesViewColumnToolName( Gtk::TreeViewColumn(M("PREFERENCES_TOOLPANEL_TOOL"))), @@ -644,6 +746,7 @@ Tool ToolLocationPreference::Impl::getToolFromName(const std::string &name) cons void ToolLocationPreference::Impl::initFavoritesRows( const std::vector &favorites) { + // Add the favorites to the favorites list store. for (const auto tool : favorites) { auto favorite_row_iter = favoritesModelPtr->append(); favorite_row_iter->set_value( @@ -658,6 +761,7 @@ void ToolLocationPreference::Impl::addToolListRowGroup( const Gtk::TreeIter &parentRowIter, const Favorites &favorites) { + // Recursively add the tool and its children to the tool list tree store. for (const ToolPanelCoordinator::ToolTree &tool : tools) { auto tool_row_iter = toolListModelPtr->append(parentRowIter->children()); tool_row_iter->set_value( @@ -680,10 +784,12 @@ void ToolLocationPreference::Impl::initToolListRows(const std::vector &fav const auto panel_tools = ToolPanelCoordinator::getDefaultToolLayout(); Favorites favorites_set; + // Convert the favorites vector into a set for fast lookup. for (const auto &tool : favorites) { favorites_set.insert(tool); } + // Add each panel and their children to the tool list. for (const auto panel : { ToolPanelCoordinator::Panel::EXPOSURE, ToolPanelCoordinator::Panel::DETAILS, diff --git a/rtgui/toollocationpref.h b/rtgui/toollocationpref.h index 815df6839..c7bee8695 100644 --- a/rtgui/toollocationpref.h +++ b/rtgui/toollocationpref.h @@ -22,6 +22,9 @@ class Options; +/** + * Widget for configuring the location of tools in the tool panel tabs. + */ class ToolLocationPreference : public Gtk::Box { private: @@ -29,6 +32,14 @@ private: std::unique_ptr impl; public: + /** + * Constructs a tool location preference widget that gets values from and + * updates the provided options object. + */ explicit ToolLocationPreference(Options &options); + /** + * Updates the options object associated with this object with the current + * favorites preferences. + */ void updateOptions(); }; From 8bd7712cce1dba8cd6cf0d876008a35646141942 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 26 Nov 2021 21:34:19 -0800 Subject: [PATCH 041/326] Add error handling to tool location preferences --- rtgui/toollocationpref.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 32cd73e97..a6c7bf6b4 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.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 "guiutils.h" @@ -152,6 +153,7 @@ std::string getToolName(Tool tool) case Tool::PD_SHARPENING: return "capturesharpening"; }; + assert(false); return ""; }; @@ -178,6 +180,7 @@ Glib::ustring getToolPanelTitleKey(ToolPanelCoordinator::Panel panel) case ToolPanelCoordinator::Panel::RAW: return "MAIN_TAB_RAW"; } + assert(false); return ""; } @@ -301,6 +304,7 @@ Glib::ustring getToolTitleKey(Tool tool) case Tool::PD_SHARPENING: return "TP_PDSHARPENING_LABEL"; }; + assert(false); return ""; } @@ -471,6 +475,8 @@ void ListEditButtons::onButtonRemovePressed() const auto row_path = row_ref.get_path(); if (row_path) { listStore->erase(listStore->get_iter(row_path)); + } else if (rtengine::settings->verbose) { + std::cout << "Unable to remove row because it does not exist anymore." << std::endl; } } @@ -829,6 +835,10 @@ std::vector ToolLocationPreference::Impl::toolNamesToTools( try { tool = getToolFromName(tool_name); } catch (const std::exception &e) { + if (rtengine::settings->verbose) { + std::cerr << "Unrecognized tool name \"" << tool_name << "\"." << std::endl; + } + assert(false); continue; } tool_set.push_back(tool); From 778b26d5bd26cce1f5bb8f6815f426ccd316cbed Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 5 Dec 2021 17:09:23 -0800 Subject: [PATCH 042/326] Make tool locations dynamic Update tool locations after changing favorite tools preferences. --- rtdata/themes/RawTherapee-GTK3-20_.css | 2 +- rtgui/editorpanel.cc | 7 + rtgui/editorpanel.h | 1 + rtgui/preferences.cc | 3 + rtgui/rtwindow.cc | 8 + rtgui/rtwindow.h | 1 + rtgui/toollocationpref.cc | 167 +------ rtgui/toolpanel.cc | 9 +- rtgui/toolpanel.h | 11 + rtgui/toolpanelcoord.cc | 608 ++++++++++++++++++++----- rtgui/toolpanelcoord.h | 43 +- 11 files changed, 586 insertions(+), 274 deletions(-) diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index 57c6db148..c576e0ddf 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -758,7 +758,7 @@ button.radio#histButton:hover { #MyExpander:first-child { border-top: none; } -#MyExpander:nth-last-child(2), +#MyExpander:nth-last-child(1), #MyExpander #MyExpander:nth-last-child(1) { border-bottom: 0.0833333333333333em solid rgba(0,0,0,0.3); } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 78a07ddd6..888fc9518 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2486,6 +2486,13 @@ void EditorPanel::updateHistogramPosition (int oldPosition, int newPosition) } +void EditorPanel::updateToolPanelToolLocations( + const std::vector &favorites) +{ + if (tpc) { + tpc->updateToolLocations(favorites); + } +} void EditorPanel::defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile) { diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 7675face5..0ffe44ace 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -185,6 +185,7 @@ public: void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); void updateTPVScrollbar (bool hide); void updateHistogramPosition (int oldPosition, int newPosition); + void updateToolPanelToolLocations(const std::vector &favorites); void defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 39726c791..e67d16015 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2572,6 +2572,9 @@ void Preferences::workflowUpdate() parent->updateProfiles (moptions.rtSettings.printerProfile, rtengine::RenderingIntent(moptions.rtSettings.printerIntent), moptions.rtSettings.printerBPC); } + if (moptions.favorites != options.favorites) { + parent->updateToolPanelToolLocations(moptions.favorites); + } } void Preferences::addExtPressed() diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 1b90d631b..15715a2fd 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -1110,6 +1110,14 @@ void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) } } +void RTWindow::updateToolPanelToolLocations( + const std::vector &favorites) +{ + if (epanel) { + epanel->updateToolPanelToolLocations(favorites); + } +} + bool RTWindow::splashClosed (GdkEventAny* event) { delete splash; diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 0c1cd2572..d35755185 100755 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -124,6 +124,7 @@ public: void updateFBQueryTB (bool singleRow); void updateFBToolBarVisibility (bool showFilmStripToolBar); void updateShowtooltipVisibility (bool showtooltip); + void updateToolPanelToolLocations(const std::vector &favorites); bool getIsFullscreen() { return is_fullscreen; diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index a6c7bf6b4..561be4601 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -31,132 +31,6 @@ using Favorites = std::unordered_set; namespace { -/** - * Gets the tool name for the tool's ToolPanel as a string. - * - * @param tool The name as a raw string, or an empty string if the tool is - * unknown. - */ -std::string getToolName(Tool tool) -{ - switch (tool) { - case Tool::TONE_CURVE: - return "tonecurve"; - case Tool::SHADOWS_HIGHLIGHTS: - return "shadowshighlights"; - case Tool::IMPULSE_DENOISE: - return "impulsedenoise"; - case Tool::DEFRINGE_TOOL: - return "defringe"; - case Tool::SPOT: - return "spot"; - case Tool::DIR_PYR_DENOISE: - return "dirpyrdenoise"; - case Tool::EPD: - return "epd"; - case Tool::SHARPENING_TOOL: - return "sharpening"; - case Tool::LOCAL_CONTRAST: - return "localcontrast"; - case Tool::SHARPEN_EDGE: - return "sharpenedge"; - case Tool::SHARPEN_MICRO: - return "sharpenmicro"; - case Tool::L_CURVE: - return "labcurves"; - case Tool::RGB_CURVES: - return "rgbcurves"; - case Tool::COLOR_TONING: - return "colortoning"; - case Tool::LENS_GEOM: - return "lensgeom"; - case Tool::LENS_PROF: - return "lensprof"; - case Tool::DISTORTION: - return "distortion"; - case Tool::ROTATE: - return "rotate"; - case Tool::VIBRANCE: - return "vibrance"; - case Tool::COLOR_APPEARANCE: - return "colorappearance"; - case Tool::WHITE_BALANCE: - return "whitebalance"; - case Tool::VIGNETTING: - return "vignetting"; - case Tool::RETINEX_TOOL: - return "retinex"; - case Tool::GRADIENT: - return "gradient"; - case Tool::LOCALLAB: - return "locallab"; - case Tool::PC_VIGNETTE: - return "pcvignette"; - case Tool::PERSPECTIVE: - return "perspective"; - case Tool::CA_CORRECTION: - return "cacorrection"; - case Tool::CH_MIXER: - return "chmixer"; - case Tool::BLACK_WHITE: - return "blackwhite"; - case Tool::RESIZE_TOOL: - return "resize"; - case Tool::PR_SHARPENING: - return "prsharpening"; - case Tool::CROP_TOOL: - return "crop"; - case Tool::ICM: - return "icm"; - case Tool::WAVELET: - return "wavelet"; - case Tool::DIR_PYR_EQUALIZER: - return "dirpyrdenoise"; - case Tool::HSV_EQUALIZER: - return "hsvequalizer"; - case Tool::FILM_SIMULATION: - return "filmsimulation"; - case Tool::SOFT_LIGHT: - return "softlight"; - case Tool::DEHAZE: - return "dehaze"; - case Tool::SENSOR_BAYER: - return "sensorbayer"; - case Tool::SENSOR_XTRANS: - return "sensorxtrans"; - case Tool::BAYER_PROCESS: - return "bayerprocess"; - case Tool::XTRANS_PROCESS: - return "xtransprocess"; - case Tool::BAYER_PREPROCESS: - return "bayerpreprocess"; - case Tool::PREPROCESS: - return "preprocess"; - case Tool::DARKFRAME_TOOL: - return "darkframe"; - case Tool::FLATFIELD_TOOL: - return "flatfield"; - case Tool::RAW_CA_CORRECTION: - return "rawcacorrection"; - case Tool::RAW_EXPOSURE: - return "rawexposure"; - case Tool::PREPROCESS_WB: - return "preprocesswb"; - case Tool::BAYER_RAW_EXPOSURE: - return "bayerrawexposure"; - case Tool::XTRANS_RAW_EXPOSURE: - return "xtransrawexposure"; - case Tool::FATTAL: - return "fattal"; - case Tool::FILM_NEGATIVE: - return "filmnegative"; - case Tool::PD_SHARPENING: - return "capturesharpening"; - }; - assert(false); - return ""; -}; - /** * Returns the language key for the panel's title. */ @@ -591,13 +465,6 @@ struct ToolLocationPreference::Impl { * @param row_path Path to the tool list model row. */ void favoriteToggled(const Glib::ustring &row_path); - /** - * Gets the tool with the provided tool name. - * - * @param name The tool name as a raw string. - * @return The tool. - */ - Tool getToolFromName(const std::string &name) const; /** * Initializes the favorites list. * @@ -719,36 +586,6 @@ void ToolLocationPreference::Impl::favoriteToggled(const Glib::ustring &row_path } } -Tool ToolLocationPreference::Impl::getToolFromName(const std::string &name) const -{ - if (toolNamesReverseMap.empty()) { - // Create the name to tool mapping. - - const auto panels = ToolPanelCoordinator::getDefaultToolLayout(); - std::vector unprocessed_tool_trees; - - // Get the root tools from each panel. - for (const auto &panel_tools : panels) { - for (const auto &tool : panel_tools.second) { - unprocessed_tool_trees.push_back(&tool); - } - } - - // Process all the tools, including their children. - while (unprocessed_tool_trees.size() > 0) { - const ToolPanelCoordinator::ToolTree *tool_tree = - unprocessed_tool_trees.back(); - unprocessed_tool_trees.pop_back(); - toolNamesReverseMap[getToolName(tool_tree->id)] = tool_tree->id; - for (const auto &child_tree : tool_tree->children) { - unprocessed_tool_trees.push_back(&child_tree); - } - } - } - - return toolNamesReverseMap.at(name); -} - void ToolLocationPreference::Impl::initFavoritesRows( const std::vector &favorites) { @@ -833,7 +670,7 @@ std::vector ToolLocationPreference::Impl::toolNamesToTools( for (auto &&tool_name : tool_names) { Tool tool; try { - tool = getToolFromName(tool_name); + tool = ToolPanelCoordinator::getToolFromName(tool_name); } catch (const std::exception &e) { if (rtengine::settings->verbose) { std::cerr << "Unrecognized tool name \"" << tool_name << "\"." << std::endl; @@ -853,7 +690,7 @@ void ToolLocationPreference::Impl::updateOptions() options.favorites.resize(favorites_rows.size()); for (unsigned i = 0; i < favorites_rows.size(); i++) { const Tool tool = favorites_rows[i].get_value(favoritesColumns.tool); - options.favorites[i] = getToolName(tool); + options.favorites[i] = ToolPanelCoordinator::getToolName(tool); } } diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index cfc53639b..bf191133d 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -73,7 +73,14 @@ FoldableToolPanel::FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, exp->signal_button_release_event().connect_notify( sigc::mem_fun(this, &FoldableToolPanel::foldThemAll) ); enaConn = signal_enabled_toggled().connect( sigc::mem_fun(*this, &FoldableToolPanel::enabled_toggled) ); - exp->add (*content); + Gtk::Box *expanderContents = Gtk::manage( + new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + subToolsContainer = Gtk::manage( + new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + expanderContents->pack_start(*content, false, false, 0); + expanderContents->pack_start(*subToolsContainer, false, false, 0); + + exp->add(*expanderContents, false); exp->show (); } diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 8fdb4540d..ce14dc64f 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -98,6 +98,10 @@ public: { return nullptr; } + virtual Gtk::Box *getSubToolsContainer() const + { + return nullptr; + } virtual void setExpanded (bool expanded) {} virtual bool getExpanded () { @@ -164,6 +168,7 @@ class FoldableToolPanel : protected: Gtk::Box* parentContainer; MyExpander* exp; + Gtk::Box *subToolsContainer; bool lastEnabled; sigc::connection enaConn; void foldThemAll (GdkEventButton* event); @@ -177,6 +182,12 @@ public: { return exp; } + + Gtk::Box *getSubToolsContainer() const final + { + return subToolsContainer; + } + void setExpanded (bool expanded) final { if (exp) { diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index fa2203958..1b81fb014 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -267,6 +267,8 @@ const ToolPanelCoordinator::ToolLayout PANEL_TOOLS = { }, }; +std::unordered_map ToolPanelCoordinator::toolNamesReverseMap; + ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr), photoLoadedOnce(false) { @@ -345,71 +347,33 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit // Valeurs par dfaut: // Best -> low ISO // Medium -> High ISO - favorites.resize(options.favorites.size(), nullptr); - addfavoritePanel (colorPanel, whitebalance); - addfavoritePanel (exposurePanel, toneCurve); - addfavoritePanel (colorPanel, vibrance); - addfavoritePanel (colorPanel, chmixer); - addfavoritePanel (colorPanel, blackwhite); - addfavoritePanel (exposurePanel, shadowshighlights); - addfavoritePanel (detailsPanel, spot); - addfavoritePanel (detailsPanel, sharpening); - addfavoritePanel (detailsPanel, localContrast); - addfavoritePanel (detailsPanel, sharpenEdge); - addfavoritePanel (detailsPanel, sharpenMicro); - addfavoritePanel (colorPanel, hsvequalizer); - addfavoritePanel (colorPanel, filmSimulation); - addfavoritePanel (colorPanel, filmNegative); - addfavoritePanel (colorPanel, softlight); - addfavoritePanel (colorPanel, rgbcurves); - addfavoritePanel (colorPanel, colortoning); - addfavoritePanel (exposurePanel, epd); - addfavoritePanel (exposurePanel, fattal); - addfavoritePanel (advancedPanel, retinex); - addfavoritePanel (exposurePanel, pcvignette); - addfavoritePanel (exposurePanel, gradient); - addfavoritePanel (exposurePanel, lcurve); - addfavoritePanel (advancedPanel, colorappearance); - addfavoritePanel (detailsPanel, impulsedenoise); - addfavoritePanel (detailsPanel, dirpyrdenoise); - addfavoritePanel (detailsPanel, defringe); - addfavoritePanel (detailsPanel, dirpyrequalizer); - addfavoritePanel (detailsPanel, dehaze); - addfavoritePanel (advancedPanel, wavelet); - addfavoritePanel(locallabPanel, locallab); + for (const auto &panel_tool_layout : getDefaultToolLayout()) { + const auto &panel_tools = panel_tool_layout.second; + std::vector unprocessed_tools; - addfavoritePanel (transformPanel, crop); - addfavoritePanel (transformPanel, resize); - addPanel (resize->getPackBox(), prsharpening, 2); - addfavoritePanel (transformPanel, lensgeom); - addfavoritePanel (lensgeom->getPackBox(), rotate, 2); - addfavoritePanel (lensgeom->getPackBox(), perspective, 2); - addfavoritePanel (lensgeom->getPackBox(), lensProf, 2); - addfavoritePanel (lensgeom->getPackBox(), distortion, 2); - addfavoritePanel (lensgeom->getPackBox(), cacorrection, 2); - addfavoritePanel (lensgeom->getPackBox(), vignetting, 2); - addfavoritePanel (colorPanel, icm); - addfavoritePanel (rawPanel, sensorbayer); - addfavoritePanel (sensorbayer->getPackBox(), bayerprocess, 2); - addfavoritePanel (sensorbayer->getPackBox(), bayerrawexposure, 2); - addfavoritePanel (sensorbayer->getPackBox(), bayerpreprocess, 2); - addfavoritePanel (sensorbayer->getPackBox(), rawcacorrection, 2); - addfavoritePanel (rawPanel, sensorxtrans); - addfavoritePanel (sensorxtrans->getPackBox(), xtransprocess, 2); - addfavoritePanel (sensorxtrans->getPackBox(), xtransrawexposure, 2); - addfavoritePanel (rawPanel, rawexposure); - addfavoritePanel (rawPanel, preprocessWB); - addfavoritePanel (rawPanel, preprocess); - addfavoritePanel (rawPanel, darkframe); - addfavoritePanel (rawPanel, flatfield); - addfavoritePanel (rawPanel, pdSharpening); + // Start with the root tools for every panel. + for (const auto &tool_tree : panel_tools) { + unprocessed_tools.push_back(&tool_tree); + } - int favoriteCount = 0; - for(auto it = favorites.begin(); it != favorites.end(); ++it) { - if (*it) { - addPanel(favoritePanel, *it); - ++favoriteCount; + // Process each tool. + while (!unprocessed_tools.empty()) { + // Pop from stack of unprocessed. + const ToolTree *cur_tool = unprocessed_tools.back(); + unprocessed_tools.pop_back(); + // Add tool to list of expanders and tool panels. + FoldableToolPanel *tool_panel = getFoldableToolPanel(*cur_tool); + expList.push_back(tool_panel->getExpander()); + toolPanels.push_back(tool_panel); + expanderToToolPanelMap[tool_panel->getExpander()] = tool_panel; + toolToDefaultToolTreeMap[cur_tool->id] = cur_tool; + // Show all now, since they won't be attached to a parent. + tool_panel->getExpander()->show_all(); + // Add children to unprocessed. + for (const auto &child_tool : cur_tool->children) { + unprocessed_tools.push_back(&child_tool); + } } } @@ -418,6 +382,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit toolPanelNotebook = new Gtk::Notebook(); toolPanelNotebook->set_name("ToolPanelNotebook"); + favoritePanelSW.reset(new MyScrolledWindow()); exposurePanelSW = Gtk::manage (new MyScrolledWindow ()); detailsPanelSW = Gtk::manage (new MyScrolledWindow ()); colorPanelSW = Gtk::manage (new MyScrolledWindow ()); @@ -434,35 +399,58 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit vbPanelEnd[i]->pack_start(*imgPanelEnd[i], Gtk::PACK_SHRINK); vbPanelEnd[i]->show_all(); } - if(favoriteCount > 0) { - favoritePanelSW = Gtk::manage(new MyScrolledWindow()); - favoritePanelSW->add(*favoritePanel); - favoritePanel->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); - } updateVScrollbars(options.hideTPVScrollbar); - exposurePanelSW->add (*exposurePanel); - exposurePanel->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK, 4); + Gtk::Box *favoritePanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *exposurePanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *detailsPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *colorPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *advancedPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *locallabPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *transformPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + Gtk::Box *rawPanelContainer = + Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - detailsPanelSW->add (*detailsPanel); - detailsPanel->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK, 4); + favoritePanelSW->add(*favoritePanelContainer); + favoritePanelContainer->pack_start(*favoritePanel, Gtk::PACK_SHRINK, 0); + favoritePanelContainer->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); - colorPanelSW->add (*colorPanel); - colorPanel->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK, 4); + exposurePanelSW->add (*exposurePanelContainer); + exposurePanelContainer->pack_start(*exposurePanel, Gtk::PACK_SHRINK, 0); + exposurePanelContainer->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK, 4); - advancedPanelSW->add (*advancedPanel); - advancedPanel->pack_start (*vbPanelEnd[6], Gtk::PACK_SHRINK, 0); + detailsPanelSW->add (*detailsPanelContainer); + detailsPanelContainer->pack_start(*detailsPanel, Gtk::PACK_SHRINK, 0); + detailsPanelContainer->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK, 4); - locallabPanelSW->add(*locallabPanel); - locallabPanel->pack_start(*vbPanelEnd[7], Gtk::PACK_SHRINK, 4); + colorPanelSW->add (*colorPanelContainer); + colorPanelContainer->pack_start(*colorPanel, Gtk::PACK_SHRINK, 0); + colorPanelContainer->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK, 4); - transformPanelSW->add (*transformPanel); - transformPanel->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 4); + advancedPanelSW->add (*advancedPanelContainer); + advancedPanelContainer->pack_start(*advancedPanel, Gtk::PACK_SHRINK, 0); + advancedPanelContainer->pack_start (*vbPanelEnd[6], Gtk::PACK_SHRINK, 0); - rawPanelSW->add (*rawPanel); - rawPanel->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0); + locallabPanelSW->add(*locallabPanelContainer); + locallabPanelContainer->pack_start(*locallabPanel, Gtk::PACK_SHRINK, 0); + locallabPanelContainer->pack_start(*vbPanelEnd[7], Gtk::PACK_SHRINK, 4); - toiF = Gtk::manage (new TextOrIcon ("star.png", M ("MAIN_TAB_FAVORITES"), M ("MAIN_TAB_FAVORITES_TOOLTIP"))); + transformPanelSW->add (*transformPanelContainer); + transformPanelContainer->pack_start(*transformPanel, Gtk::PACK_SHRINK, 0); + transformPanelContainer->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 4); + + rawPanelSW->add (*rawPanelContainer); + rawPanelContainer->pack_start(*rawPanel, Gtk::PACK_SHRINK, 0); + rawPanelContainer->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0); + + toiF.reset(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"))); @@ -472,9 +460,6 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit 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"))); - if (favoritePanelSW) { - toolPanelNotebook->append_page (*favoritePanelSW, *toiF); - } toolPanelNotebook->append_page (*exposurePanelSW, *toiE); toolPanelNotebook->append_page (*detailsPanelSW, *toiD); toolPanelNotebook->append_page (*colorPanelSW, *toiC); @@ -491,6 +476,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit toolPanelNotebook->set_scrollable(); toolPanelNotebook->show_all(); + updateToolLocations(options.favorites); notebookconn = toolPanelNotebook->signal_switch_page().connect( sigc::mem_fun(*this, &ToolPanelCoordinator::notebookPageChanged)); @@ -528,6 +514,156 @@ const ToolPanelCoordinator::ToolLayout& ToolPanelCoordinator::getDefaultToolLayo return PANEL_TOOLS; } +Tool ToolPanelCoordinator::getToolFromName(const std::string &name) +{ + if (toolNamesReverseMap.empty()) { + // Create the name to tool mapping. + + const auto panels = ToolPanelCoordinator::getDefaultToolLayout(); + std::vector unprocessed_tool_trees; + + // Get the root tools from each panel. + for (const auto &panel_tools : panels) { + for (const auto &tool : panel_tools.second) { + unprocessed_tool_trees.push_back(&tool); + } + } + + // Process all the tools, including their children. + while (unprocessed_tool_trees.size() > 0) { + const ToolPanelCoordinator::ToolTree *tool_tree = + unprocessed_tool_trees.back(); + unprocessed_tool_trees.pop_back(); + toolNamesReverseMap[getToolName(tool_tree->id)] = tool_tree->id; + for (const auto &child_tree : tool_tree->children) { + unprocessed_tool_trees.push_back(&child_tree); + } + } + } + + return toolNamesReverseMap.at(name); +} + +std::string ToolPanelCoordinator::getToolName(Tool tool) +{ + switch (tool) { + case Tool::TONE_CURVE: + return "tonecurve"; + case Tool::SHADOWS_HIGHLIGHTS: + return "shadowshighlights"; + case Tool::IMPULSE_DENOISE: + return "impulsedenoise"; + case Tool::DEFRINGE_TOOL: + return "defringe"; + case Tool::SPOT: + return "spot"; + case Tool::DIR_PYR_DENOISE: + return "dirpyrdenoise"; + case Tool::EPD: + return "epd"; + case Tool::SHARPENING_TOOL: + return "sharpening"; + case Tool::LOCAL_CONTRAST: + return "localcontrast"; + case Tool::SHARPEN_EDGE: + return "sharpenedge"; + case Tool::SHARPEN_MICRO: + return "sharpenmicro"; + case Tool::L_CURVE: + return "labcurves"; + case Tool::RGB_CURVES: + return "rgbcurves"; + case Tool::COLOR_TONING: + return "colortoning"; + case Tool::LENS_GEOM: + return "lensgeom"; + case Tool::LENS_PROF: + return "lensprof"; + case Tool::DISTORTION: + return "distortion"; + case Tool::ROTATE: + return "rotate"; + case Tool::VIBRANCE: + return "vibrance"; + case Tool::COLOR_APPEARANCE: + return "colorappearance"; + case Tool::WHITE_BALANCE: + return "whitebalance"; + case Tool::VIGNETTING: + return "vignetting"; + case Tool::RETINEX_TOOL: + return "retinex"; + case Tool::GRADIENT: + return "gradient"; + case Tool::LOCALLAB: + return "locallab"; + case Tool::PC_VIGNETTE: + return "pcvignette"; + case Tool::PERSPECTIVE: + return "perspective"; + case Tool::CA_CORRECTION: + return "cacorrection"; + case Tool::CH_MIXER: + return "chmixer"; + case Tool::BLACK_WHITE: + return "blackwhite"; + case Tool::RESIZE_TOOL: + return "resize"; + case Tool::PR_SHARPENING: + return "prsharpening"; + case Tool::CROP_TOOL: + return "crop"; + case Tool::ICM: + return "icm"; + case Tool::WAVELET: + return "wavelet"; + case Tool::DIR_PYR_EQUALIZER: + return "dirpyrdenoise"; + case Tool::HSV_EQUALIZER: + return "hsvequalizer"; + case Tool::FILM_SIMULATION: + return "filmsimulation"; + case Tool::SOFT_LIGHT: + return "softlight"; + case Tool::DEHAZE: + return "dehaze"; + case Tool::SENSOR_BAYER: + return "sensorbayer"; + case Tool::SENSOR_XTRANS: + return "sensorxtrans"; + case Tool::BAYER_PROCESS: + return "bayerprocess"; + case Tool::XTRANS_PROCESS: + return "xtransprocess"; + case Tool::BAYER_PREPROCESS: + return "bayerpreprocess"; + case Tool::PREPROCESS: + return "preprocess"; + case Tool::DARKFRAME_TOOL: + return "darkframe"; + case Tool::FLATFIELD_TOOL: + return "flatfield"; + case Tool::RAW_CA_CORRECTION: + return "rawcacorrection"; + case Tool::RAW_EXPOSURE: + return "rawexposure"; + case Tool::PREPROCESS_WB: + return "preprocesswb"; + case Tool::BAYER_RAW_EXPOSURE: + return "bayerrawexposure"; + case Tool::XTRANS_RAW_EXPOSURE: + return "xtransrawexposure"; + case Tool::FATTAL: + return "fattal"; + case Tool::FILM_NEGATIVE: + return "filmnegative"; + case Tool::PD_SHARPENING: + return "capturesharpening"; + }; + assert(false); + return ""; +}; + bool ToolPanelCoordinator::isFavoritable(Tool tool) { switch (tool) { @@ -540,6 +676,8 @@ bool ToolPanelCoordinator::isFavoritable(Tool tool) void ToolPanelCoordinator::notebookPageChanged(Gtk::Widget* page, guint page_num) { + updatePanelTools(page, options.favorites); + // Locallab spot curves are set visible if at least one photo has been loaded (to avoid // segfault) and locallab panel is active if (photoLoadedOnce) { @@ -557,26 +695,140 @@ void ToolPanelCoordinator::notebookPageChanged(Gtk::Widget* page, guint page_num } } +void ToolPanelCoordinator::updateFavoritesPanel( + const std::vector &favoritesNames) +{ + std::unordered_set favorites_set; + std::vector> favorites_tool_tree; + + for (const auto &tool_name : favoritesNames) { + Tool tool = getToolFromName(tool_name.raw()); + favorites_set.insert(tool); + favorites_tool_tree.push_back( + std::ref(*(toolToDefaultToolTreeMap.at(tool)))); + } + + updateToolPanel(favoritePanel, favorites_tool_tree, 1, favorites_set); +} + +void ToolPanelCoordinator::updatePanelTools( + Gtk::Widget *page, const std::vector &favorites) +{ + if (page == favoritePanelSW.get()) { + updateFavoritesPanel(favorites); + return; + } + + ToolVBox *panel = nullptr; + const std::vector *default_panel_tools = nullptr; + if (page == exposurePanelSW) { + panel = exposurePanel; + default_panel_tools = &EXPOSURE_PANEL_TOOLS; + } else if (page == detailsPanelSW) { + panel = detailsPanel; + default_panel_tools = &DETAILS_PANEL_TOOLS; + } else if (page == colorPanelSW) { + panel = colorPanel; + default_panel_tools = &COLOR_PANEL_TOOLS; + } else if (page == transformPanelSW) { + panel = transformPanel; + default_panel_tools = &TRANSFORM_PANEL_TOOLS; + } else if (page == rawPanelSW) { + panel = rawPanel; + default_panel_tools = &RAW_PANEL_TOOLS; + } else if (page == advancedPanelSW) { + panel = advancedPanel; + default_panel_tools = &ADVANCED_PANEL_TOOLS; + } else if (page == locallabPanelSW) { + panel = locallabPanel; + default_panel_tools = &LOCALLAB_PANEL_TOOLS; + } else { + return; + } + assert(panel && default_panel_tools); + + std::unordered_set favoriteTools; + for (const auto &tool_name : favorites) { + favoriteTools.insert(getToolFromName(tool_name.raw())); + } + + updateToolPanel(panel, *default_panel_tools, 1, favoriteTools); +} + +template +typename std::enable_if::value, void>::type +ToolPanelCoordinator::updateToolPanel( + Gtk::Box *panelBox, + const std::vector &children, + int level, + std::unordered_set favorites) +{ + const bool is_favorite_panel = panelBox == favoritePanel; + const std::vector old_tool_panels = panelBox->get_children(); + auto old_widgets_iter = old_tool_panels.begin(); + auto new_tool_trees_iter = children.begin(); + + // Indicates if this tool should not be added. Favorite tools are skipped + // unless the parent panel box is the favorites panel. + const auto should_skip_tool = + [is_favorite_panel, &favorites](const ToolTree &tool_tree) { + return !is_favorite_panel && favorites.count(tool_tree.id); + }; + + // Keep tools that are already correct. + while ( + old_widgets_iter != old_tool_panels.end() && + new_tool_trees_iter != children.end()) { + if (should_skip_tool(*new_tool_trees_iter)) { + ++new_tool_trees_iter; + continue; + } + if (*old_widgets_iter != + getFoldableToolPanel(*new_tool_trees_iter)->getExpander()) { + break; + } + ++old_widgets_iter; + } + + // Remove incorrect tools. + for (auto iter = old_tool_panels.end(); iter != old_widgets_iter;) { + --iter; + FoldableToolPanel *old_tool_panel = expanderToToolPanelMap.at(*iter); + assert(*iter == old_tool_panel->getExpander()); + panelBox->remove(**iter); + old_tool_panel->setParent(nullptr); + } + + // Add correct tools. + for (; new_tool_trees_iter != children.end(); new_tool_trees_iter++) { + if (should_skip_tool(*new_tool_trees_iter)) { + continue; + } + FoldableToolPanel *tool_panel = + getFoldableToolPanel(*new_tool_trees_iter); + if (tool_panel->getParent()) { + tool_panel->getParent()->remove(*tool_panel->getExpander()); + } + addPanel(panelBox, tool_panel, level); + } + + // Update the child tools. + for (const ToolTree &tool_tree : children) { + const FoldableToolPanel *tool_panel = getFoldableToolPanel(tool_tree); + updateToolPanel( + tool_panel->getSubToolsContainer(), + tool_tree.children, + level + 1, + favorites); + } +} + void ToolPanelCoordinator::addPanel(Gtk::Box* where, FoldableToolPanel* panel, int level) { panel->setParent(where); panel->setLevel(level); - - expList.push_back(panel->getExpander()); where->pack_start(*panel->getExpander(), false, false); - toolPanels.push_back(panel); -} -void ToolPanelCoordinator::addfavoritePanel (Gtk::Box* where, FoldableToolPanel* panel, int level) -{ - auto name = panel->getToolName(); - auto it = std::find(options.favorites.begin(), options.favorites.end(), name); - if (it != options.favorites.end()) { - int index = std::distance(options.favorites.begin(), it); - favorites[index] = panel; - } else { - addPanel(where, panel, level); - } } ToolPanelCoordinator::~ToolPanelCoordinator () @@ -1366,6 +1618,30 @@ void ToolPanelCoordinator::foldAllButOne(Gtk::Box* parent, FoldableToolPanel* op } } +void ToolPanelCoordinator::updateToolLocations(const std::vector &favorites) +{ + const int fav_page_num = toolPanelNotebook->page_num(*favoritePanelSW); + + // Add or remove favorites tab if necessary. + if (favorites.empty() && fav_page_num != -1) { + toolPanelNotebook->remove_page(fav_page_num); + } else if (!favorites.empty() && fav_page_num == -1) { + toolPanelNotebook->prepend_page(*favoritePanelSW, *toiF); + } + + // Update favorite tool panels list. + favoritesToolPanels.clear(); + for (const auto &favorite_name : favorites) { + favoritesToolPanels.push_back( + getFoldableToolPanel(getToolFromName(favorite_name))); + } + + int cur_page_num = toolPanelNotebook->get_current_page(); + Gtk::Widget *const cur_page = toolPanelNotebook->get_nth_page(cur_page_num); + + updatePanelTools(cur_page, favorites); +} + bool ToolPanelCoordinator::handleShortcutKey(GdkEventKey* event) { @@ -1376,7 +1652,7 @@ bool ToolPanelCoordinator::handleShortcutKey(GdkEventKey* event) if (alt) { switch (event->keyval) { case GDK_KEY_u: - if (favoritePanelSW) { + if (toolPanelNotebook->page_num(*favoritePanelSW) >= 0) { toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*favoritePanelSW)); } return true; @@ -1422,9 +1698,7 @@ void ToolPanelCoordinator::updateVScrollbars(bool hide) { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected Gtk::PolicyType policy = hide ? Gtk::POLICY_NEVER : Gtk::POLICY_AUTOMATIC; - if (favoritePanelSW) { - favoritePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); - } + favoritePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); exposurePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); detailsPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); colorPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); @@ -1456,7 +1730,7 @@ void ToolPanelCoordinator::toolSelected(ToolMode tool) notebookconn.block(true); // "signal_switch_page" event is blocked to avoid unsubscribing Locallab (allows a correct behavior when switching to another tool using toolbar) auto checkFavorite = [this](FoldableToolPanel* tool) { - for (auto fav : favorites) { + for (auto fav : favoritesToolPanels) { if (fav == tool) { return true; } @@ -1512,6 +1786,8 @@ void ToolPanelCoordinator::toolSelected(ToolMode tool) break; } + updateToolLocations(options.favorites); + notebookconn.block(false); } @@ -1541,3 +1817,127 @@ bool ToolPanelCoordinator::getFilmNegativeSpot(rtengine::Coord spot, int spotSiz { return ipc && ipc->getFilmNegativeSpot(spot.x, spot.y, spotSize, refInput, refOutput); } + +FoldableToolPanel *ToolPanelCoordinator::getFoldableToolPanel(Tool tool) const +{ + switch (tool) { + case Tool::TONE_CURVE: + return toneCurve; + case Tool::SHADOWS_HIGHLIGHTS: + return shadowshighlights; + case Tool::IMPULSE_DENOISE: + return impulsedenoise; + case Tool::DEFRINGE_TOOL: + return defringe; + case Tool::SPOT: + return spot; + case Tool::DIR_PYR_DENOISE: + return dirpyrdenoise; + case Tool::EPD: + return epd; + case Tool::SHARPENING_TOOL: + return sharpening; + case Tool::LOCAL_CONTRAST: + return localContrast; + case Tool::SHARPEN_EDGE: + return sharpenEdge; + case Tool::SHARPEN_MICRO: + return sharpenMicro; + case Tool::L_CURVE: + return lcurve; + case Tool::RGB_CURVES: + return rgbcurves; + case Tool::COLOR_TONING: + return colortoning; + case Tool::LENS_GEOM: + return lensgeom; + case Tool::LENS_PROF: + return lensProf; + case Tool::DISTORTION: + return distortion; + case Tool::ROTATE: + return rotate; + case Tool::VIBRANCE: + return vibrance; + case Tool::COLOR_APPEARANCE: + return colorappearance; + case Tool::WHITE_BALANCE: + return whitebalance; + case Tool::VIGNETTING: + return vignetting; + case Tool::RETINEX_TOOL: + return retinex; + case Tool::GRADIENT: + return gradient; + case Tool::LOCALLAB: + return locallab; + case Tool::PC_VIGNETTE: + return pcvignette; + case Tool::PERSPECTIVE: + return perspective; + case Tool::CA_CORRECTION: + return cacorrection; + case Tool::CH_MIXER: + return chmixer; + case Tool::BLACK_WHITE: + return blackwhite; + case Tool::RESIZE_TOOL: + return resize; + case Tool::PR_SHARPENING: + return prsharpening; + case Tool::CROP_TOOL: + return crop; + case Tool::ICM: + return icm; + case Tool::WAVELET: + return wavelet; + case Tool::DIR_PYR_EQUALIZER: + return dirpyrequalizer; + case Tool::HSV_EQUALIZER: + return hsvequalizer; + case Tool::FILM_SIMULATION: + return filmSimulation; + case Tool::SOFT_LIGHT: + return softlight; + case Tool::DEHAZE: + return dehaze; + case Tool::SENSOR_BAYER: + return sensorbayer; + case Tool::SENSOR_XTRANS: + return sensorxtrans; + case Tool::BAYER_PROCESS: + return bayerprocess; + case Tool::XTRANS_PROCESS: + return xtransprocess; + case Tool::BAYER_PREPROCESS: + return bayerpreprocess; + case Tool::PREPROCESS: + return preprocess; + case Tool::DARKFRAME_TOOL: + return darkframe; + case Tool::FLATFIELD_TOOL: + return flatfield; + case Tool::RAW_CA_CORRECTION: + return rawcacorrection; + case Tool::RAW_EXPOSURE: + return rawexposure; + case Tool::PREPROCESS_WB: + return preprocessWB; + case Tool::BAYER_RAW_EXPOSURE: + return bayerrawexposure; + case Tool::XTRANS_RAW_EXPOSURE: + return xtransrawexposure; + case Tool::FATTAL: + return fattal; + case Tool::FILM_NEGATIVE: + return filmNegative; + case Tool::PD_SHARPENING: + return pdSharpening; + }; + return nullptr; +} + +FoldableToolPanel *ToolPanelCoordinator::getFoldableToolPanel(const ToolTree &toolTree) const +{ + return getFoldableToolPanel(toolTree.id); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 94e5a8717..3182d3e16 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include @@ -169,11 +170,13 @@ protected: FilmNegative* filmNegative; PdSharpening* pdSharpening; std::vector paramcListeners; + std::unordered_map + expanderToToolPanelMap; rtengine::StagedImageProcessor* ipc; std::vector toolPanels; - std::vector favorites; + std::vector favoritesToolPanels; ToolVBox* favoritePanel; ToolVBox* exposurePanel; ToolVBox* detailsPanel; @@ -184,7 +187,7 @@ protected: ToolVBox* locallabPanel; ToolBar* toolBar; - TextOrIcon* toiF; + std::unique_ptr toiF; TextOrIcon* toiE; TextOrIcon* toiD; TextOrIcon* toiC; @@ -197,7 +200,7 @@ protected: Gtk::Image* imgPanelEnd[8]; Gtk::Box* vbPanelEnd[8]; - Gtk::ScrolledWindow* favoritePanelSW; + std::unique_ptr favoritePanelSW; Gtk::ScrolledWindow* exposurePanelSW; Gtk::ScrolledWindow* detailsPanelSW; Gtk::ScrolledWindow* colorPanelSW; @@ -215,6 +218,8 @@ protected: void updateVScrollbars(bool hide); void addfavoritePanel (Gtk::Box* where, FoldableToolPanel* panel, int level = 1); void notebookPageChanged(Gtk::Widget* page, guint page_num); + void updatePanelTools( + Gtk::Widget *page, const std::vector &favorites); private: EditDataProvider *editDataProvider; @@ -307,6 +312,20 @@ public: ~ToolPanelCoordinator () override; static const ToolLayout& getDefaultToolLayout(); + /** + * Gets the tool with the provided tool name. + * + * @param name The tool name as a raw string. + * @return The tool. + */ + static Tool getToolFromName(const std::string &name); + /** + * Gets the tool name for the tool's ToolPanel as a string. + * + * @param tool The name as a raw string, or an empty string if the tool is + * unknown. + */ + static std::string getToolName(Tool tool); static bool isFavoritable(Tool tool); bool getChangedState() @@ -326,6 +345,7 @@ public: const LUTu& histLRETI ); void foldAllButOne(Gtk::Box* parent, FoldableToolPanel* openedSection); + void updateToolLocations(const std::vector &favorites); // multiple listeners can be added that are notified on changes (typical: profile panel and the history) void addPParamsChangeListener(PParamsChangeListener* pp) @@ -433,6 +453,23 @@ public: void setEditProvider(EditDataProvider *provider); +protected: + static std::unordered_map toolNamesReverseMap; + + std::unordered_map + toolToDefaultToolTreeMap; + + FoldableToolPanel *getFoldableToolPanel(Tool tool) const; + FoldableToolPanel *getFoldableToolPanel(const ToolTree &tool) const; + void updateFavoritesPanel(const std::vector &favorites); + template + typename std::enable_if::value, void>::type + updateToolPanel( + Gtk::Box *panelBox, + const std::vector &children, + int level, + std::unordered_set favorites); + private: IdleRegister idle_register; }; From acda4da22633983b9c72b1fdb046f3aecb87cdd8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 5 Dec 2021 18:07:10 -0800 Subject: [PATCH 043/326] Fix favorites panel not being added Favorites panel would not show after adding tools to the favorites panel if the program started with no favorites. --- rtgui/toolpanelcoord.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 1b81fb014..985fb5461 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -421,6 +421,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit favoritePanelSW->add(*favoritePanelContainer); favoritePanelContainer->pack_start(*favoritePanel, Gtk::PACK_SHRINK, 0); favoritePanelContainer->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); + favoritePanelSW->show_all(); exposurePanelSW->add (*exposurePanelContainer); exposurePanelContainer->pack_start(*exposurePanel, Gtk::PACK_SHRINK, 0); @@ -460,6 +461,10 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit 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"))); + toiF->show_all(); + if (options.favorites.size()) { + toolPanelNotebook->append_page(*favoritePanelSW, *toiF); + } toolPanelNotebook->append_page (*exposurePanelSW, *toiE); toolPanelNotebook->append_page (*detailsPanelSW, *toiD); toolPanelNotebook->append_page (*colorPanelSW, *toiC); From f8a1deb371737971d61e494a23b5d37708517564 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 9 Dec 2021 21:27:39 -0800 Subject: [PATCH 044/326] Add option to clone favorite tools If cloning is enabled, favorite tools will appear in the favorites panel and in the original location. --- rtdata/languages/default | 1 + rtgui/editorpanel.cc | 4 ++-- rtgui/editorpanel.h | 3 ++- rtgui/options.cc | 6 ++++++ rtgui/options.h | 1 + rtgui/preferences.cc | 6 ++++-- rtgui/rtwindow.cc | 4 ++-- rtgui/rtwindow.h | 3 ++- rtgui/toollocationpref.cc | 16 ++++++++++++++++ rtgui/toolpanelcoord.cc | 39 ++++++++++++++++++++++++--------------- rtgui/toolpanelcoord.h | 13 +++++++++---- 11 files changed, 69 insertions(+), 27 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 525fa2d09..bd65781a8 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1901,6 +1901,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_TOOLPANEL_AVAILABLETOOLS;Available Tools +PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations PREFERENCES_TOOLPANEL_FAVORITE;Favorite PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel PREFERENCES_TOOLPANEL_TOOL;Tool diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 888fc9518..64fa50a6a 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2487,10 +2487,10 @@ void EditorPanel::updateHistogramPosition (int oldPosition, int newPosition) } void EditorPanel::updateToolPanelToolLocations( - const std::vector &favorites) + const std::vector &favorites, bool cloneFavoriteTools) { if (tpc) { - tpc->updateToolLocations(favorites); + tpc->updateToolLocations(favorites, cloneFavoriteTools); } } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 0ffe44ace..bb0ecbc89 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -185,7 +185,8 @@ public: void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); void updateTPVScrollbar (bool hide); void updateHistogramPosition (int oldPosition, int newPosition); - void updateToolPanelToolLocations(const std::vector &favorites); + void updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools); void defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile); diff --git a/rtgui/options.cc b/rtgui/options.cc index 70b0fa010..b5463949a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -424,6 +424,7 @@ void Options::setDefaults() //crvOpen.clear (); parseExtensions.clear(); favorites.clear(); + cloneFavoriteTools = true; parseExtensionsEnabled.clear(); parsedExtensions.clear(); parsedExtensionsSet.clear(); @@ -1220,6 +1221,10 @@ void Options::readFromFile(Glib::ustring fname) favorites = keyFile.get_string_list("GUI", "Favorites"); } + if (keyFile.has_key("GUI", "FavoritesCloneTools")) { + cloneFavoriteTools = keyFile.get_boolean("GUI", "FavoritesCloneTools"); + } + if (keyFile.has_key("GUI", "WindowWidth")) { windowWidth = keyFile.get_integer("GUI", "WindowWidth"); } @@ -2261,6 +2266,7 @@ void Options::saveToFile(Glib::ustring fname) Glib::ArrayHandle ahfavorites = favorites; keyFile.set_string_list("GUI", "Favorites", ahfavorites); + keyFile.set_boolean("GUI", "FavoritesCloneTools", cloneFavoriteTools); keyFile.set_integer("GUI", "WindowWidth", windowWidth); keyFile.set_integer("GUI", "WindowHeight", windowHeight); keyFile.set_integer("GUI", "WindowX", windowX); diff --git a/rtgui/options.h b/rtgui/options.h index bc5e41c91..6f21d1d76 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -428,6 +428,7 @@ public: bool fastexport_use_fast_pipeline; std::vector favorites; + bool cloneFavoriteTools; // Dialog settings Glib::ustring lastIccDir; Glib::ustring lastDarkframeDir; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index e67d16015..493f84f5a 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2572,8 +2572,10 @@ void Preferences::workflowUpdate() parent->updateProfiles (moptions.rtSettings.printerProfile, rtengine::RenderingIntent(moptions.rtSettings.printerIntent), moptions.rtSettings.printerBPC); } - if (moptions.favorites != options.favorites) { - parent->updateToolPanelToolLocations(moptions.favorites); + if (moptions.cloneFavoriteTools != options.cloneFavoriteTools || + moptions.favorites != options.favorites) { + parent->updateToolPanelToolLocations( + moptions.favorites, moptions.cloneFavoriteTools); } } diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 15715a2fd..f3eb658e5 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -1111,10 +1111,10 @@ void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) } void RTWindow::updateToolPanelToolLocations( - const std::vector &favorites) + const std::vector &favorites, bool cloneFavoriteTools) { if (epanel) { - epanel->updateToolPanelToolLocations(favorites); + epanel->updateToolPanelToolLocations(favorites, cloneFavoriteTools); } } diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index d35755185..0ef5abb1f 100755 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -124,7 +124,8 @@ public: void updateFBQueryTB (bool singleRow); void updateFBToolBarVisibility (bool showFilmStripToolBar); void updateShowtooltipVisibility (bool showtooltip); - void updateToolPanelToolLocations(const std::vector &favorites); + void updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools); bool getIsFullscreen() { return is_fullscreen; diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 561be4601..849ff29b6 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -423,6 +423,9 @@ struct ToolLocationPreference::Impl { Options &options; + // General options. + Gtk::CheckButton *cloneFavoriteToolsToggleWidget; + // Tool list. ToolListColumns toolListColumns; Glib::RefPtr toolListModelPtr; @@ -506,6 +509,10 @@ std::unordered_map ToolLocationPreference::Impl::Impl(Options &options) : options(options), + // General options. + cloneFavoriteToolsToggleWidget(Gtk::manage( + new Gtk::CheckButton(M("PREFERENCES_TOOLPANEL_CLONE_FAVORITES")))), + // Tool list. toolListModelPtr(Gtk::TreeStore::create(toolListColumns)), toolListViewColumnFavorite( @@ -523,6 +530,9 @@ ToolLocationPreference::Impl::Impl(Options &options) : { const std::vector favorites = toolNamesToTools(options.favorites); + // General options. + cloneFavoriteToolsToggleWidget->set_active(options.cloneFavoriteTools); + // Tool list. toolListViewPtr->append_column(toolListViewColumnToolName); toolListViewColumnToolName.pack_start(toolListCellRendererToolName); @@ -686,6 +696,8 @@ std::vector ToolLocationPreference::Impl::toolNamesToTools( void ToolLocationPreference::Impl::updateOptions() { + options.cloneFavoriteTools = cloneFavoriteToolsToggleWidget->get_active(); + const auto favorites_rows = favoritesModelPtr->children(); options.favorites.resize(favorites_rows.size()); for (unsigned i = 0; i < favorites_rows.size(); i++) { @@ -729,6 +741,10 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( favorites_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); + + // General options. + layout_grid->attach_next_to( + *impl->cloneFavoriteToolsToggleWidget, Gtk::PositionType::POS_BOTTOM, 2, 1); } void ToolLocationPreference::updateOptions() diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 985fb5461..4991e68d8 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -481,7 +481,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit toolPanelNotebook->set_scrollable(); toolPanelNotebook->show_all(); - updateToolLocations(options.favorites); + updateToolLocations(options.favorites, options.cloneFavoriteTools); notebookconn = toolPanelNotebook->signal_switch_page().connect( sigc::mem_fun(*this, &ToolPanelCoordinator::notebookPageChanged)); @@ -681,7 +681,7 @@ bool ToolPanelCoordinator::isFavoritable(Tool tool) void ToolPanelCoordinator::notebookPageChanged(Gtk::Widget* page, guint page_num) { - updatePanelTools(page, options.favorites); + updatePanelTools(page, options.favorites, options.cloneFavoriteTools); // Locallab spot curves are set visible if at least one photo has been loaded (to avoid // segfault) and locallab panel is active @@ -701,7 +701,8 @@ void ToolPanelCoordinator::notebookPageChanged(Gtk::Widget* page, guint page_num } void ToolPanelCoordinator::updateFavoritesPanel( - const std::vector &favoritesNames) + const std::vector &favoritesNames, + bool cloneFavoriteTools) { std::unordered_set favorites_set; std::vector> favorites_tool_tree; @@ -713,14 +714,17 @@ void ToolPanelCoordinator::updateFavoritesPanel( std::ref(*(toolToDefaultToolTreeMap.at(tool)))); } - updateToolPanel(favoritePanel, favorites_tool_tree, 1, favorites_set); + updateToolPanel( + favoritePanel, favorites_tool_tree, 1, favorites_set, cloneFavoriteTools); } void ToolPanelCoordinator::updatePanelTools( - Gtk::Widget *page, const std::vector &favorites) + Gtk::Widget *page, + const std::vector &favorites, + bool cloneFavoriteTools) { if (page == favoritePanelSW.get()) { - updateFavoritesPanel(favorites); + updateFavoritesPanel(favorites, cloneFavoriteTools); return; } @@ -757,7 +761,7 @@ void ToolPanelCoordinator::updatePanelTools( favoriteTools.insert(getToolFromName(tool_name.raw())); } - updateToolPanel(panel, *default_panel_tools, 1, favoriteTools); + updateToolPanel(panel, *default_panel_tools, 1, favoriteTools, cloneFavoriteTools); } template @@ -766,18 +770,21 @@ ToolPanelCoordinator::updateToolPanel( Gtk::Box *panelBox, const std::vector &children, int level, - std::unordered_set favorites) + std::unordered_set favorites, + bool cloneFavoriteTools) { const bool is_favorite_panel = panelBox == favoritePanel; + const bool skip_favorites = !cloneFavoriteTools && !is_favorite_panel; const std::vector old_tool_panels = panelBox->get_children(); auto old_widgets_iter = old_tool_panels.begin(); auto new_tool_trees_iter = children.begin(); // Indicates if this tool should not be added. Favorite tools are skipped - // unless the parent panel box is the favorites panel. + // if they are sub-tools within the favorites panel, or if tool cloning is + // off and they are not within the favorites panel. const auto should_skip_tool = - [is_favorite_panel, &favorites](const ToolTree &tool_tree) { - return !is_favorite_panel && favorites.count(tool_tree.id); + [skip_favorites, &favorites](const ToolTree &tool_tree) { + return skip_favorites && favorites.count(tool_tree.id); }; // Keep tools that are already correct. @@ -824,7 +831,8 @@ ToolPanelCoordinator::updateToolPanel( tool_panel->getSubToolsContainer(), tool_tree.children, level + 1, - favorites); + favorites, + cloneFavoriteTools && !is_favorite_panel); } } @@ -1623,7 +1631,8 @@ void ToolPanelCoordinator::foldAllButOne(Gtk::Box* parent, FoldableToolPanel* op } } -void ToolPanelCoordinator::updateToolLocations(const std::vector &favorites) +void ToolPanelCoordinator::updateToolLocations( + const std::vector &favorites, bool cloneFavoriteTools) { const int fav_page_num = toolPanelNotebook->page_num(*favoritePanelSW); @@ -1644,7 +1653,7 @@ void ToolPanelCoordinator::updateToolLocations(const std::vector int cur_page_num = toolPanelNotebook->get_current_page(); Gtk::Widget *const cur_page = toolPanelNotebook->get_nth_page(cur_page_num); - updatePanelTools(cur_page, favorites); + updatePanelTools(cur_page, favorites, cloneFavoriteTools); } bool ToolPanelCoordinator::handleShortcutKey(GdkEventKey* event) @@ -1791,7 +1800,7 @@ void ToolPanelCoordinator::toolSelected(ToolMode tool) break; } - updateToolLocations(options.favorites); + updateToolLocations(options.favorites, options.cloneFavoriteTools); notebookconn.block(false); } diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 3182d3e16..8c0f6beaf 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -219,7 +219,9 @@ protected: void addfavoritePanel (Gtk::Box* where, FoldableToolPanel* panel, int level = 1); void notebookPageChanged(Gtk::Widget* page, guint page_num); void updatePanelTools( - Gtk::Widget *page, const std::vector &favorites); + Gtk::Widget *page, + const std::vector &favorites, + bool cloneFavoriteTools); private: EditDataProvider *editDataProvider; @@ -345,7 +347,8 @@ public: const LUTu& histLRETI ); void foldAllButOne(Gtk::Box* parent, FoldableToolPanel* openedSection); - void updateToolLocations(const std::vector &favorites); + void updateToolLocations( + const std::vector &favorites, bool cloneFavoriteTools); // multiple listeners can be added that are notified on changes (typical: profile panel and the history) void addPParamsChangeListener(PParamsChangeListener* pp) @@ -461,14 +464,16 @@ protected: FoldableToolPanel *getFoldableToolPanel(Tool tool) const; FoldableToolPanel *getFoldableToolPanel(const ToolTree &tool) const; - void updateFavoritesPanel(const std::vector &favorites); + void updateFavoritesPanel( + const std::vector &favorites, bool cloneFavoriteTools); template typename std::enable_if::value, void>::type updateToolPanel( Gtk::Box *panelBox, const std::vector &children, int level, - std::unordered_set favorites); + std::unordered_set favorites, + bool cloneFavoriteTools); private: IdleRegister idle_register; From 80944d6c9b83f242a0d7f113ab08e073d6a7e03f Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 10 Dec 2021 22:24:18 -0800 Subject: [PATCH 045/326] Change look of favorites preferences Set column widths based on DPI and font size in pseudo-HiDPI mode. Move favorites buttons to left side of list. --- rtgui/toollocationpref.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index 849ff29b6..d4021f03b 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -22,6 +22,7 @@ #include "guiutils.h" #include "options.h" #include "rtimage.h" +#include "rtscalable.h" #include "toollocationpref.h" #include "toolpanelcoord.h" @@ -720,7 +721,8 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : M("PREFERENCES_TOOLPANEL_AVAILABLETOOLS"))); Gtk::ScrolledWindow *tool_list_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); - tool_list_scrolled_window->set_min_content_width(550); + tool_list_scrolled_window->set_min_content_width( + 400 * (RTScalable::getTweakedDPI() / RTScalable::baseDPI)); 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); @@ -733,10 +735,11 @@ 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(400); + favorites_list_scrolled_window->set_min_content_width( + 300 * (RTScalable::getTweakedDPI() / RTScalable::baseDPI)); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); - favorites_box->pack_start(*favorites_list_scrolled_window, false, false); favorites_box->pack_start(impl->favoritesListEditButtons, false, false); + favorites_box->pack_start(*favorites_list_scrolled_window, false, false); favorites_frame->add(*favorites_box); favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( From 546c99d276b3855c293d2d4638b91a2c500af3bb Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 11 Dec 2021 15:35:52 -0800 Subject: [PATCH 046/326] Clean up favorites preferences code --- rtgui/toollocationpref.cc | 54 +++++++++++++++++---------------- rtgui/toolpanelcoord.cc | 64 ++++++++++++++++++++++++++++++++------- rtgui/toolpanelcoord.h | 7 +++-- 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index d4021f03b..f489c4f63 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -199,7 +199,7 @@ private: Gtk::Button buttonDown; Gtk::Button buttonRemove; - sigc::signal> signalRowsPreErase; + sigc::signal &> signalRowsPreErase; void onButtonDownPressed(); void onButtonRemovePressed(); @@ -224,7 +224,7 @@ public: * The signal contains a vector of tree model paths of the rows that will be * erased. */ - sigc::signal> getSignalRowsPreErase(); + sigc::signal &> getSignalRowsPreErase() const; }; /** @@ -319,7 +319,7 @@ void ListEditButtons::onButtonDownPressed() } // Get the selected row and next row. - auto selected_row_iter = listStore->get_iter(selected[0]); + const auto selected_row_iter = listStore->get_iter(selected[0]); auto next_row_iter = selected_row_iter; next_row_iter++; @@ -336,17 +336,21 @@ void ListEditButtons::onButtonRemovePressed() { const std::vector selected_paths = list.get_selection()->get_selected_rows(); - std::vector selected; + std::vector selected(selected_paths.size()); // Get row references, which are valid until the row is removed. - for (const auto & row_path : selected_paths) { - selected.push_back(Gtk::TreeModel::RowReference(listStore, row_path)); - } + std::transform( + selected_paths.begin(), + selected_paths.end(), + selected.begin(), + [this](const Gtk::TreeModel::Path &row_path) { + return Gtk::TreeModel::RowReference(listStore, row_path); + }); signalRowsPreErase.emit(selected_paths); // Remove the selected rows. - for (const auto & row_ref : selected) { + for (const auto &row_ref : selected) { const auto row_path = row_ref.get_path(); if (row_path) { listStore->erase(listStore->get_iter(row_path)); @@ -368,7 +372,7 @@ void ListEditButtons::onButtonUpPressed() return; } - auto selected_row_iter = listStore->get_iter(selected[0]); + const auto selected_row_iter = listStore->get_iter(selected[0]); if (selected_row_iter == list_children.begin()) { // Can't be first row. return; @@ -411,8 +415,8 @@ void ListEditButtons::updateButtonSensitivity() buttonRemove.set_sensitive(selected.size() > 0); } -sigc::signal> -ListEditButtons::getSignalRowsPreErase() +sigc::signal &> +ListEditButtons::getSignalRowsPreErase() const { return signalRowsPreErase; } @@ -420,8 +424,6 @@ ListEditButtons::getSignalRowsPreErase() } struct ToolLocationPreference::Impl { - static std::unordered_map toolNamesReverseMap; - Options &options; // General options. @@ -488,7 +490,7 @@ struct ToolLocationPreference::Impl { * @param paths Paths in the favorites list pointing to the rows that are * about to be removed. */ - void onFavoritesRowsPreRemove(const std::vector paths); + void onFavoritesRowsPreRemove(const std::vector &paths); /** * Converts tool names to their corresponding tools. * @@ -504,9 +506,6 @@ struct ToolLocationPreference::Impl { void updateOptions(); }; -std::unordered_map - ToolLocationPreference::Impl::toolNamesReverseMap; - ToolLocationPreference::Impl::Impl(Options &options) : options(options), @@ -577,7 +576,7 @@ void ToolLocationPreference::Impl::favoriteToggled(const Glib::ustring &row_path // Update the favorites list. if (is_favorite) { // Add to favorites list. - auto new_favorite_row_iter = favoritesModelPtr->append(); + const auto new_favorite_row_iter = favoritesModelPtr->append(); new_favorite_row_iter->set_value( favoritesColumns.toolName, M(getToolTitleKey(tool))); @@ -602,7 +601,7 @@ void ToolLocationPreference::Impl::initFavoritesRows( { // Add the favorites to the favorites list store. for (const auto tool : favorites) { - auto favorite_row_iter = favoritesModelPtr->append(); + const auto favorite_row_iter = favoritesModelPtr->append(); favorite_row_iter->set_value( favoritesColumns.toolName, M(getToolTitleKey(tool))); @@ -617,7 +616,8 @@ void ToolLocationPreference::Impl::addToolListRowGroup( { // Recursively add the tool and its children to the tool list tree store. for (const ToolPanelCoordinator::ToolTree &tool : tools) { - auto tool_row_iter = toolListModelPtr->append(parentRowIter->children()); + const auto tool_row_iter = + toolListModelPtr->append(parentRowIter->children()); tool_row_iter->set_value( toolListColumns.toolName, M(getToolTitleKey(tool.id))); @@ -653,7 +653,7 @@ void ToolLocationPreference::Impl::initToolListRows(const std::vector &fav ToolPanelCoordinator::Panel::TRANSFORM_PANEL, ToolPanelCoordinator::Panel::RAW, }) { - auto tool_group_iter = toolListModelPtr->append(); + const auto tool_group_iter = toolListModelPtr->append(); tool_group_iter->set_value( toolListColumns.toolName, M(getToolPanelTitleKey(panel))); @@ -662,7 +662,7 @@ void ToolLocationPreference::Impl::initToolListRows(const std::vector &fav } void ToolLocationPreference::Impl::onFavoritesRowsPreRemove( - const std::vector paths) + const std::vector &paths) { // Unset the favorite column in the tools list for tools about to be removed // from the favorites list. @@ -678,13 +678,15 @@ std::vector ToolLocationPreference::Impl::toolNamesToTools( { std::vector tool_set; - for (auto &&tool_name : tool_names) { + for (const auto &tool_name : tool_names) { Tool tool; try { tool = ToolPanelCoordinator::getToolFromName(tool_name); - } catch (const std::exception &e) { + } catch (const std::out_of_range &e) { if (rtengine::settings->verbose) { - std::cerr << "Unrecognized tool name \"" << tool_name << "\"." << std::endl; + std::cerr + << "Unrecognized tool name \"" << tool_name << "\"." + << std::endl; } assert(false); continue; @@ -701,7 +703,7 @@ void ToolLocationPreference::Impl::updateOptions() const auto favorites_rows = favoritesModelPtr->children(); options.favorites.resize(favorites_rows.size()); - for (unsigned i = 0; i < favorites_rows.size(); i++) { + for (Gtk::TreeNodeChildren::size_type i = 0; i < favorites_rows.size(); i++) { const Tool tool = favorites_rows[i].get_value(favoritesColumns.tool); options.favorites[i] = ToolPanelCoordinator::getToolName(tool); } diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 4991e68d8..f89c76b8d 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + #include "multilangmgr.h" #include "toolpanelcoord.h" #include "metadatapanel.h" @@ -350,12 +352,14 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit for (const auto &panel_tool_layout : getDefaultToolLayout()) { const auto &panel_tools = panel_tool_layout.second; - std::vector unprocessed_tools; + std::vector unprocessed_tools(panel_tools.size()); // Start with the root tools for every panel. - for (const auto &tool_tree : panel_tools) { - unprocessed_tools.push_back(&tool_tree); - } + std::transform( + panel_tools.begin(), + panel_tools.end(), + unprocessed_tools.begin(), + [](const ToolTree &tool_tree) { return &tool_tree; }); // Process each tool. while (!unprocessed_tools.empty()) { @@ -363,7 +367,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit const ToolTree *cur_tool = unprocessed_tools.back(); unprocessed_tools.pop_back(); // Add tool to list of expanders and tool panels. - FoldableToolPanel *tool_panel = getFoldableToolPanel(*cur_tool); + FoldableToolPanel *const tool_panel = getFoldableToolPanel(*cur_tool); expList.push_back(tool_panel->getExpander()); toolPanels.push_back(tool_panel); expanderToToolPanelMap[tool_panel->getExpander()] = tool_panel; @@ -514,7 +518,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit prevPage = toolPanelNotebook->get_nth_page(0); } -const ToolPanelCoordinator::ToolLayout& ToolPanelCoordinator::getDefaultToolLayout() +const ToolPanelCoordinator::ToolLayout &ToolPanelCoordinator::getDefaultToolLayout() { return PANEL_TOOLS; } @@ -708,10 +712,22 @@ void ToolPanelCoordinator::updateFavoritesPanel( std::vector> favorites_tool_tree; for (const auto &tool_name : favoritesNames) { - Tool tool = getToolFromName(tool_name.raw()); + Tool tool; + try { + tool = getToolFromName(tool_name.raw()); + } catch (const std::out_of_range &e) { + if (rtengine::settings->verbose) { + std::cerr + << "Unrecognized favorite tool \"" << tool_name << "\"" + << std::endl; + } + continue; + } + if (isFavoritable(tool)) { favorites_set.insert(tool); favorites_tool_tree.push_back( std::ref(*(toolToDefaultToolTreeMap.at(tool)))); + } } updateToolPanel( @@ -758,7 +774,20 @@ void ToolPanelCoordinator::updatePanelTools( std::unordered_set favoriteTools; for (const auto &tool_name : favorites) { - favoriteTools.insert(getToolFromName(tool_name.raw())); + Tool tool; + try { + tool = getToolFromName(tool_name.raw()); + } catch (const std::out_of_range &e) { + if (rtengine::settings->verbose) { + std::cerr + << "Unrecognized favorite tool \"" << tool_name << "\"" + << std::endl; + } + continue; + } + if (isFavoritable(tool)) { + favoriteTools.insert(tool); + } } updateToolPanel(panel, *default_panel_tools, 1, favoriteTools, cloneFavoriteTools); @@ -770,7 +799,7 @@ ToolPanelCoordinator::updateToolPanel( Gtk::Box *panelBox, const std::vector &children, int level, - std::unordered_set favorites, + const std::unordered_set &favorites, bool cloneFavoriteTools) { const bool is_favorite_panel = panelBox == favoritePanel; @@ -1646,8 +1675,20 @@ void ToolPanelCoordinator::updateToolLocations( // Update favorite tool panels list. favoritesToolPanels.clear(); for (const auto &favorite_name : favorites) { - favoritesToolPanels.push_back( - getFoldableToolPanel(getToolFromName(favorite_name))); + Tool tool; + try { + tool = getToolFromName(favorite_name.raw()); + } catch (const std::out_of_range &e) { + if (rtengine::settings->verbose) { + std::cerr + << "Unrecognized favorite tool \"" << favorite_name << "\"" + << std::endl; + } + continue; + } + if (isFavoritable(tool)) { + favoritesToolPanels.push_back(getFoldableToolPanel(tool)); + } } int cur_page_num = toolPanelNotebook->get_current_page(); @@ -1948,6 +1989,7 @@ FoldableToolPanel *ToolPanelCoordinator::getFoldableToolPanel(Tool tool) const case Tool::PD_SHARPENING: return pdSharpening; }; + assert(false); return nullptr; } diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 8c0f6beaf..cd354738e 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -305,7 +305,7 @@ public: std::vector children; }; - using ToolLayout = std::unordered_map, ScopedEnumHash>; + using ToolLayout = std::unordered_map &, ScopedEnumHash>; CoarsePanel* coarse; Gtk::Notebook* toolPanelNotebook; @@ -313,12 +313,13 @@ public: ToolPanelCoordinator(bool batch = false); ~ToolPanelCoordinator () override; - static const ToolLayout& getDefaultToolLayout(); + static const ToolLayout &getDefaultToolLayout(); /** * Gets the tool with the provided tool name. * * @param name The tool name as a raw string. * @return The tool. + * @throws std::out_of_range If the name is not recognized. */ static Tool getToolFromName(const std::string &name); /** @@ -472,7 +473,7 @@ protected: Gtk::Box *panelBox, const std::vector &children, int level, - std::unordered_set favorites, + const std::unordered_set &favorites, bool cloneFavoriteTools); private: From 40678f67b021de85db7c5d742fc7be2195912576 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 11 Dec 2021 21:21:54 -0800 Subject: [PATCH 047/326] Refactor tool name code --- rtgui/bayerpreprocess.cc | 4 +- rtgui/bayerpreprocess.h | 1 + rtgui/bayerprocess.cc | 3 +- rtgui/bayerprocess.h | 1 + rtgui/bayerrawexposure.cc | 4 +- rtgui/bayerrawexposure.h | 2 + rtgui/blackwhite.cc | 3 +- rtgui/blackwhite.h | 1 + rtgui/cacorrection.cc | 4 +- rtgui/cacorrection.h | 1 + rtgui/chmixer.cc | 4 +- rtgui/chmixer.h | 1 + rtgui/colorappearance.cc | 4 +- rtgui/colorappearance.h | 2 + rtgui/colortoning.cc | 3 +- rtgui/colortoning.h | 2 + rtgui/crop.cc | 4 +- rtgui/crop.h | 2 + rtgui/darkframe.cc | 4 +- rtgui/darkframe.h | 1 + rtgui/defringe.cc | 4 +- rtgui/defringe.h | 1 + rtgui/dehaze.cc | 4 +- rtgui/dehaze.h | 1 + rtgui/dirpyrdenoise.cc | 4 +- rtgui/dirpyrdenoise.h | 2 + rtgui/dirpyrequalizer.cc | 4 +- rtgui/dirpyrequalizer.h | 1 + rtgui/distortion.cc | 4 +- rtgui/distortion.h | 1 + rtgui/epd.cc | 4 +- rtgui/epd.h | 1 + rtgui/fattaltonemap.cc | 4 +- rtgui/fattaltonemap.h | 1 + rtgui/filmnegative.cc | 4 +- rtgui/filmnegative.h | 2 + rtgui/filmsimulation.cc | 4 +- rtgui/filmsimulation.h | 2 + rtgui/flatfield.cc | 4 +- rtgui/flatfield.h | 1 + rtgui/gradient.cc | 4 +- rtgui/gradient.h | 1 + rtgui/hsvequalizer.cc | 4 +- rtgui/hsvequalizer.h | 1 + rtgui/icmpanel.cc | 4 +- rtgui/icmpanel.h | 2 + rtgui/impulsedenoise.cc | 4 +- rtgui/impulsedenoise.h | 1 + rtgui/labcurve.cc | 4 +- rtgui/labcurve.h | 1 + rtgui/lensgeom.cc | 4 +- rtgui/lensgeom.h | 1 + rtgui/lensprofile.cc | 4 +- rtgui/lensprofile.h | 2 + rtgui/localcontrast.cc | 4 +- rtgui/localcontrast.h | 1 + rtgui/locallab.cc | 4 +- rtgui/locallab.h | 2 + rtgui/pcvignette.cc | 4 +- rtgui/pcvignette.h | 1 + rtgui/pdsharpening.cc | 4 +- rtgui/pdsharpening.h | 1 + rtgui/perspective.cc | 4 +- rtgui/perspective.h | 1 + rtgui/preprocess.cc | 4 +- rtgui/preprocess.h | 1 + rtgui/preprocesswb.cc | 4 +- rtgui/preprocesswb.h | 1 + rtgui/prsharpening.cc | 4 +- rtgui/prsharpening.h | 1 + rtgui/rawcacorrection.cc | 4 +- rtgui/rawcacorrection.h | 1 + rtgui/rawexposure.cc | 4 +- rtgui/rawexposure.h | 1 + rtgui/resize.cc | 4 +- rtgui/resize.h | 2 + rtgui/retinex.cc | 4 +- rtgui/retinex.h | 2 + rtgui/rgbcurves.cc | 4 +- rtgui/rgbcurves.h | 1 + rtgui/rotate.cc | 4 +- rtgui/rotate.h | 1 + rtgui/sensorbayer.cc | 4 +- rtgui/sensorbayer.h | 1 + rtgui/sensorxtrans.cc | 4 +- rtgui/sensorxtrans.h | 1 + rtgui/shadowshighlights.cc | 4 +- rtgui/shadowshighlights.h | 1 + rtgui/sharpenedge.cc | 3 +- rtgui/sharpenedge.h | 1 + rtgui/sharpening.cc | 4 +- rtgui/sharpening.h | 1 + rtgui/sharpenmicro.cc | 3 +- rtgui/sharpenmicro.h | 1 + rtgui/softlight.cc | 4 +- rtgui/softlight.h | 1 + rtgui/spot.cc | 4 +- rtgui/spot.h | 1 + rtgui/tonecurve.cc | 4 +- rtgui/tonecurve.h | 2 + rtgui/toollocationpref.cc | 2 +- rtgui/toolpanelcoord.cc | 112 ++++++++++++++++++------------------- rtgui/vibrance.cc | 4 +- rtgui/vibrance.h | 1 + rtgui/vignetting.cc | 4 +- rtgui/vignetting.h | 1 + rtgui/wavelet.cc | 4 +- rtgui/wavelet.h | 2 + rtgui/whitebalance.cc | 4 +- rtgui/whitebalance.h | 1 + rtgui/xtransprocess.cc | 4 +- rtgui/xtransprocess.h | 1 + rtgui/xtransrawexposure.cc | 4 +- rtgui/xtransrawexposure.h | 1 + 114 files changed, 290 insertions(+), 113 deletions(-) diff --git a/rtgui/bayerpreprocess.cc b/rtgui/bayerpreprocess.cc index 793496b5f..e8b965736 100644 --- a/rtgui/bayerpreprocess.cc +++ b/rtgui/bayerpreprocess.cc @@ -28,7 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; -BayerPreProcess::BayerPreProcess() : FoldableToolPanel(this, "bayerpreprocess", M("TP_PREPROCESS_LABEL"), options.prevdemo != PD_Sidecar) +const Glib::ustring BayerPreProcess::TOOL_NAME = "bayerpreprocess"; + +BayerPreProcess::BayerPreProcess() : FoldableToolPanel(this, TOOL_NAME, M("TP_PREPROCESS_LABEL"), options.prevdemo != PD_Sidecar) { auto m = ProcEventMapper::getInstance(); EvLineDenoiseDirection = m->newEvent(DARKFRAME, "HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION"); diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h index 16b469626..8b5f8d981 100644 --- a/rtgui/bayerpreprocess.h +++ b/rtgui/bayerpreprocess.h @@ -37,6 +37,7 @@ protected: rtengine::ProcEvent EvPDAFLinesFilter; public: + static const Glib::ustring TOOL_NAME; BayerPreProcess (); diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 4d1657a47..e7e038e52 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -28,9 +28,10 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring BayerProcess::TOOL_NAME = "bayerprocess"; BayerProcess::BayerProcess () : - FoldableToolPanel(this, "bayerprocess", M("TP_RAW_LABEL"), options.prevdemo != PD_Sidecar), + FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_LABEL"), options.prevdemo != PD_Sidecar), oldMethod(-1) { diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index b9c63e9b2..00a5c8aac 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -76,6 +76,7 @@ protected: rtengine::ProcEvent EvDemosaicPixelshiftDemosaicMethod; rtengine::ProcEvent EvPixelshiftAverage; public: + static const Glib::ustring TOOL_NAME; BayerProcess (); ~BayerProcess () override; diff --git a/rtgui/bayerrawexposure.cc b/rtgui/bayerrawexposure.cc index 157abc2cf..834384a91 100644 --- a/rtgui/bayerrawexposure.cc +++ b/rtgui/bayerrawexposure.cc @@ -26,7 +26,9 @@ using namespace rtengine; using namespace rtengine::procparams; -BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, "bayerrawexposure", M("TP_EXPOS_BLACKPOINT_LABEL"), options.prevdemo != PD_Sidecar) +const Glib::ustring BayerRAWExposure::TOOL_NAME = "bayerrawexposure"; + +BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOS_BLACKPOINT_LABEL"), options.prevdemo != PD_Sidecar) { PexBlack1 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_1"), -2048, 2048, 1.0, 0)); //black level PexBlack1->setAdjusterListener (this); diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h index eb18aa0e3..53c5817f8 100644 --- a/rtgui/bayerrawexposure.h +++ b/rtgui/bayerrawexposure.h @@ -31,6 +31,8 @@ class BayerRAWExposure final : public FoldableToolPanel { public: + static const Glib::ustring TOOL_NAME; + BayerRAWExposure (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index e713f1450..c92e68896 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -34,8 +34,9 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring BlackWhite::TOOL_NAME = "blackwhite"; -BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LABEL"), false, true) +BlackWhite::BlackWhite (): FoldableToolPanel(this, TOOL_NAME, M("TP_BWMIX_LABEL"), false, true) { CurveListener::setMulti(true); diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h index 505d842db..fe41ccda0 100644 --- a/rtgui/blackwhite.h +++ b/rtgui/blackwhite.h @@ -40,6 +40,7 @@ class BlackWhite final : public ColorProvider { public: + static const Glib::ustring TOOL_NAME; BlackWhite (); ~BlackWhite () override; diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc index 971c0a284..52ed782df 100644 --- a/rtgui/cacorrection.cc +++ b/rtgui/cacorrection.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -CACorrection::CACorrection () : FoldableToolPanel(this, "cacorrection", M("TP_CACORRECTION_LABEL")) +const Glib::ustring CACorrection::TOOL_NAME = "cacorrection"; + +CACorrection::CACorrection () : FoldableToolPanel(this, TOOL_NAME, M("TP_CACORRECTION_LABEL")) { Gtk::Image* icaredL = Gtk::manage (new RTImage ("circle-red-cyan-small.png")); diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h index 12d6396eb..7afccb4de 100644 --- a/rtgui/cacorrection.h +++ b/rtgui/cacorrection.h @@ -34,6 +34,7 @@ protected: Adjuster* blue; public: + static const Glib::ustring TOOL_NAME; CACorrection (); diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc index 619d7be3e..e54ddfc5d 100644 --- a/rtgui/chmixer.cc +++ b/rtgui/chmixer.cc @@ -25,7 +25,9 @@ using namespace rtengine; using namespace rtengine::procparams; -ChMixer::ChMixer (): FoldableToolPanel(this, "chmixer", M("TP_CHMIXER_LABEL"), false, true) +const Glib::ustring ChMixer::TOOL_NAME = "chmixer"; + +ChMixer::ChMixer (): FoldableToolPanel(this, TOOL_NAME, M("TP_CHMIXER_LABEL"), false, true) { imgIcon[0] = Gtk::manage (new RTImage ("circle-red-small.png")); diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h index d80b89cf7..831449c30 100644 --- a/rtgui/chmixer.h +++ b/rtgui/chmixer.h @@ -36,6 +36,7 @@ protected: Gtk::Image *imgIcon[9]; public: + static const Glib::ustring TOOL_NAME; ChMixer (); diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index f579da6e6..6a3346f18 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -44,6 +44,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring ColorAppearance::TOOL_NAME = "colorappearance"; + static double wbSlider2Temp (double sval) { @@ -212,7 +214,7 @@ static double wbTemp2Slider (double temp) } -ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance", M ("TP_COLORAPP_LABEL"), false, true) +ColorAppearance::ColorAppearance () : FoldableToolPanel (this, TOOL_NAME, M ("TP_COLORAPP_LABEL"), false, true) { CurveListener::setMulti (true); std::vector milestones; diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index ce1971e85..caa481c34 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -39,6 +39,8 @@ class ColorAppearance final : public ColorProvider { public: + static const Glib::ustring TOOL_NAME; + ColorAppearance (); ~ColorAppearance () override; diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 0140c5b62..5e97084c9 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -14,6 +14,7 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring ColorToning::TOOL_NAME = "colortoning"; namespace { @@ -33,7 +34,7 @@ inline float round_ab(float v) } // namespace -ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLORTONING_LABEL"), false, true) +ColorToning::ColorToning () : FoldableToolPanel(this, TOOL_NAME, M("TP_COLORTONING_LABEL"), false, true) { nextbw = 0; CurveListener::setMulti(true); diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index be3a83c2d..e763a069c 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -30,6 +30,8 @@ class ColorToning final : public AdjusterListener { public: + static const Glib::ustring TOOL_NAME; + ColorToning (); ~ColorToning() override; void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 853cec255..21a32b653 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -29,6 +29,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring Crop::TOOL_NAME = "crop"; + namespace { @@ -124,7 +126,7 @@ private: }; Crop::Crop(): - FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true), + FoldableToolPanel(this, TOOL_NAME, M("TP_CROP_LABEL"), false, true), crop_ratios(new CropRatios), opt(0), wDirty(true), diff --git a/rtgui/crop.h b/rtgui/crop.h index c6636b917..83eb6bbbb 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -41,6 +41,8 @@ class Crop final : public rtengine::SizeListener { public: + static const Glib::ustring TOOL_NAME; + Crop(); ~Crop() override; diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index b6b1201a7..9cb45ae98 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -30,7 +30,9 @@ using namespace rtengine; using namespace rtengine::procparams; -DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_LABEL")), dfChanged(false), lastDFauto(false), dfp(nullptr), israw(true) +const Glib::ustring DarkFrame::TOOL_NAME = "darkframe"; + +DarkFrame::DarkFrame () : FoldableToolPanel(this, TOOL_NAME, M("TP_DARKFRAME_LABEL")), dfChanged(false), lastDFauto(false), dfp(nullptr), israw(true) { hbdf = Gtk::manage(new Gtk::Box()); hbdf->set_spacing(4); diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h index 58e8b4842..fea8299a4 100644 --- a/rtgui/darkframe.h +++ b/rtgui/darkframe.h @@ -62,6 +62,7 @@ protected: bool israw; public: + static const Glib::ustring TOOL_NAME; DarkFrame (); diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index 7aae8377a..72388ac8c 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -30,7 +30,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Defringe::Defringe () : FoldableToolPanel(this, "defringe", M("TP_DEFRINGE_LABEL"), true, true) +const Glib::ustring Defringe::TOOL_NAME = "defringe"; + +Defringe::Defringe () : FoldableToolPanel(this, TOOL_NAME, M("TP_DEFRINGE_LABEL"), true, true) { std::vector bottomMilestones; diff --git a/rtgui/defringe.h b/rtgui/defringe.h index ebf1eecd8..d939ff926 100644 --- a/rtgui/defringe.h +++ b/rtgui/defringe.h @@ -46,6 +46,7 @@ protected: bool edges; public: + static const Glib::ustring TOOL_NAME; Defringe (); ~Defringe () override; diff --git a/rtgui/dehaze.cc b/rtgui/dehaze.cc index 76d309afc..b77b76945 100644 --- a/rtgui/dehaze.cc +++ b/rtgui/dehaze.cc @@ -29,7 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, true) +const Glib::ustring Dehaze::TOOL_NAME = "dehaze"; + +Dehaze::Dehaze(): FoldableToolPanel(this, TOOL_NAME, M("TP_DEHAZE_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); EvDehazeEnabled = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_ENABLED"); diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 155efa522..1da50d7dd 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -39,6 +39,7 @@ private: rtengine::ProcEvent EvDehazeSaturation; public: + static const Glib::ustring TOOL_NAME; Dehaze(); diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index 3bf7c21f4..f2b780eba 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -33,7 +33,9 @@ using namespace rtengine; using namespace rtengine::procparams; -DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) +const Glib::ustring DirPyrDenoise::TOOL_NAME = "dirpyrdenoise"; + +DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) { std::vector milestones; CurveListener::setMulti(true); diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index 71c9b1894..dadd96988 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -40,6 +40,8 @@ class DirPyrDenoise final : public ColorProvider { public: + static const Glib::ustring TOOL_NAME; + DirPyrDenoise (); ~DirPyrDenoise () override; diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index 9393d7c42..46966ea45 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -24,7 +24,9 @@ using namespace rtengine; using namespace rtengine::procparams; -DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer", M("TP_DIRPYREQUALIZER_LABEL"), true, true) +const Glib::ustring DirPyrEqualizer::TOOL_NAME = "dirpyrequalizer"; + +DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYREQUALIZER_LABEL"), true, true) { std::vector milestones; diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index bb03e1a53..39b201b9b 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -56,6 +56,7 @@ protected: bool lastgamutlab; public: + static const Glib::ustring TOOL_NAME; DirPyrEqualizer (); ~DirPyrEqualizer () override; diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc index 165ccee06..84566ab80 100644 --- a/rtgui/distortion.cc +++ b/rtgui/distortion.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Distortion::Distortion (): FoldableToolPanel(this, "distortion", M("TP_DISTORTION_LABEL")) +const Glib::ustring Distortion::TOOL_NAME = "distortion"; + +Distortion::Distortion (): FoldableToolPanel(this, TOOL_NAME, M("TP_DISTORTION_LABEL")) { rlistener = nullptr; diff --git a/rtgui/distortion.h b/rtgui/distortion.h index 7ef33d73a..98044bacf 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -37,6 +37,7 @@ protected: LensGeomListener * rlistener; public: + static const Glib::ustring TOOL_NAME; Distortion (); diff --git a/rtgui/epd.cc b/rtgui/epd.cc index d032cf28d..073c5ecdd 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -26,7 +26,9 @@ using namespace rtengine; using namespace rtengine::procparams; -EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPanel(this, "epd", M("TP_EPD_LABEL"), true, true) +const Glib::ustring EdgePreservingDecompositionUI::TOOL_NAME = "epd"; + +EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPanel(this, TOOL_NAME, M("TP_EPD_LABEL"), true, true) { strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); diff --git a/rtgui/epd.h b/rtgui/epd.h index 6a5160623..1d866d690 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -36,6 +36,7 @@ protected: Adjuster *reweightingIterates; public: + static const Glib::ustring TOOL_NAME; EdgePreservingDecompositionUI(); diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc index 89a1e9e30..d4ed90612 100644 --- a/rtgui/fattaltonemap.cc +++ b/rtgui/fattaltonemap.cc @@ -31,7 +31,9 @@ using namespace rtengine; using namespace rtengine::procparams; -FattalToneMapping::FattalToneMapping(): FoldableToolPanel(this, "fattal", M("TP_TM_FATTAL_LABEL"), true, true) +const Glib::ustring FattalToneMapping::TOOL_NAME = "fattal"; + +FattalToneMapping::FattalToneMapping(): FoldableToolPanel(this, TOOL_NAME, M("TP_TM_FATTAL_LABEL"), true, true) { auto m = ProcEventMapper::getInstance(); EvTMFattalAnchor = m->newEvent(HDR, "HISTORY_MSG_TM_FATTAL_ANCHOR"); diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h index 3d36ec7d2..f5c19f15c 100644 --- a/rtgui/fattaltonemap.h +++ b/rtgui/fattaltonemap.h @@ -33,6 +33,7 @@ protected: rtengine::ProcEvent EvTMFattalAnchor; public: + static const Glib::ustring TOOL_NAME; FattalToneMapping(); diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 068575a96..292fa98ae 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -28,6 +28,8 @@ #include "../rtengine/procparams.h" #include "../rtengine/color.h" +const Glib::ustring FilmNegative::TOOL_NAME = "filmnegative"; + namespace { @@ -184,7 +186,7 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } FilmNegative::FilmNegative() : - FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), + FoldableToolPanel(this, TOOL_NAME, M("TP_FILMNEGATIVE_LABEL"), false, true), EditSubscriber(ET_OBJECTS), NEUTRAL_TEMP(rtengine::ColorTemp(1., 1., 1., 1.)), evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(ALLNORAW, "HISTORY_MSG_FILMNEGATIVE_VALUES")), diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 21a7dce5c..722625fa2 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -52,6 +52,8 @@ class FilmNegative final : public rtengine::FilmNegListener { public: + static const Glib::ustring TOOL_NAME; + FilmNegative(); ~FilmNegative() override; diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index 6b40bb586..55a8e0ffe 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -12,6 +12,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring FilmSimulation::TOOL_NAME = "filmsimulation"; + namespace { @@ -61,7 +63,7 @@ bool notifySlowParseDir (const std::chrono::system_clock::time_point& startedAt) } FilmSimulation::FilmSimulation() - : FoldableToolPanel( this, "filmsimulation", M("TP_FILMSIMULATION_LABEL"), false, true ) + : FoldableToolPanel( this, TOOL_NAME, M("TP_FILMSIMULATION_LABEL"), false, true ) { m_clutComboBox = Gtk::manage( new ClutComboBox(options.clutsDir) ); int foundClutsCount = m_clutComboBox->foundClutsCount(); diff --git a/rtgui/filmsimulation.h b/rtgui/filmsimulation.h index cfe7016bb..ed30b866e 100644 --- a/rtgui/filmsimulation.h +++ b/rtgui/filmsimulation.h @@ -56,6 +56,8 @@ private: class FilmSimulation : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { public: + static const Glib::ustring TOOL_NAME; + FilmSimulation(); void adjusterChanged(Adjuster* a, double newval) override; diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 71fa0aab6..7e4086c07 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -30,7 +30,9 @@ using namespace rtengine; using namespace rtengine::procparams; -FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL")) +const Glib::ustring FlatField::TOOL_NAME = "flatfield"; + +FlatField::FlatField () : FoldableToolPanel(this, TOOL_NAME, M("TP_FLATFIELD_LABEL")) { hbff = Gtk::manage(new Gtk::Box()); flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index 0d6f167e1..9b20b3e6f 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -67,6 +67,7 @@ protected: IdleRegister idle_register; public: + static const Glib::ustring TOOL_NAME; FlatField (); ~FlatField () override; diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 1274da9ab..26be51975 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -25,7 +25,9 @@ enum GeometryIndex { } -Gradient::Gradient () : FoldableToolPanel(this, "gradient", M("TP_GRADIENT_LABEL"), false, true), EditSubscriber(ET_OBJECTS), lastObject(-1), draggedPointOldAngle(-1000.) +const Glib::ustring Gradient::TOOL_NAME = "gradient"; + +Gradient::Gradient () : FoldableToolPanel(this, TOOL_NAME, M("TP_GRADIENT_LABEL"), false, true), EditSubscriber(ET_OBJECTS), lastObject(-1), draggedPointOldAngle(-1000.) { editHBox = Gtk::manage (new Gtk::Box()); diff --git a/rtgui/gradient.h b/rtgui/gradient.h index dc0371932..d7754007c 100644 --- a/rtgui/gradient.h +++ b/rtgui/gradient.h @@ -38,6 +38,7 @@ protected: void releaseEdit(); public: + static const Glib::ustring TOOL_NAME; Gradient (); ~Gradient () override; diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index 817ba1f4d..ddb1d2fb5 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -28,9 +28,11 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring HSVEqualizer::TOOL_NAME = "hsvequalizer"; + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -HSVEqualizer::HSVEqualizer () : FoldableToolPanel(this, "hsvequalizer", M("TP_HSVEQUALIZER_LABEL"), false, true) +HSVEqualizer::HSVEqualizer () : FoldableToolPanel(this, TOOL_NAME, M("TP_HSVEQUALIZER_LABEL"), false, true) { std::vector bottomMilestones; diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h index 77c1ee1b0..1f80cd9e4 100644 --- a/rtgui/hsvequalizer.h +++ b/rtgui/hsvequalizer.h @@ -44,6 +44,7 @@ protected: FlatCurveEditor* vshape; public: + static const Glib::ustring TOOL_NAME; HSVEqualizer (); ~HSVEqualizer () override; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 45d0f6622..254882736 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -35,7 +35,9 @@ using namespace rtengine; using namespace rtengine::procparams; -ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr) +const Glib::ustring ICMPanel::TOOL_NAME = "icm"; + +ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr) { auto m = ProcEventMapper::getInstance(); EvICMprimariMethod = m->newEvent(GAMMA, "HISTORY_MSG_ICM_OUTPUT_PRIMARIES"); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 063da28d1..422b674ff 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -177,6 +177,8 @@ private: float nextwy; public: + static const Glib::ustring TOOL_NAME; + ICMPanel(); ~ICMPanel() override; diff --git a/rtgui/impulsedenoise.cc b/rtgui/impulsedenoise.cc index cc2e10899..1df662aad 100644 --- a/rtgui/impulsedenoise.cc +++ b/rtgui/impulsedenoise.cc @@ -28,7 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; -ImpulseDenoise::ImpulseDenoise () : FoldableToolPanel(this, "impulsedenoise", M("TP_IMPULSEDENOISE_LABEL"), true, true) +const Glib::ustring ImpulseDenoise::TOOL_NAME = "impulsedenoise"; + +ImpulseDenoise::ImpulseDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_IMPULSEDENOISE_LABEL"), true, true) { thresh = Gtk::manage (new Adjuster (M("TP_IMPULSEDENOISE_THRESH"), 0, 100, 1, 50)); diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h index b8acafcfc..c4c297927 100644 --- a/rtgui/impulsedenoise.h +++ b/rtgui/impulsedenoise.h @@ -34,6 +34,7 @@ protected: //Adjuster* edge; public: + static const Glib::ustring TOOL_NAME; ImpulseDenoise (); diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index dca1dfd45..1d49cd6ff 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -32,7 +32,9 @@ using namespace rtengine; using namespace rtengine::procparams; -LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), false, true) +const Glib::ustring LCurve::TOOL_NAME = "labcurves"; + +LCurve::LCurve () : FoldableToolPanel(this, TOOL_NAME, M("TP_LABCURVE_LABEL"), false, true) { brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index dfb79ae7a..b9039baca 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -69,6 +69,7 @@ protected: //%%%%%%%%%%%%%%%% public: + static const Glib::ustring TOOL_NAME; LCurve (); ~LCurve () override; diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 8bdbf6dd4..6b9d70fb0 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false) +const Glib::ustring LensGeometry::TOOL_NAME = "lensgeom"; + +LensGeometry::LensGeometry () : FoldableToolPanel(this, TOOL_NAME, M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false) { auto m = ProcEventMapper::getInstance(); diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index 73c28b006..e8f85faac 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -39,6 +39,7 @@ protected: rtengine::ProcEvent EvTransMethod; public: + static const Glib::ustring TOOL_NAME; LensGeometry (); ~LensGeometry () override; diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 73fb0399b..65c962b7b 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -36,8 +36,10 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring LensProfilePanel::TOOL_NAME = "lensprof"; + LensProfilePanel::LensProfilePanel() : - FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")), + FoldableToolPanel(this, TOOL_NAME, M("TP_LENSPROFILE_LABEL")), lcModeChanged(false), lcpFileChanged(false), useDistChanged(false), diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 7b5b7343c..42746f41e 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -28,6 +28,8 @@ class LensProfilePanel final : public FoldableToolPanel { public: + static const Glib::ustring TOOL_NAME; + LensProfilePanel(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/localcontrast.cc b/rtgui/localcontrast.cc index 6b668a1eb..a56f9cb15 100644 --- a/rtgui/localcontrast.cc +++ b/rtgui/localcontrast.cc @@ -29,7 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; -LocalContrast::LocalContrast(): FoldableToolPanel(this, "localcontrast", M("TP_LOCALCONTRAST_LABEL"), false, true) +const Glib::ustring LocalContrast::TOOL_NAME = "localcontrast"; + +LocalContrast::LocalContrast(): FoldableToolPanel(this, TOOL_NAME, M("TP_LOCALCONTRAST_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); /* EvLocalContrastEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_ENABLED"); diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h index d1d25fb3d..fa769c35e 100644 --- a/rtgui/localcontrast.h +++ b/rtgui/localcontrast.h @@ -38,6 +38,7 @@ private: rtengine::ProcEvent EvLocalContrastLightness; public: + static const Glib::ustring TOOL_NAME; LocalContrast(); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 880125085..db9fc6e1a 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -29,6 +29,8 @@ using namespace procparams; extern Options options; +const Glib::ustring Locallab::TOOL_NAME = "locallab"; + /* ==== LocallabToolList ==== */ LocallabToolList::LocallabToolList(): // Tool list GUI elements @@ -142,7 +144,7 @@ void LocallabToolList::toolRowSelected() /* ==== Locallab ==== */ Locallab::Locallab(): - FoldableToolPanel(this, "locallab", M("TP_LOCALLAB_LABEL"), false, true), + FoldableToolPanel(this, TOOL_NAME, M("TP_LOCALLAB_LABEL"), false, true), // Spot control panel widget expsettings(Gtk::manage(new ControlSpotPanel())), diff --git a/rtgui/locallab.h b/rtgui/locallab.h index d86d8c5c1..c615d49ae 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -131,6 +131,8 @@ private: Glib::ustring spotName; public: + static const Glib::ustring TOOL_NAME; + Locallab(); // FoldableToolPanel management functions diff --git a/rtgui/pcvignette.cc b/rtgui/pcvignette.cc index 9c141d618..1ed7446b1 100644 --- a/rtgui/pcvignette.cc +++ b/rtgui/pcvignette.cc @@ -8,7 +8,9 @@ using namespace rtengine; using namespace rtengine::procparams; -PCVignette::PCVignette () : FoldableToolPanel(this, "pcvignette", M("TP_PCVIGNETTE_LABEL"), false, true) +const Glib::ustring PCVignette::TOOL_NAME = "pcvignette"; + +PCVignette::PCVignette () : FoldableToolPanel(this, TOOL_NAME, M("TP_PCVIGNETTE_LABEL"), false, true) { strength = Gtk::manage (new Adjuster (M("TP_PCVIGNETTE_STRENGTH"), -6, 6, 0.01, 0)); strength->set_tooltip_text (M("TP_PCVIGNETTE_STRENGTH_TOOLTIP")); diff --git a/rtgui/pcvignette.h b/rtgui/pcvignette.h index 87915703f..825654630 100644 --- a/rtgui/pcvignette.h +++ b/rtgui/pcvignette.h @@ -20,6 +20,7 @@ protected: Adjuster* roundness; public: + static const Glib::ustring TOOL_NAME; PCVignette (); diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 45d5b545c..57133048c 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -31,8 +31,10 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring PdSharpening::TOOL_NAME = "capturesharpening"; + PdSharpening::PdSharpening() : - FoldableToolPanel(this, "capturesharpening", M("TP_PDSHARPENING_LABEL"), false, true), + FoldableToolPanel(this, TOOL_NAME, M("TP_PDSHARPENING_LABEL"), false, true), lastAutoContrast(true), lastAutoRadius(true) { diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index eb0576ceb..c4902e4b6 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -50,6 +50,7 @@ protected: IdleRegister idle_register; public: + static const Glib::ustring TOOL_NAME; PdSharpening (); ~PdSharpening () override; diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index d06243524..be151e9bc 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -27,6 +27,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring PerspCorrection::TOOL_NAME = "perspective"; + namespace { @@ -84,7 +86,7 @@ std::vector valuesToControlLines( } -PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("TP_PERSPECTIVE_LABEL")) +PerspCorrection::PerspCorrection () : FoldableToolPanel(this, TOOL_NAME, M("TP_PERSPECTIVE_LABEL")) { auto mapper = ProcEventMapper::getInstance(); diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 404b02010..6ca2381e3 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -104,6 +104,7 @@ public: static constexpr std::size_t MIN_HORIZ_LINES = 2; /** Minimum number of vertical lines for vertical/full correction. */ static constexpr std::size_t MIN_VERT_LINES = 2; + static const Glib::ustring TOOL_NAME; PerspCorrection (); diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index b9326e3ad..4d7df213c 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -28,7 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; -PreProcess::PreProcess () : FoldableToolPanel(this, "preprocess", M("TP_PREPROCESS_LABEL"), options.prevdemo != PD_Sidecar) +const Glib::ustring PreProcess::TOOL_NAME = "preprocess"; + +PreProcess::PreProcess () : FoldableToolPanel(this, TOOL_NAME, M("TP_PREPROCESS_LABEL"), options.prevdemo != PD_Sidecar) { Gtk::Box* hotdeadPixel = Gtk::manage( new Gtk::Box () ); diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index d10ff5223..047413bdb 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -38,6 +38,7 @@ protected: sigc::connection dpixelconn; Adjuster* hdThreshold; public: + static const Glib::ustring TOOL_NAME; PreProcess (); diff --git a/rtgui/preprocesswb.cc b/rtgui/preprocesswb.cc index dddd7fdc2..9251f9440 100644 --- a/rtgui/preprocesswb.cc +++ b/rtgui/preprocesswb.cc @@ -29,8 +29,10 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring PreprocessWB::TOOL_NAME = "preprocesswb"; + PreprocessWB::PreprocessWB() : - FoldableToolPanel(this, "preprocesswb", M("TP_PREPROCWB_LABEL")), + FoldableToolPanel(this, TOOL_NAME, M("TP_PREPROCWB_LABEL")), evPreprocessWBMode(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_PREPROCWB_MODE")), mode(Gtk::manage(new MyComboBoxText())) { diff --git a/rtgui/preprocesswb.h b/rtgui/preprocesswb.h index 343d2e9e9..08e1dc468 100644 --- a/rtgui/preprocesswb.h +++ b/rtgui/preprocesswb.h @@ -34,6 +34,7 @@ private: MyComboBoxText* mode; public: + static const Glib::ustring TOOL_NAME; PreprocessWB(); diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index c79fff1a1..d3c936fa2 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -23,7 +23,9 @@ using namespace rtengine; using namespace rtengine::procparams; -PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PRSHARPENING_LABEL"), false, true) +const Glib::ustring PrSharpening::TOOL_NAME = "prsharpening"; + +PrSharpening::PrSharpening () : FoldableToolPanel(this, TOOL_NAME, M("TP_PRSHARPENING_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index 4128bc4c5..ea22234f8 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -59,6 +59,7 @@ protected: sigc::connection hcConn; rtengine::ProcEvent EvPrShrContrast; public: + static const Glib::ustring TOOL_NAME; PrSharpening (); ~PrSharpening () override; diff --git a/rtgui/rawcacorrection.cc b/rtgui/rawcacorrection.cc index 58c7995f9..473ca2ed3 100644 --- a/rtgui/rawcacorrection.cc +++ b/rtgui/rawcacorrection.cc @@ -28,7 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; -RAWCACorr::RAWCACorr () : FoldableToolPanel(this, "rawcacorrection", M("TP_RAWCACORR_LABEL")) +const Glib::ustring RAWCACorr::TOOL_NAME = "rawcacorrection"; + +RAWCACorr::RAWCACorr () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAWCACORR_LABEL")) { auto m = ProcEventMapper::getInstance(); EvPreProcessCAAutoiterations = m->newEvent(DARKFRAME, "HISTORY_MSG_RAWCACORR_AUTOIT"); diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h index 3c95602a7..88b65528e 100644 --- a/rtgui/rawcacorrection.h +++ b/rtgui/rawcacorrection.h @@ -43,6 +43,7 @@ protected: rtengine::ProcEvent EvPreProcessCAColourshiftHistory; public: + static const Glib::ustring TOOL_NAME; RAWCACorr (); diff --git a/rtgui/rawexposure.cc b/rtgui/rawexposure.cc index 7b5ecabc9..778283b75 100644 --- a/rtgui/rawexposure.cc +++ b/rtgui/rawexposure.cc @@ -28,7 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; -RAWExposure::RAWExposure () : FoldableToolPanel(this, "rawexposure", M("TP_EXPOS_WHITEPOINT_LABEL")) +const Glib::ustring RAWExposure::TOOL_NAME = "rawexposure"; + +RAWExposure::RAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOS_WHITEPOINT_LABEL")) { PexPos = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_LINEAR"), 0.1, 16.0, 0.01, 1)); PexPos->setAdjusterListener (this); diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h index 33c897113..ca839d230 100644 --- a/rtgui/rawexposure.h +++ b/rtgui/rawexposure.h @@ -33,6 +33,7 @@ protected: Adjuster* PexPos; public: + static const Glib::ustring TOOL_NAME; RAWExposure (); diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 0bbb65845..258ccf791 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -29,7 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), false, true), maxw(100000), maxh(100000) +const Glib::ustring Resize::TOOL_NAME = "resize"; + +Resize::Resize () : FoldableToolPanel(this, TOOL_NAME, M("TP_RESIZE_LABEL"), false, true), maxw(100000), maxh(100000) { auto m = ProcEventMapper::getInstance(); EvResizeAllowUpscaling = m->newEvent(RESIZE, "HISTORY_MSG_RESIZE_ALLOWUPSCALING"); diff --git a/rtgui/resize.h b/rtgui/resize.h index d13bf8aa4..71fefb503 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -32,6 +32,8 @@ class Resize final : public rtengine::SizeListener { public: + static const Glib::ustring TOOL_NAME; + Resize (); ~Resize () override; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index a9d7cc376..3aac6f203 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -14,7 +14,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL"), false, true), lastmedianmap (false) +const Glib::ustring Retinex::TOOL_NAME = "retinex"; + +Retinex::Retinex () : FoldableToolPanel (this, TOOL_NAME, M ("TP_RETINEX_LABEL"), false, true), lastmedianmap (false) { CurveListener::setMulti (true); std::vector milestones; diff --git a/rtgui/retinex.h b/rtgui/retinex.h index bf480c9cc..bdcbcc466 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -109,6 +109,8 @@ protected: sigc::connection medianmapConn; public: + static const Glib::ustring TOOL_NAME; + Retinex(); ~Retinex() override; diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 5e7616e70..0dd6805fe 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL"), false, true), lastLumamode(false) +const Glib::ustring RGBCurves::TOOL_NAME = "rgbcurves"; + +RGBCurves::RGBCurves () : FoldableToolPanel(this, TOOL_NAME, M("TP_RGBCURVES_LABEL"), false, true), lastLumamode(false) { lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_RGBCURVES_LUMAMODE"))); diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h index edc80eb41..d7e3c3853 100644 --- a/rtgui/rgbcurves.h +++ b/rtgui/rgbcurves.h @@ -45,6 +45,7 @@ protected: sigc::connection lumamodeConn; public: + static const Glib::ustring TOOL_NAME; RGBCurves (); ~RGBCurves () override; diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 06c53cd4e..944c54e6d 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -29,7 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Rotate::Rotate () : FoldableToolPanel(this, "rotate", M("TP_ROTATE_LABEL")) +const Glib::ustring Rotate::TOOL_NAME = "rotate"; + +Rotate::Rotate () : FoldableToolPanel(this, TOOL_NAME, M("TP_ROTATE_LABEL")) { rlistener = nullptr; diff --git a/rtgui/rotate.h b/rtgui/rotate.h index 41e10eb4d..26db33ffd 100644 --- a/rtgui/rotate.h +++ b/rtgui/rotate.h @@ -36,6 +36,7 @@ protected: LensGeomListener* rlistener; public: + static const Glib::ustring TOOL_NAME; Rotate (); diff --git a/rtgui/sensorbayer.cc b/rtgui/sensorbayer.cc index 39ed5cb91..002cdf1de 100644 --- a/rtgui/sensorbayer.cc +++ b/rtgui/sensorbayer.cc @@ -20,7 +20,9 @@ #include "guiutils.h" #include "rtimage.h" -SensorBayer::SensorBayer () : FoldableToolPanel(this, "sensorbayer", M("TP_RAW_SENSOR_BAYER_LABEL")) +const Glib::ustring SensorBayer::TOOL_NAME = "sensorbayer"; + +SensorBayer::SensorBayer () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_SENSOR_BAYER_LABEL")) { packBox = Gtk::manage (new ToolParamBlock ()); diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h index 2401bf760..0e65b8b38 100644 --- a/rtgui/sensorbayer.h +++ b/rtgui/sensorbayer.h @@ -31,6 +31,7 @@ protected: ToolParamBlock* packBox; public: + static const Glib::ustring TOOL_NAME; SensorBayer (); diff --git a/rtgui/sensorxtrans.cc b/rtgui/sensorxtrans.cc index f13e6607f..c4a5bf76d 100644 --- a/rtgui/sensorxtrans.cc +++ b/rtgui/sensorxtrans.cc @@ -20,7 +20,9 @@ #include "guiutils.h" #include "rtimage.h" -SensorXTrans::SensorXTrans () : FoldableToolPanel(this, "sensorxtrans", M("TP_RAW_SENSOR_XTRANS_LABEL")) +const Glib::ustring SensorXTrans::TOOL_NAME = "sensorxtrans"; + +SensorXTrans::SensorXTrans () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_SENSOR_XTRANS_LABEL")) { packBox = Gtk::manage (new ToolParamBlock ()); diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h index eee014f6c..12c851db3 100644 --- a/rtgui/sensorxtrans.h +++ b/rtgui/sensorxtrans.h @@ -31,6 +31,7 @@ protected: ToolParamBlock* packBox; public: + static const Glib::ustring TOOL_NAME; SensorXTrans (); diff --git a/rtgui/shadowshighlights.cc b/rtgui/shadowshighlights.cc index a168527d6..3c821d863 100644 --- a/rtgui/shadowshighlights.cc +++ b/rtgui/shadowshighlights.cc @@ -25,7 +25,9 @@ using namespace rtengine; using namespace rtengine::procparams; -ShadowsHighlights::ShadowsHighlights () : FoldableToolPanel(this, "shadowshighlights", M("TP_SHADOWSHLIGHTS_LABEL"), false, true) +const Glib::ustring ShadowsHighlights::TOOL_NAME = "shadowshighlights"; + +ShadowsHighlights::ShadowsHighlights () : FoldableToolPanel(this, TOOL_NAME, M("TP_SHADOWSHLIGHTS_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); EvSHColorspace = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_SH_COLORSPACE"); diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h index 7bb0bb01c..fd8b30a6a 100644 --- a/rtgui/shadowshighlights.h +++ b/rtgui/shadowshighlights.h @@ -40,6 +40,7 @@ protected: rtengine::ProcEvent EvSHColorspace; public: + static const Glib::ustring TOOL_NAME; ShadowsHighlights (); diff --git a/rtgui/sharpenedge.cc b/rtgui/sharpenedge.cc index e00d919c3..247a8a5d7 100644 --- a/rtgui/sharpenedge.cc +++ b/rtgui/sharpenedge.cc @@ -28,8 +28,9 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring SharpenEdge::TOOL_NAME = "sharpenedge"; -SharpenEdge::SharpenEdge () : FoldableToolPanel(this, "sharpenedge", M("TP_SHARPENEDGE_LABEL"), true, true) +SharpenEdge::SharpenEdge () : FoldableToolPanel(this, TOOL_NAME, M("TP_SHARPENEDGE_LABEL"), true, true) { passes = Gtk::manage(new Adjuster (M("TP_SHARPENEDGE_PASSES"), 1, 4, 1, 2)); diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h index a813d86e1..bfb48b408 100644 --- a/rtgui/sharpenedge.h +++ b/rtgui/sharpenedge.h @@ -44,6 +44,7 @@ protected: bool lastchanthree; public: + static const Glib::ustring TOOL_NAME; SharpenEdge (); diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 687358349..ba39ac97c 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -23,7 +23,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENING_LABEL"), true, true) +const Glib::ustring Sharpening::TOOL_NAME = "sharpening"; + +Sharpening::Sharpening () : FoldableToolPanel(this, TOOL_NAME, M("TP_SHARPENING_LABEL"), true, true) { auto m = ProcEventMapper::getInstance(); EvSharpenContrast = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_CONTRAST"); diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index aa65b3662..e30db3dd2 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -62,6 +62,7 @@ protected: rtengine::ProcEvent EvSharpenContrast; rtengine::ProcEvent EvSharpenBlur; public: + static const Glib::ustring TOOL_NAME; Sharpening (); ~Sharpening () override; diff --git a/rtgui/sharpenmicro.cc b/rtgui/sharpenmicro.cc index 78228d27c..527d146d7 100644 --- a/rtgui/sharpenmicro.cc +++ b/rtgui/sharpenmicro.cc @@ -29,8 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring SharpenMicro::TOOL_NAME = "sharpenmicro"; -SharpenMicro::SharpenMicro () : FoldableToolPanel(this, "sharpenmicro", M("TP_SHARPENMICRO_LABEL"), true, true) +SharpenMicro::SharpenMicro () : FoldableToolPanel(this, TOOL_NAME, M("TP_SHARPENMICRO_LABEL"), true, true) { auto m = ProcEventMapper::getInstance(); diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h index 23224dd60..876117e68 100644 --- a/rtgui/sharpenmicro.h +++ b/rtgui/sharpenmicro.h @@ -47,6 +47,7 @@ protected: bool lastmatrix; public: + static const Glib::ustring TOOL_NAME; SharpenMicro (); diff --git a/rtgui/softlight.cc b/rtgui/softlight.cc index 84461f169..3a7f84985 100644 --- a/rtgui/softlight.cc +++ b/rtgui/softlight.cc @@ -29,7 +29,9 @@ using namespace rtengine; using namespace rtengine::procparams; -SoftLight::SoftLight(): FoldableToolPanel(this, "softlight", M("TP_SOFTLIGHT_LABEL"), false, true) +const Glib::ustring SoftLight::TOOL_NAME = "softlight"; + +SoftLight::SoftLight(): FoldableToolPanel(this, TOOL_NAME, M("TP_SOFTLIGHT_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); EvSoftLightEnabled = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_SOFTLIGHT_ENABLED"); diff --git a/rtgui/softlight.h b/rtgui/softlight.h index 710da4e34..3b9ff5399 100644 --- a/rtgui/softlight.h +++ b/rtgui/softlight.h @@ -32,6 +32,7 @@ private: rtengine::ProcEvent EvSoftLightStrength; public: + static const Glib::ustring TOOL_NAME; SoftLight(); diff --git a/rtgui/spot.cc b/rtgui/spot.cc index 6e9143dbe..ffc380534 100644 --- a/rtgui/spot.cc +++ b/rtgui/spot.cc @@ -52,8 +52,10 @@ enum GeometryIndex { } +const Glib::ustring Spot::TOOL_NAME = "spot"; + Spot::Spot() : - FoldableToolPanel(this, "spot", M ("TP_SPOT_LABEL"), true, true), + FoldableToolPanel(this, TOOL_NAME, M ("TP_SPOT_LABEL"), true, true), EditSubscriber(ET_OBJECTS), draggedSide(DraggedSide::NONE), lastObject(-1), diff --git a/rtgui/spot.h b/rtgui/spot.h index 85cefa4c2..6320e068e 100644 --- a/rtgui/spot.h +++ b/rtgui/spot.h @@ -97,6 +97,7 @@ protected: Geometry* getVisibleGeometryFromMO (int MOID); public: + static const Glib::ustring TOOL_NAME; Spot (); ~Spot (); diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 8a33575ca..677f73683 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -33,7 +33,9 @@ using namespace rtengine; using namespace rtengine::procparams; -ToneCurve::ToneCurve() : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LABEL")) +const Glib::ustring ToneCurve::TOOL_NAME = "tonecurve"; + +ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL")) { auto m = ProcEventMapper::getInstance(); EvHistMatching = m->newEvent(AUTOEXP, "HISTORY_MSG_HISTMATCHING"); diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 6dd77951d..7ba2178ac 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -97,6 +97,8 @@ protected: void setHistmatching(bool enabled); public: + static const Glib::ustring TOOL_NAME; + ToneCurve (); ~ToneCurve () override; diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index f489c4f63..cf2386257 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -137,7 +137,7 @@ Glib::ustring getToolTitleKey(Tool tool) case Tool::WAVELET: return "TP_WAVELET_LABEL"; case Tool::DIR_PYR_EQUALIZER: - return "TP_DIRPYRDENOISE_LABEL"; + return "TP_DIRPYREQUALIZER_LABEL"; case Tool::HSV_EQUALIZER: return "TP_HSVEQUALIZER_LABEL"; case Tool::FILM_SIMULATION: diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index f89c76b8d..7d98d0dc1 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -557,117 +557,117 @@ std::string ToolPanelCoordinator::getToolName(Tool tool) { switch (tool) { case Tool::TONE_CURVE: - return "tonecurve"; + return ToneCurve::TOOL_NAME; case Tool::SHADOWS_HIGHLIGHTS: - return "shadowshighlights"; + return ShadowsHighlights::TOOL_NAME; case Tool::IMPULSE_DENOISE: - return "impulsedenoise"; + return ImpulseDenoise::TOOL_NAME; case Tool::DEFRINGE_TOOL: - return "defringe"; + return Defringe::TOOL_NAME; case Tool::SPOT: - return "spot"; + return Spot::TOOL_NAME; case Tool::DIR_PYR_DENOISE: - return "dirpyrdenoise"; + return DirPyrDenoise::TOOL_NAME; case Tool::EPD: - return "epd"; + return EdgePreservingDecompositionUI::TOOL_NAME; case Tool::SHARPENING_TOOL: - return "sharpening"; + return Sharpening::TOOL_NAME; case Tool::LOCAL_CONTRAST: - return "localcontrast"; + return LocalContrast::TOOL_NAME; case Tool::SHARPEN_EDGE: - return "sharpenedge"; + return SharpenEdge::TOOL_NAME; case Tool::SHARPEN_MICRO: - return "sharpenmicro"; + return SharpenMicro::TOOL_NAME; case Tool::L_CURVE: - return "labcurves"; + return LCurve::TOOL_NAME; case Tool::RGB_CURVES: - return "rgbcurves"; + return RGBCurves::TOOL_NAME; case Tool::COLOR_TONING: - return "colortoning"; + return ColorToning::TOOL_NAME; case Tool::LENS_GEOM: - return "lensgeom"; + return LensGeometry::TOOL_NAME; case Tool::LENS_PROF: - return "lensprof"; + return LensProfilePanel::TOOL_NAME; case Tool::DISTORTION: - return "distortion"; + return Distortion::TOOL_NAME; case Tool::ROTATE: - return "rotate"; + return Rotate::TOOL_NAME; case Tool::VIBRANCE: - return "vibrance"; + return Vibrance::TOOL_NAME; case Tool::COLOR_APPEARANCE: - return "colorappearance"; + return ColorAppearance::TOOL_NAME; case Tool::WHITE_BALANCE: - return "whitebalance"; + return WhiteBalance::TOOL_NAME; case Tool::VIGNETTING: - return "vignetting"; + return Vignetting::TOOL_NAME; case Tool::RETINEX_TOOL: - return "retinex"; + return Retinex::TOOL_NAME; case Tool::GRADIENT: - return "gradient"; + return Gradient::TOOL_NAME; case Tool::LOCALLAB: - return "locallab"; + return Locallab::TOOL_NAME; case Tool::PC_VIGNETTE: - return "pcvignette"; + return PCVignette::TOOL_NAME; case Tool::PERSPECTIVE: - return "perspective"; + return PerspCorrection::TOOL_NAME; case Tool::CA_CORRECTION: - return "cacorrection"; + return CACorrection::TOOL_NAME; case Tool::CH_MIXER: - return "chmixer"; + return ChMixer::TOOL_NAME; case Tool::BLACK_WHITE: - return "blackwhite"; + return BlackWhite::TOOL_NAME; case Tool::RESIZE_TOOL: - return "resize"; + return Resize::TOOL_NAME; case Tool::PR_SHARPENING: - return "prsharpening"; + return PrSharpening::TOOL_NAME; case Tool::CROP_TOOL: - return "crop"; + return Crop::TOOL_NAME; case Tool::ICM: - return "icm"; + return ICMPanel::TOOL_NAME; case Tool::WAVELET: - return "wavelet"; + return Wavelet::TOOL_NAME; case Tool::DIR_PYR_EQUALIZER: - return "dirpyrdenoise"; + return DirPyrEqualizer::TOOL_NAME; case Tool::HSV_EQUALIZER: - return "hsvequalizer"; + return HSVEqualizer::TOOL_NAME; case Tool::FILM_SIMULATION: - return "filmsimulation"; + return FilmSimulation::TOOL_NAME; case Tool::SOFT_LIGHT: - return "softlight"; + return SoftLight::TOOL_NAME; case Tool::DEHAZE: - return "dehaze"; + return Dehaze::TOOL_NAME; case Tool::SENSOR_BAYER: - return "sensorbayer"; + return SensorBayer::TOOL_NAME; case Tool::SENSOR_XTRANS: - return "sensorxtrans"; + return SensorXTrans::TOOL_NAME; case Tool::BAYER_PROCESS: - return "bayerprocess"; + return BayerProcess::TOOL_NAME; case Tool::XTRANS_PROCESS: - return "xtransprocess"; + return XTransProcess::TOOL_NAME; case Tool::BAYER_PREPROCESS: - return "bayerpreprocess"; + return BayerPreProcess::TOOL_NAME; case Tool::PREPROCESS: - return "preprocess"; + return PreProcess::TOOL_NAME; case Tool::DARKFRAME_TOOL: - return "darkframe"; + return DarkFrame::TOOL_NAME; case Tool::FLATFIELD_TOOL: - return "flatfield"; + return FlatField::TOOL_NAME; case Tool::RAW_CA_CORRECTION: - return "rawcacorrection"; + return RAWCACorr::TOOL_NAME; case Tool::RAW_EXPOSURE: - return "rawexposure"; + return RAWExposure::TOOL_NAME; case Tool::PREPROCESS_WB: - return "preprocesswb"; + return PreprocessWB::TOOL_NAME; case Tool::BAYER_RAW_EXPOSURE: - return "bayerrawexposure"; + return BayerRAWExposure::TOOL_NAME; case Tool::XTRANS_RAW_EXPOSURE: - return "xtransrawexposure"; + return XTransRAWExposure::TOOL_NAME; case Tool::FATTAL: - return "fattal"; + return FattalToneMapping::TOOL_NAME; case Tool::FILM_NEGATIVE: - return "filmnegative"; + return FilmNegative::TOOL_NAME; case Tool::PD_SHARPENING: - return "capturesharpening"; + return PdSharpening::TOOL_NAME; }; assert(false); return ""; diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 4a9fab3d3..f2eb8fc4e 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Vibrance::Vibrance () : FoldableToolPanel(this, "vibrance", M("TP_VIBRANCE_LABEL"), false, true) +const Glib::ustring Vibrance::TOOL_NAME = "vibrance"; + +Vibrance::Vibrance () : FoldableToolPanel(this, TOOL_NAME, M("TP_VIBRANCE_LABEL"), false, true) { std::vector milestones; diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index 12acc7948..ee3d029ee 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -57,6 +57,7 @@ protected: sigc::connection pastsattogconn; public: + static const Glib::ustring TOOL_NAME; Vibrance (); ~Vibrance () override; diff --git a/rtgui/vignetting.cc b/rtgui/vignetting.cc index 04a350b99..c2652de42 100644 --- a/rtgui/vignetting.cc +++ b/rtgui/vignetting.cc @@ -23,7 +23,9 @@ using namespace rtengine; using namespace rtengine::procparams; -Vignetting::Vignetting () : FoldableToolPanel(this, "vignetting", M("TP_VIGNETTING_LABEL")) +const Glib::ustring Vignetting::TOOL_NAME = "vignetting"; + +Vignetting::Vignetting () : FoldableToolPanel(this, TOOL_NAME, M("TP_VIGNETTING_LABEL")) { amount = Gtk::manage (new Adjuster (M("TP_VIGNETTING_AMOUNT"), -100, 100, 1, 0)); diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h index be7765094..bcb7f9d19 100644 --- a/rtgui/vignetting.h +++ b/rtgui/vignetting.h @@ -37,6 +37,7 @@ protected: Adjuster* centerY; public: + static const Glib::ustring TOOL_NAME; Vignetting (); diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index f14dd8c8c..e9ee19335 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -34,6 +34,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring Wavelet::TOOL_NAME = "wavelet"; + namespace { @@ -62,7 +64,7 @@ std::vector makeWholeHueRange() } Wavelet::Wavelet() : - FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true), + FoldableToolPanel(this, TOOL_NAME, M("TP_WAVELET_LABEL"), true, true), curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))), curveEditorC(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTRASTEDIT"))), CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))), diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index bdbf7bbc3..eee9af91c 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -45,6 +45,8 @@ class Wavelet final : public FoldableToolPanel { public: + static const Glib::ustring TOOL_NAME; + Wavelet(); ~Wavelet() override; bool wavComputed_(); diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index fbcf40faf..f6a26e335 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -34,6 +34,8 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring WhiteBalance::TOOL_NAME = "whitebalance"; + Glib::RefPtr WhiteBalance::wbPixbufs[toUnderlying(WBEntry::Type::CUSTOM) + 1]; void WhiteBalance::init () @@ -142,7 +144,7 @@ static double wbTemp2Slider(double temp) return sval; } -WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WBALANCE_LABEL"), true, true), wbp(nullptr), wblistener(nullptr) +WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANCE_LABEL"), true, true), wbp(nullptr), wblistener(nullptr) { Gtk::Grid* methodgrid = Gtk::manage(new Gtk::Grid()); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 1ed99a2aa..f172590c8 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -98,6 +98,7 @@ protected: std::pair findWBEntry (const Glib::ustring& label, enum WB_LabelType lblType = WBLT_GUI); public: + static const Glib::ustring TOOL_NAME; WhiteBalance (); ~WhiteBalance () override; diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 89fd0f8a4..d6850da63 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP_RAW_LABEL"), options.prevdemo != PD_Sidecar) +const Glib::ustring XTransProcess::TOOL_NAME = "xtransprocess"; + +XTransProcess::XTransProcess () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_LABEL"), options.prevdemo != PD_Sidecar) { auto m = ProcEventMapper::getInstance(); EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER"); diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index 4725f4a6d..6639a3796 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -52,6 +52,7 @@ protected: rtengine::ProcEvent EvDemosaicContrast; public: + static const Glib::ustring TOOL_NAME; XTransProcess (); ~XTransProcess () override; diff --git a/rtgui/xtransrawexposure.cc b/rtgui/xtransrawexposure.cc index e1b56b9f0..2e26b8f63 100644 --- a/rtgui/xtransrawexposure.cc +++ b/rtgui/xtransrawexposure.cc @@ -27,7 +27,9 @@ using namespace rtengine; using namespace rtengine::procparams; -XTransRAWExposure::XTransRAWExposure () : FoldableToolPanel(this, "xtransrawexposure", M("TP_EXPOS_BLACKPOINT_LABEL")) +const Glib::ustring XTransRAWExposure::TOOL_NAME = "xtransrawexposure"; + +XTransRAWExposure::XTransRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOS_BLACKPOINT_LABEL")) { PexBlackRed = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_RED"), -2048, 2048, 1.0, 0)); //black level PexBlackRed->setAdjusterListener (this); diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h index a8daf6972..c332bc510 100644 --- a/rtgui/xtransrawexposure.h +++ b/rtgui/xtransrawexposure.h @@ -37,6 +37,7 @@ protected: private: // Gtk::CheckButton* PextwoGreen; public: + static const Glib::ustring TOOL_NAME; XTransRAWExposure (); From 697af1fcb3d2c4d742fa03a60c7902d888853b10 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Dec 2021 16:27:43 -0800 Subject: [PATCH 048/326] Fix tool location updater optimization --- rtgui/toolpanelcoord.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 7d98d0dc1..df28ca21f 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -828,6 +828,7 @@ ToolPanelCoordinator::updateToolPanel( getFoldableToolPanel(*new_tool_trees_iter)->getExpander()) { break; } + ++new_tool_trees_iter; ++old_widgets_iter; } From 901f4e4f6340b84b5c68d43dfb37028e1818bc25 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Dec 2021 17:09:01 -0800 Subject: [PATCH 049/326] Fix memory leak --- rtgui/toolpanelcoord.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index df28ca21f..592c4c97e 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -884,6 +884,17 @@ ToolPanelCoordinator::~ToolPanelCoordinator () // which is responsible of segfault if listener isn't deactivated before notebookconn.block(true); + // Foldable tool panels manage (Gtk::manage) their expanders. Each expander + // will only be automatically deleted if attached to a parent and the parent + // is deleted. This is a hack in lieu of a potentially tedious refactoring + // of FoldableToolPanel. + std::unique_ptr hidden_tool_panel_parent(new Gtk::Box()); + for (const auto expander : expList) { + if (!expander->get_parent()) { + hidden_tool_panel_parent->add(*expander); + } + } + delete toolPanelNotebook; delete toolBar; } From d29b451aa643022f54ffebf14fadfe7a514c03e7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Dec 2021 17:09:53 -0800 Subject: [PATCH 050/326] Hide local adjustments from batch process favorite --- rtgui/toolpanelcoord.cc | 7 ++++--- rtgui/toolpanelcoord.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 592c4c97e..360aca7a0 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -271,7 +271,7 @@ const ToolPanelCoordinator::ToolLayout PANEL_TOOLS = { std::unordered_map ToolPanelCoordinator::toolNamesReverseMap; -ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr), photoLoadedOnce(false) +ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), batch(batch), editDataProvider (nullptr), photoLoadedOnce(false) { favoritePanel = Gtk::manage (new ToolVBox ()); @@ -812,8 +812,9 @@ ToolPanelCoordinator::updateToolPanel( // if they are sub-tools within the favorites panel, or if tool cloning is // off and they are not within the favorites panel. const auto should_skip_tool = - [skip_favorites, &favorites](const ToolTree &tool_tree) { - return skip_favorites && favorites.count(tool_tree.id); + [this, skip_favorites, &favorites](const ToolTree &tool_tree) { + return (skip_favorites && favorites.count(tool_tree.id)) || + (batch && tool_tree.id == Tool::LOCALLAB); }; // Keep tools that are already correct. diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index cd354738e..fda89ef37 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -212,6 +212,7 @@ protected: std::vector expList; bool hasChanged; + bool batch; void addPanel(Gtk::Box* where, FoldableToolPanel* panel, int level = 1); void foldThemAll(GdkEventButton* event); From 012103b4e2d8aa0dba38dc5ccdd4ea668e20198c Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Dec 2021 17:50:12 -0800 Subject: [PATCH 051/326] Fix update of tool locations after changing pref Only the editor panel in single editor mode was being updated. This commit makes them update in multiple editor mode and also updates the batch editor. --- rtgui/editwindow.cc | 8 ++++++++ rtgui/editwindow.h | 2 ++ rtgui/filepanel.cc | 8 ++++++++ rtgui/filepanel.h | 2 ++ rtgui/rtwindow.cc | 13 +++++++++++++ 5 files changed, 33 insertions(+) diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index d0e53d730..4ba1b369a 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -485,3 +485,11 @@ void EditWindow::set_title_decorated(Glib::ustring fname) set_title("RawTherapee " + M("EDITWINDOW_TITLE") + subtitle); } + +void EditWindow::updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools) +{ + for (const auto& panel : epanels) { + panel.second->updateToolPanelToolLocations(favorites, cloneFavoriteTools); + } +} diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index b8eeaee82..b9304c5af 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -64,6 +64,8 @@ public: bool selectEditorPanel(const std::string &name); bool closeOpenEditors(); bool isProcessing(); + void updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools); void toFront(); bool keyPressed (GdkEventKey* event); diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index 682dd1746..63ebd5632 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -436,3 +436,11 @@ void FilePanel::updateTPVScrollbar (bool hide) { tpc->updateTPVScrollbar (hide); } + +void FilePanel::updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools) +{ + if (tpc) { + tpc->updateToolLocations(favorites, cloneFavoriteTools); + } +} diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index ba5dfa7c9..4a006f002 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -83,6 +83,8 @@ public: bool handleShortcutKey (GdkEventKey* event); bool handleShortcutKeyRelease(GdkEventKey *event); void updateTPVScrollbar (bool hide); + void updateToolPanelToolLocations( + const std::vector &favorites, bool cloneFavoriteTools); private: void on_NB_switch_page(Gtk::Widget* page, guint page_num); diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index f3eb658e5..8dfb18b12 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -1113,9 +1113,22 @@ void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) void RTWindow::updateToolPanelToolLocations( const std::vector &favorites, bool cloneFavoriteTools) { + if (fpanel) { + fpanel->updateToolPanelToolLocations(favorites, cloneFavoriteTools); + } + if (epanel) { epanel->updateToolPanelToolLocations(favorites, cloneFavoriteTools); } + + for (const auto &panel : epanels) { + panel.second->updateToolPanelToolLocations(favorites, cloneFavoriteTools); + } + + if (options.multiDisplayMode > 0) { + EditWindow::getInstance(this) + ->updateToolPanelToolLocations(favorites, cloneFavoriteTools); + } } bool RTWindow::splashClosed (GdkEventAny* event) From a7010d25cd88ce15b558d3c20fb61868798e555d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 19 Dec 2021 14:51:47 -0800 Subject: [PATCH 052/326] Fix theme margins Fix spacing that was changed due to the restructuring of foldable tool panels. --- .../themes/RawTherapee - Legacy-GTK3-20_.css | 31 ++++++++++++++--- rtdata/themes/RawTherapee-GTK3-20_.css | 27 +++++++++++++++ rtdata/themes/TooWaBlue-GTK3-20_.css | 3 ++ rtgui/lensgeom.cc | 3 -- rtgui/lensgeom.h | 6 ---- rtgui/resize.cc | 10 +++--- rtgui/resize.h | 6 ---- rtgui/sensorbayer.cc | 3 -- rtgui/sensorbayer.h | 8 ----- rtgui/sensorxtrans.cc | 3 -- rtgui/sensorxtrans.h | 8 ----- rtgui/toolpanel.cc | 6 ++-- rtgui/toolpanel.h | 6 ++-- rtgui/toolpanelcoord.cc | 33 ++++++++++--------- 14 files changed, 85 insertions(+), 68 deletions(-) diff --git a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css b/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css index dd7be3bfd..07a0bd65d 100644 --- a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css +++ b/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css @@ -760,6 +760,23 @@ button.radio#histButton:hover { margin-right: 0.25em; } +/* ExpanderContents is just a logical container. Don't add additional spacing. */ +#ExpanderBox > .ExpanderContents > * { + margin: 0; + min-height: 0; + padding: 0; +} + +/* For sub-tools containers that go below another widget, add some margin + * between them if the container has children. */ +#MyExpander .SubToolsContainer:not(:first-child) > :first-child { + margin-top: 0.1666666666666666em; +} + +#MyExpander .SubToolsContainer { + min-height: 0; +} + /* Tool background */ #ExpanderBox > box, #ExpanderBox > grid { background-color: #363636; @@ -808,9 +825,11 @@ button.radio#histButton:hover { } #LocallabToolPanel > box > checkbutton, #LocallabToolPanel > box > box, #LocallabToolPanel > grid > checkbutton, #LocallabToolPanel > box > grid, #LocallabToolPanel > grid > grid, #LocallabToolPanel frame > box > grid, #LocallabToolPanel frame > grid > grid, #LocallabToolPanel frame > grid > box, -#ExpanderBox > box > checkbutton, #ExpanderBox > box > box, #ExpanderBox > grid > checkbutton, #ExpanderBox > box > grid, #ExpanderBox > grid > grid, #ExpanderBox frame > box > grid, #ExpanderBox frame > grid > grid, #ExpanderBox frame > grid > box, -#ExpanderBox2 > box > checkbutton, #ExpanderBox2 > box > box, #ExpanderBox2 > grid > checkbutton, #ExpanderBox2 > box > grid, #ExpanderBox2 > grid > grid, #ExpanderBox2 frame > box > grid, #ExpanderBox2 frame > grid > grid, #ExpanderBox2 frame > grid > box, -#ExpanderBox3 > box > checkbutton, #ExpanderBox3 > box > box, #ExpanderBox3 > grid > checkbutton, #ExpanderBox3 > box > grid, #ExpanderBox3 > grid > grid, #ExpanderBox3 frame > box > grid, #ExpanderBox3 frame > grid > grid, #ExpanderBox3 frame > grid > box { +#ExpanderBox > .ExpanderContents > box:not(.SubToolsContainer) > checkbutton, #ExpanderBox > .ExpanderContents > box:not(.SubToolsContainer) > box, #ExpanderBox > .ExpanderContents > grid > checkbutton, #ExpanderBox > .ExpanderContents > box:not(.SubToolsContainer) > grid, #ExpanderBox > .ExpanderContents > grid > grid, #ExpanderBox frame > box > grid, #ExpanderBox frame > grid > grid, #ExpanderBox frame > grid > box, +#ExpanderBox2 > .ExpanderContents > box:not(.SubToolsContainer) > checkbutton, #ExpanderBox2 > .ExpanderContents > box:not(.SubToolsContainer) > box, #ExpanderBox2 > .ExpanderContents > grid > checkbutton, #ExpanderBox2 > .ExpanderContents > box:not(.SubToolsContainer) > grid, #ExpanderBox2 > .ExpanderContents > grid > grid, #ExpanderBox2 frame > box > grid, #ExpanderBox2 frame > grid > grid, #ExpanderBox2 frame > grid > box, +#ExpanderBox2 > box:not(.ExpanderContents) > checkbutton, #ExpanderBox2 > box:not(.ExpanderContents) > box, #ExpanderBox2 > grid > checkbutton, #ExpanderBox2 > box:not(.ExpanderContents) > grid, #ExpanderBox2 > grid > grid, #ExpanderBox2 frame > box > grid, #ExpanderBox2 frame > grid > grid, #ExpanderBox2 frame > grid > box, +#ExpanderBox3 > .ExpanderContents > box:not(.SubToolsContainer) > checkbutton, #ExpanderBox3 > .ExpanderContents > box:not(.SubToolsContainer) > box, #ExpanderBox3 > .ExpanderContents > grid > checkbutton, #ExpanderBox3 > .ExpanderContents > box:not(.SubToolsContainer) > grid, #ExpanderBox3 > .ExpanderContents > grid > grid, #ExpanderBox3 frame > box > grid, #ExpanderBox3 frame > grid > grid, #ExpanderBox3 frame > grid > box, +#ExpanderBox3 > box:not(.ExpanderContents) > checkbutton, #ExpanderBox3 > box:not(.ExpanderContents) > box, #ExpanderBox3 > grid > checkbutton, #ExpanderBox3 > box:not(.ExpanderContents) > grid, #ExpanderBox3 > grid > grid, #ExpanderBox3 frame > box > grid, #ExpanderBox3 frame > grid > grid, #ExpanderBox3 frame > grid > box { margin-top: 0.1666666666666666em; } @@ -1099,6 +1118,10 @@ dialog frame > label:not(.dummy) { min-width: 25em; } +#ToolPanelNotebook .PanelEnding { + margin-top: 4px; +} + #ToolPanelNotebook header { background-color: #383838; border-color: #262626; @@ -1395,4 +1418,4 @@ progressbar progress { .grid-spacing > * { margin: 0.1666666666666666em; -} \ No newline at end of file +} diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index c576e0ddf..2e314510a 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -766,6 +766,29 @@ button.radio#histButton:hover { border-bottom: none; } +/* ExpanderContents is just a logical container. Don't add additional spacing. */ +#ExpanderBox > .ExpanderContents > * { + margin: 0; + min-height: 0; + padding: 0; +} + +/* For sub-tools containers that go below another widget, add some margin + * between them if the container has children. */ +#MyExpander .SubToolsContainer:not(:first-child) > :first-child { + margin-top: 0.3333333333333333em; +} + +#MyExpander .SubToolsContainer { + min-height: 0; +} + +.SubToolsContainer > #MyExpander, +.ToolParamBlock > #MyExpander, +.ExpanderContents, +#MyExpander .ToolParamBlock { + margin: 0; +} /* Tool background */ #ExpanderBox > box, @@ -1046,6 +1069,10 @@ dialog frame > label:not(.dummy) { padding: 0; } +#ToolPanelNotebook .PanelEnding { + margin-top: 4px; +} + #ToolPanelNotebook header tabs { padding: 0.0833333333333333em; background-color: #2A2A2A; diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index 4e7e192ad..2e9c6ccde 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -963,6 +963,9 @@ window.csd:not(.fullscreen) #MainNotebook > header.top { #ToolPanelNotebook { background-color: @bg-dark-grey; } +#ToolPanelNotebook .PanelEnding { + margin-top: 4px; +} #ToolPanelNotebook > header { border-bottom: 0.083333333333333333em solid @view-grid-border; margin-left: 0.083333333333333333em; diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 6b9d70fb0..e8febf8e2 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -52,9 +52,6 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, TOOL_NAME, M("TP_LENSGEO autoCrop->get_style_context()->add_class("independent"); pack_start (*autoCrop, Gtk::PACK_SHRINK, 2); - packBox = Gtk::manage (new ToolParamBlock ()); - pack_start (*packBox); - method->connect(method->signal_changed().connect(sigc::mem_fun(*this, &LensGeometry::methodChanged))); autoCrop->signal_pressed().connect(sigc::mem_fun(*this, &LensGeometry::autoCropPressed)); fillConn = fill->signal_toggled().connect(sigc::mem_fun(*this, &LensGeometry::fillPressed)); diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index e8f85faac..fa260e177 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -35,7 +35,6 @@ protected: Gtk::CheckButton* fill; bool lastFill; sigc::connection fillConn; - ToolParamBlock* packBox; rtengine::ProcEvent EvTransMethod; public: @@ -44,11 +43,6 @@ public: LensGeometry (); ~LensGeometry () override; - Gtk::Box* getPackBox () - { - return packBox; - } - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; void setBatchMode (bool batchMode) override; diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 258ccf791..de9f6b4d1 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -172,10 +172,8 @@ Resize::Resize () : FoldableToolPanel(this, TOOL_NAME, M("TP_RESIZE_LABEL"), fal method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) ); sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) ); - packBox = Gtk::manage (new ToolParamBlock ()); - pack_end (*packBox); - packBox->hide(); - packBox->set_tooltip_markup (M("TP_PRSHARPENING_TOOLTIP")); + getSubToolsContainer()->hide(); + getSubToolsContainer()->set_tooltip_markup (M("TP_PRSHARPENING_TOOLTIP")); show_all(); } @@ -398,9 +396,9 @@ void Resize::methodChanged () // Post-resize Sharpening assumes the image is in Lab space, and currently Lanczos is the only method which uses that space, and Lanczos is on row 0. if (method->get_active_row_number() == 0) { - packBox->set_sensitive(true); + getSubToolsContainer()->set_sensitive(true); } else { - packBox->set_sensitive(false); + getSubToolsContainer()->set_sensitive(false); } } diff --git a/rtgui/resize.h b/rtgui/resize.h index 71fefb503..674bbb34f 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -37,11 +37,6 @@ public: Resize (); ~Resize () override; - Gtk::Box* getPackBox () - { - return packBox; - } - 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; @@ -89,7 +84,6 @@ private: int cropw, croph; sigc::connection sconn, aconn, wconn, hconn, leconn, seconn; bool wDirty, hDirty, leDirty, seDirty; - ToolParamBlock* packBox; IdleRegister idle_register; static constexpr int MAX_SCALE = 16; // 16 to match the main preview max scale of 1600% diff --git a/rtgui/sensorbayer.cc b/rtgui/sensorbayer.cc index 002cdf1de..70537f666 100644 --- a/rtgui/sensorbayer.cc +++ b/rtgui/sensorbayer.cc @@ -25,8 +25,5 @@ const Glib::ustring SensorBayer::TOOL_NAME = "sensorbayer"; SensorBayer::SensorBayer () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_SENSOR_BAYER_LABEL")) { - packBox = Gtk::manage (new ToolParamBlock ()); - pack_start (*packBox); - show_all (); } diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h index 0e65b8b38..d3d867ace 100644 --- a/rtgui/sensorbayer.h +++ b/rtgui/sensorbayer.h @@ -27,16 +27,8 @@ class SensorBayer final : public FoldableToolPanel { -protected: - ToolParamBlock* packBox; - public: static const Glib::ustring TOOL_NAME; SensorBayer (); - - Gtk::Box* getPackBox () - { - return packBox; - } }; diff --git a/rtgui/sensorxtrans.cc b/rtgui/sensorxtrans.cc index c4a5bf76d..45e5d57e4 100644 --- a/rtgui/sensorxtrans.cc +++ b/rtgui/sensorxtrans.cc @@ -25,8 +25,5 @@ const Glib::ustring SensorXTrans::TOOL_NAME = "sensorxtrans"; SensorXTrans::SensorXTrans () : FoldableToolPanel(this, TOOL_NAME, M("TP_RAW_SENSOR_XTRANS_LABEL")) { - packBox = Gtk::manage (new ToolParamBlock ()); - pack_start (*packBox); - show_all (); } diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h index 12c851db3..2e5c10483 100644 --- a/rtgui/sensorxtrans.h +++ b/rtgui/sensorxtrans.h @@ -27,16 +27,8 @@ class SensorXTrans final: public FoldableToolPanel { -protected: - ToolParamBlock* packBox; - public: static const Glib::ustring TOOL_NAME; SensorXTrans (); - - Gtk::Box* getPackBox () - { - return packBox; - } }; diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index bf191133d..6db30bb14 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -38,6 +38,7 @@ ToolVBox::ToolVBox() { ToolParamBlock::ToolParamBlock() { set_orientation(Gtk::ORIENTATION_VERTICAL); + get_style_context()->add_class("ToolParamBlock"); //GTK318 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 set_spacing(2); // Vertical space between parameters in a single tool @@ -75,8 +76,9 @@ FoldableToolPanel::FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, Gtk::Box *expanderContents = Gtk::manage( new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - subToolsContainer = Gtk::manage( - new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + subToolsContainer = Gtk::manage(new ToolParamBlock()); + subToolsContainer->get_style_context()->add_class("SubToolsContainer"); + expanderContents->get_style_context()->add_class("ExpanderContents"); expanderContents->pack_start(*content, false, false, 0); expanderContents->pack_start(*subToolsContainer, false, false, 0); diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index ce14dc64f..5ec59c9c2 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -98,7 +98,7 @@ public: { return nullptr; } - virtual Gtk::Box *getSubToolsContainer() const + virtual ToolParamBlock *getSubToolsContainer() const { return nullptr; } @@ -168,7 +168,7 @@ class FoldableToolPanel : protected: Gtk::Box* parentContainer; MyExpander* exp; - Gtk::Box *subToolsContainer; + ToolParamBlock *subToolsContainer; bool lastEnabled; sigc::connection enaConn; void foldThemAll (GdkEventButton* event); @@ -183,7 +183,7 @@ public: return exp; } - Gtk::Box *getSubToolsContainer() const final + ToolParamBlock *getSubToolsContainer() const final { return subToolsContainer; } diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 360aca7a0..cd04583c9 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -400,6 +400,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit vbPanelEnd[i] = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); imgPanelEnd[i] = Gtk::manage (new RTImage ("ornament1.png")); imgPanelEnd[i]->show(); + vbPanelEnd[i]->get_style_context()->add_class("PanelEnding"); vbPanelEnd[i]->pack_start(*imgPanelEnd[i], Gtk::PACK_SHRINK); vbPanelEnd[i]->show_all(); } @@ -423,37 +424,37 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); favoritePanelSW->add(*favoritePanelContainer); - favoritePanelContainer->pack_start(*favoritePanel, Gtk::PACK_SHRINK, 0); - favoritePanelContainer->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); + favoritePanelContainer->pack_start(*favoritePanel, Gtk::PACK_SHRINK); + favoritePanelContainer->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK); favoritePanelSW->show_all(); exposurePanelSW->add (*exposurePanelContainer); - exposurePanelContainer->pack_start(*exposurePanel, Gtk::PACK_SHRINK, 0); - exposurePanelContainer->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK, 4); + exposurePanelContainer->pack_start(*exposurePanel, Gtk::PACK_SHRINK); + exposurePanelContainer->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK); detailsPanelSW->add (*detailsPanelContainer); - detailsPanelContainer->pack_start(*detailsPanel, Gtk::PACK_SHRINK, 0); - detailsPanelContainer->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK, 4); + detailsPanelContainer->pack_start(*detailsPanel, Gtk::PACK_SHRINK); + detailsPanelContainer->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK); colorPanelSW->add (*colorPanelContainer); - colorPanelContainer->pack_start(*colorPanel, Gtk::PACK_SHRINK, 0); - colorPanelContainer->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK, 4); + colorPanelContainer->pack_start(*colorPanel, Gtk::PACK_SHRINK); + colorPanelContainer->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK); advancedPanelSW->add (*advancedPanelContainer); - advancedPanelContainer->pack_start(*advancedPanel, Gtk::PACK_SHRINK, 0); - advancedPanelContainer->pack_start (*vbPanelEnd[6], Gtk::PACK_SHRINK, 0); + advancedPanelContainer->pack_start(*advancedPanel, Gtk::PACK_SHRINK); + advancedPanelContainer->pack_start (*vbPanelEnd[6], Gtk::PACK_SHRINK); locallabPanelSW->add(*locallabPanelContainer); - locallabPanelContainer->pack_start(*locallabPanel, Gtk::PACK_SHRINK, 0); - locallabPanelContainer->pack_start(*vbPanelEnd[7], Gtk::PACK_SHRINK, 4); + locallabPanelContainer->pack_start(*locallabPanel, Gtk::PACK_SHRINK); + locallabPanelContainer->pack_start(*vbPanelEnd[7], Gtk::PACK_SHRINK); transformPanelSW->add (*transformPanelContainer); - transformPanelContainer->pack_start(*transformPanel, Gtk::PACK_SHRINK, 0); - transformPanelContainer->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 4); + transformPanelContainer->pack_start(*transformPanel, Gtk::PACK_SHRINK); + transformPanelContainer->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK); rawPanelSW->add (*rawPanelContainer); - rawPanelContainer->pack_start(*rawPanel, Gtk::PACK_SHRINK, 0); - rawPanelContainer->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0); + rawPanelContainer->pack_start(*rawPanel, Gtk::PACK_SHRINK); + rawPanelContainer->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK); toiF.reset(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"))); From 6a0067d7387365fc094ed66a698b46b771e84c34 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 24 Dec 2021 16:03:58 -0800 Subject: [PATCH 053/326] Disable favorite tool cloning by default Also add tooltip stating that tool cloning may cause a delay while switching between tabs. --- rtdata/languages/default | 1 + rtgui/options.cc | 2 +- rtgui/toollocationpref.cc | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index bd65781a8..d409c4393 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1902,6 +1902,7 @@ 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 diff --git a/rtgui/options.cc b/rtgui/options.cc index b5463949a..f597d3a1c 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -424,7 +424,7 @@ void Options::setDefaults() //crvOpen.clear (); parseExtensions.clear(); favorites.clear(); - cloneFavoriteTools = true; + cloneFavoriteTools = false; parseExtensionsEnabled.clear(); parsedExtensions.clear(); parsedExtensionsSet.clear(); diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index cf2386257..cf25dbc34 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -532,6 +532,8 @@ ToolLocationPreference::Impl::Impl(Options &options) : // General options. cloneFavoriteToolsToggleWidget->set_active(options.cloneFavoriteTools); + cloneFavoriteToolsToggleWidget->set_tooltip_text( + M("PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP")); // Tool list. toolListViewPtr->append_column(toolListViewColumnToolName); From 58f0783561d1244edfcd6413b4d8b9d8df98c95e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 5 Mar 2022 18:26:52 -0800 Subject: [PATCH 054/326] Allow selecting file as external editor --- rtdata/languages/default | 2 + rtgui/externaleditorpreferences.cc | 71 ++++++++++++++++++++++++++++++ rtgui/externaleditorpreferences.h | 19 ++++++++ 3 files changed, 92 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 538c25b00..4d80f56a9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -208,6 +208,7 @@ FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multi 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 @@ -1782,6 +1783,7 @@ PREFERENCES_EDITORCMDLINE;Custom command line PREFERENCES_EDITORLAYOUT;Editor layout PREFERENCES_EXTERNALEDITOR;External Editor PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application +PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command PREFERENCES_EXTEDITOR_DIR;Output directory diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 61bf8dc3a..c6ee9b93e 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -18,6 +18,11 @@ */ #include +#include +#include +#include +#include + #include "externaleditorpreferences.h" #include "multilangmgr.h" #include "rtimage.h" @@ -54,11 +59,14 @@ ExternalEditorPreferences::ExternalEditorPreferences(): button_add->set_image(*add_image); button_remove->set_image(*remove_image); button_app_chooser = Gtk::make_managed(M("PREFERENCES_EXTERNALEDITOR_CHANGE")); + button_file_chooser = Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE_FILE"))); button_app_chooser->signal_pressed().connect(sigc::mem_fun( *this, &ExternalEditorPreferences::openAppChooserDialog)); button_add->signal_pressed().connect(sigc::mem_fun( *this, &ExternalEditorPreferences::addEditor)); + button_file_chooser->signal_pressed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::openFileChooserDialog)); button_remove->signal_pressed().connect(sigc::mem_fun( *this, &ExternalEditorPreferences::removeSelectedEditors)); @@ -69,6 +77,7 @@ ExternalEditorPreferences::ExternalEditorPreferences(): // Toolbar. toolbar.set_halign(Gtk::Align::ALIGN_END); toolbar.add(*button_app_chooser); + toolbar.add(*button_file_chooser); toolbar.add(*button_add); toolbar.add(*button_remove); @@ -204,6 +213,38 @@ void ExternalEditorPreferences::onAppChooserDialogResponse( } } +void ExternalEditorPreferences::onFileChooserDialogResponse( + int response_id, Gtk::FileChooserDialog *dialog) +{ + switch (response_id) { + case Gtk::RESPONSE_OK: { + dialog->close(); + + auto selection = list_view->get_selection()->get_selected_rows(); + for (const auto &selected : selection) { + auto row = *list_model->get_iter(selected); + row[model_columns.icon] = Glib::RefPtr(nullptr); + row[model_columns.command] = +#ifdef WIN32 + '"' + dialog->get_filename() + '"'; +#else + Glib::shell_quote(dialog->get_filename()); +#endif + } + + break; + } + + case Gtk::RESPONSE_CANCEL: + case Gtk::RESPONSE_CLOSE: + dialog->close(); + break; + + default: + break; + } +} + void ExternalEditorPreferences::openAppChooserDialog() { if (app_chooser_dialog.get()) { @@ -221,6 +262,35 @@ void ExternalEditorPreferences::openAppChooserDialog() app_chooser_dialog->show(); } +void ExternalEditorPreferences::openFileChooserDialog() +{ + if (file_chooser_dialog.get()) { + file_chooser_dialog->show(); + return; + } + + file_chooser_dialog.reset(new Gtk::FileChooserDialog(M("PREFERENCES_EXTERNALEDITOR_CHANGE_FILE"))); + + const auto exe_filter = Gtk::FileFilter::create(); + exe_filter->set_name(M("FILECHOOSER_FILTER_EXECUTABLE")); + exe_filter->add_custom(Gtk::FILE_FILTER_MIME_TYPE, [](const Gtk::FileFilter::Info &info) { + return Gio::content_type_can_be_executable(info.mime_type); + }); + const auto all_filter = Gtk::FileFilter::create(); + all_filter->set_name(M("FILECHOOSER_FILTER_ANY")); + all_filter->add_pattern("*"); + file_chooser_dialog->add_filter(exe_filter); + file_chooser_dialog->add_filter(all_filter); + + file_chooser_dialog->signal_response().connect(sigc::bind( + sigc::mem_fun(*this, &ExternalEditorPreferences::onFileChooserDialogResponse), + file_chooser_dialog.get())); + file_chooser_dialog->set_modal(); + file_chooser_dialog->add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); + file_chooser_dialog->add_button(M("GENERAL_OPEN"), Gtk::RESPONSE_OK); + file_chooser_dialog->show(); +} + void ExternalEditorPreferences::removeSelectedEditors() { auto selection = list_view->get_selection()->get_selected_rows(); @@ -265,6 +335,7 @@ void ExternalEditorPreferences::updateToolbarSensitivity() { bool selected = list_view->get_selection()->count_selected_rows(); button_app_chooser->set_sensitive(selected); + button_file_chooser->set_sensitive(selected); button_remove->set_sensitive(selected); } diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index 5761d8b63..34658d942 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -28,6 +28,14 @@ #include "rtappchooserdialog.h" +namespace Gtk +{ + +class FileChooserDialog; + +} + + /** * Widget for editing the external editors options. */ @@ -98,8 +106,10 @@ private: Gtk::Box toolbar; // Contains buttons for editing the list. Gtk::Button *button_app_chooser; Gtk::Button *button_add; + Gtk::Button *button_file_chooser; Gtk::Button *button_remove; std::unique_ptr app_chooser_dialog; + std::unique_ptr file_chooser_dialog; /** * Inserts a new editor entry after the current selection, or at the end if @@ -119,10 +129,19 @@ private: * Closes the dialog and updates the selected entry if an app was chosen. */ void onAppChooserDialogResponse(int responseId, RTAppChooserDialog *dialog); + /** + * Called when the user is done interacting with the file chooser dialog. + * Closes the dialog and updates the selected entry if a file was chosen. + */ + void onFileChooserDialogResponse(int responseId, Gtk::FileChooserDialog *dialog); /** * Shows the app chooser dialog. */ void openAppChooserDialog(); + /** + * Shows the file chooser dialog for picking an executable. + */ + void openFileChooserDialog(); /** * Removes all selected editors. */ From 329341f89f78cd995e6266e97e19e76f08a419b2 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 5 Mar 2022 18:36:28 -0800 Subject: [PATCH 055/326] Replace Gtk::make_managed() with Gtk::manage() Maintain compatibility with gtkmm 3.16. --- rtgui/editorpanel.cc | 2 +- rtgui/externaleditorpreferences.cc | 22 +++++++++++----------- rtgui/popupcommon.cc | 12 ++++++------ rtgui/preferences.cc | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 987852891..a9797a216 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -671,7 +671,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) queueimg->set_tooltip_markup (M ("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP")); setExpandAlignProperties (queueimg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - send_to_external = Gtk::make_managed("", false); + send_to_external = Gtk::manage(new PopUpButton("", false)); send_to_external->set_tooltip_text(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); setExpandAlignProperties(send_to_external->buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER")); diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index c6ee9b93e..58a562725 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -34,7 +34,7 @@ ExternalEditorPreferences::ExternalEditorPreferences(): toolbar(Gtk::Orientation::ORIENTATION_HORIZONTAL) { // List view. - list_view = Gtk::make_managed(); + list_view = Gtk::manage(new Gtk::TreeView()); list_view->set_model(list_model); list_view->append_column(*Gtk::manage(makeAppColumn())); list_view->append_column(*Gtk::manage(makeCommandColumn())); @@ -52,13 +52,13 @@ ExternalEditorPreferences::ExternalEditorPreferences(): list_scroll_area.add(*list_view); // Toolbar buttons. - auto add_image = Gtk::make_managed("add-small.png"); - auto remove_image = Gtk::make_managed("remove-small.png"); - button_add = Gtk::make_managed(); - button_remove = Gtk::make_managed(); + 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_app_chooser = Gtk::make_managed(M("PREFERENCES_EXTERNALEDITOR_CHANGE")); + 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"))); button_app_chooser->signal_pressed().connect(sigc::mem_fun( @@ -159,9 +159,9 @@ void ExternalEditorPreferences::addEditor() Gtk::TreeViewColumn *ExternalEditorPreferences::makeAppColumn() { - auto name_renderer = Gtk::make_managed(); - auto icon_renderer = Gtk::make_managed(); - auto col = Gtk::make_managed(); + auto name_renderer = Gtk::manage(new Gtk::CellRendererText()); + auto icon_renderer = Gtk::manage(new Gtk::CellRendererPixbuf()); + auto col = Gtk::manage(new Gtk::TreeViewColumn()); col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_NAME")); col->set_resizable(); @@ -180,8 +180,8 @@ Gtk::TreeViewColumn *ExternalEditorPreferences::makeAppColumn() Gtk::TreeViewColumn *ExternalEditorPreferences::makeCommandColumn() { - auto command_renderer = Gtk::make_managed(); - auto col = Gtk::make_managed(); + auto command_renderer = Gtk::manage(new Gtk::CellRendererText()); + auto col = Gtk::manage(new Gtk::TreeViewColumn()); col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND")); col->pack_start(*command_renderer); diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index c33ac068e..1dbde833e 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -50,14 +50,14 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) buttonGroup->get_style_context()->add_class("image-combo"); // Create the image for the button - buttonImage = Gtk::make_managed(); + buttonImage = Gtk::manage(new RTImage()); setExpandAlignProperties(buttonImage, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); imageContainer->attach_next_to(*buttonImage, Gtk::POS_RIGHT, 1, 1); buttonImage->set_no_show_all(); // Create the button for showing the pop-up. - arrowButton = Gtk::make_managed(); - Gtk::Image *arrowImage = Gtk::make_managed(); + 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); setExpandAlignProperties(arrowButton, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); arrowButton->add(*arrowImage); //menuSymbol); @@ -82,7 +82,7 @@ bool PopUpCommon::insertEntry(int position, const Glib::ustring& fileName, const { RTImage* image = nullptr; if (!fileName.empty()) { - image = Gtk::make_managed(fileName); + image = Gtk::manage(new RTImage(fileName)); } bool success = insertEntryImpl(position, fileName, Glib::RefPtr(), image, label); if (!success && image) { @@ -93,7 +93,7 @@ bool PopUpCommon::insertEntry(int position, const Glib::ustring& fileName, const bool PopUpCommon::insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label) { - RTImage* image = Gtk::make_managed(gIcon, Gtk::ICON_SIZE_BUTTON); + RTImage* image = Gtk::manage(new RTImage(gIcon, Gtk::ICON_SIZE_BUTTON)); bool success = insertEntryImpl(position, "", gIcon, image, label); if (!success) { delete image; @@ -107,7 +107,7 @@ bool PopUpCommon::insertEntryImpl(int position, const Glib::ustring& fileName, c return false; // Create the menu item and image - MyImageMenuItem *newItem = Gtk::make_managed(label, image); + MyImageMenuItem *newItem = Gtk::manage(new MyImageMenuItem(label, image)); imageIcons.insert(imageIcons.begin() + position, gIcon); imageFilenames.insert(imageFilenames.begin() + position, fileName); images.insert(images.begin() + position, newItem->getImage()); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index a8f5c64a3..734e74e91 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1249,7 +1249,7 @@ Gtk::Widget* Preferences::getGeneralPanel() #endif #endif - externalEditors = Gtk::make_managed(); + externalEditors = Gtk::manage(new ExternalEditorPreferences()); externalEditors->set_size_request(-1, 200); #ifdef EXT_EDITORS_RADIOS externaleditorGrid->attach_next_to(*externalEditors, *edOther, Gtk::POS_BOTTOM, 2, 1); From 793a77fc4484505645106547ee952dfd2e2d30a8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 6 Mar 2022 11:52:09 -0800 Subject: [PATCH 056/326] Add missing include --- rtgui/extprog.h | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/extprog.h b/rtgui/extprog.h index 86dbc1674..cdcf14e48 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -20,6 +20,7 @@ #include +#include #include #include "threadutils.h" From ba906af841a47438512ff3f67202b0760b3a6b0e Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Fri, 25 Mar 2022 15:47:40 +0100 Subject: [PATCH 057/326] dcraw: increase linear table parsing to 65536 values The dcraw linear_table method limits the max values to 4096. But 16 bit per channel linear DNGs can provide a LinearizationTable with 65536 entries. This patch changes the dcraw linear_table method to accept 65536 entries. --- rtengine/dcraw.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 39e527598..95df2d21b 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6292,11 +6292,11 @@ void CLASS parse_mos (int offset) void CLASS linear_table (unsigned len) { int i; - if (len > 0x1000) len = 0x1000; + if (len > 0x10000) len = 0x10000; read_shorts (curve, len); - for (i=len; i < 0x1000; i++) + for (i=len; i < 0x10000; i++) curve[i] = curve[i-1]; - maximum = curve[0xfff]; + maximum = curve[0xffff]; } void CLASS parse_kodak_ifd (int base) From bd3bd809b5415b875c0a8d38c18cfb0c1cc2e34a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 1 May 2022 16:13:27 -0700 Subject: [PATCH 058/326] Port tone equalizer from ART Merge with local adjustments tone equalizer image processing function for consistent results. To-do: Enable for batch editing and add pivot/colormap to the local adjustments version. --- rtdata/languages/default | 15 ++ rtengine/CMakeLists.txt | 1 + rtengine/imagefloat.cc | 68 ++++--- rtengine/imagefloat.h | 5 +- rtengine/improccoordinator.cc | 1 + rtengine/improcfun.cc | 6 + rtengine/improcfun.h | 4 +- rtengine/iplocallab.cc | 227 +-------------------- rtengine/iptoneequalizer.cc | 362 ++++++++++++++++++++++++++++++++++ rtengine/procparams.cc | 44 +++++ rtengine/procparams.h | 17 ++ rtgui/CMakeLists.txt | 1 + rtgui/adjuster.cc | 27 ++- rtgui/adjuster.h | 2 + rtgui/paramsedited.cc | 30 +++ rtgui/paramsedited.h | 9 + rtgui/partialpastedlg.cc | 9 + rtgui/partialpastedlg.h | 2 + rtgui/thumbnail.cc | 1 + rtgui/toneequalizer.cc | 169 ++++++++++++++++ rtgui/toneequalizer.h | 56 ++++++ rtgui/toolpanelcoord.cc | 2 + rtgui/toolpanelcoord.h | 2 + 23 files changed, 794 insertions(+), 266 deletions(-) create mode 100644 rtengine/iptoneequalizer.cc create mode 100644 rtgui/toneequalizer.cc create mode 100644 rtgui/toneequalizer.h diff --git a/rtdata/languages/default b/rtdata/languages/default index a3e99cfc2..6dd32ef7b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1520,6 +1520,11 @@ 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 @@ -1827,6 +1832,7 @@ PARTIALPASTE_SHARPENMICRO;Microcontrast PARTIALPASTE_SOFTLIGHT;Soft light PARTIALPASTE_SPOT;Spot removal PARTIALPASTE_TM_FATTAL;Dynamic range compression +PARTIALPASTE_TONE_EQUALIZER;Tone equalizer PARTIALPASTE_VIBRANCE;Vibrance PARTIALPASTE_VIGNETTING;Vignetting correction PARTIALPASTE_WHITEBALANCE;White balance @@ -3837,6 +3843,15 @@ 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_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_AVOIDCOLORSHIFT;Avoid color shift TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 1f3cf352b..3cc8df625 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -133,6 +133,7 @@ set(RTENGINESOURCEFILES ipsharpen.cc ipsharpenedges.cc ipsoftlight.cc + iptoneequalizer.cc iptransform.cc ipvibrance.cc ipwavelet.cc diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 7bc75fe6d..e4cb28e6b 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -341,6 +341,38 @@ void Imagefloat::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* imag #endif } +// From ART. +void Imagefloat::multiply(float factor, bool multithread) +{ + const int W = width; + const int H = height; +#ifdef __SSE2__ + vfloat vfactor = F2V(factor); +#endif + +#ifdef _OPENMP +# pragma omp parallel for firstprivate(W, H) schedule(dynamic, 5) if (multithread) +#endif + for (int y = 0; y < H; y++) { + int x = 0; +#ifdef __SSE2__ + for (; x < W-3; x += 4) { + vfloat rv = LVF(r(y, x)); + vfloat gv = LVF(g(y, x)); + vfloat bv = LVF(b(y, x)); + STVF(r(y, x), rv * vfactor); + STVF(g(y, x), gv * vfactor); + STVF(b(y, x), bv * vfactor); + } +#endif + for (; x < W; ++x) { + r(y, x) *= factor; + g(y, x) *= factor; + b(y, x) *= factor; + } + } +} + void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal) { @@ -362,43 +394,15 @@ void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal) } // convert values's range to [0;1] ; this method assumes that the input values's range is [0;65535] -void Imagefloat::normalizeFloatTo1() +void Imagefloat::normalizeFloatTo1(bool multithread) { - - const int w = width; - const int h = height; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 5) -#endif - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - r(y, x) /= 65535.f; - g(y, x) /= 65535.f; - b(y, x) /= 65535.f; - } - } + multiply(1.f/65535.f, multithread); } // convert values's range to [0;65535 ; this method assumes that the input values's range is [0;1] -void Imagefloat::normalizeFloatTo65535() +void Imagefloat::normalizeFloatTo65535(bool multithread) { - - const int w = width; - const int h = height; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 5) -#endif - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - r(y, x) *= 65535.f; - g(y, x) *= 65535.f; - b(y, x) *= 65535.f; - } - } + multiply(65535.f, multithread); } // Parallelized transformation; create transform with cmsFLAGS_NOCACHE! diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index fc3ba318d..3bee52d9a 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -207,9 +207,10 @@ public: return (uint32_t) ((lsign << 31) | (exponent << 23) | mantissa); } + void multiply(float factor, bool multithread); void normalizeFloat(float srcMinVal, float srcMaxVal) override; - void normalizeFloatTo1(); - void normalizeFloatTo65535(); + void normalizeFloatTo1(bool multithread=true); + void normalizeFloatTo65535(bool multithread=true); void ExecCMSTransform(cmsHTRANSFORM hTransform); void ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy); }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 33cce1842..cb9f6500f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -2734,6 +2734,7 @@ void ImProcCoordinator::process() || params->epd != nextParams->epd || params->fattal != nextParams->fattal || params->sh != nextParams->sh + || params->toneEqualizer != nextParams->toneEqualizer || params->crop != nextParams->crop || params->coarse != nextParams->coarse || params->commonTrans != nextParams->commonTrans diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 15ebcc2e6..e50e28a01 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2258,6 +2258,12 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer // For tonecurve histogram const float lumimulf[3] = {static_cast(lumimul[0]), static_cast(lumimul[1]), static_cast(lumimul[2])}; + std::unique_ptr workimg_copy; + if (params->toneEqualizer.enabled) { + working = working->copy(); + workimg_copy.reset(working); + toneEqualizer(working); + } #define TS 112 diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 1be1d0371..70aed428c 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -97,6 +97,7 @@ struct LocalContrastParams; struct LocallabParams; struct SharpeningParams; struct SoftLightParams; +struct ToneEqualizerParams; struct VibranceParams; struct VignettingParams; struct WaveletParams; @@ -491,7 +492,8 @@ enum class BlurType { void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); //void shadowsHighlights(LabImage *lab); void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal); - + bool toneEqualizer(Imagefloat *rgb); + static void toneEqualizer(array2D &R, array2D &G, array2D &B, const procparams::ToneEqualizerParams & params, const Glib::ustring &workingProfile, double scale, bool multithread, bool show_color_map); void softLight(LabImage *lab, const procparams::SoftLightParams &softLightParams); void labColorCorrectionRegions(LabImage *lab); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index ac87c75d7..7a427b0eb 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2258,230 +2258,11 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, } void tone_eq(array2D &R, array2D &G, array2D &B, const struct local_params & lp, const Glib::ustring &workingProfile, double scale, bool multithread) -// adapted from the tone equalizer of darktable -/* - Copyright 2019 Alberto Griggio - Small adaptation to Local Adjustment 10 2019 Jacques Desmis - This file is part of darktable, - copyright (c) 2018 Aurelien Pierre. - - 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 . -*/ - { - // BENCHFUN - - const int W = R.getWidth(); - const int H = R.getHeight(); - array2D Y(W, H); - - const auto log2 = - [](float x) -> float { - static const float l2 = xlogf(2); - return xlogf(x) / l2; - }; - - const auto exp2 = - [](float x) -> float { - return pow_F(2.f, x); - }; - // Build the luma channels: band-pass filters with gaussian windows of - // std 2 EV, spaced by 2 EV - const float centers[12] = { - -18.0f, -16.0f, -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, - -4.0f, -2.0f, 0.0f, 2.0f, 4.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] = { - conv(lp.mullocsh[0], 2.f, 3.f), // -18 EV - conv(lp.mullocsh[0], 2.f, 3.f), // -16 EV - conv(lp.mullocsh[0], 2.f, 3.f), // -14 EV - conv(lp.mullocsh[0], 2.f, 3.f), // -12 EV - conv(lp.mullocsh[0], 2.f, 3.f), // -10 EV - conv(lp.mullocsh[0], 2.f, 3.f), // -8 EV - conv(lp.mullocsh[1], 2.f, 3.f), // -6 EV - conv(lp.mullocsh[2], 2.5f, 2.5f), // -4 EV - conv(lp.mullocsh[3], 3.f, 2.f), // -2 EV - conv(lp.mullocsh[4], 3.f, 2.f), // 0 EV - conv(lp.mullocsh[4], 3.f, 2.f), // 2 EV - conv(lp.mullocsh[4], 3.f, 2.f) // 4 EV - }; - - TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(workingProfile); - -#ifdef _OPENMP - #pragma omp parallel for if (multithread) -#endif - for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { - Y[y][x] = Color::rgbLuminance(R[y][x], G[y][x], B[y][x], ws); - } - } - - int detail = LIM(lp.detailsh + 5, 0, 5); - int radius = detail / scale + 0.5; - float epsilon2 = 0.01f + 0.002f * rtengine::max(detail - 3, 0); - - if (radius > 0) { - rtengine::guidedFilterLog(10.f, Y, radius, epsilon2, multithread); - } - - if (lp.detailsh > 0) { - array2D Y2(W, H); - constexpr float base_epsilon = 0.02f; - constexpr float base_posterization = 5.f; - -#ifdef _OPENMP - #pragma omp parallel for if (multithread) -#endif - for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { - float l = LIM(log2(rtengine::max(Y[y][x], 1e-9f)), centers[0], centers[11]); - float ll = round(l * base_posterization) / base_posterization; - Y2[y][x] = Y[y][x]; - Y[y][x] = exp2(ll); - } - } - - radius = 350.0 / scale; - epsilon2 = base_epsilon / float(6 - rtengine::min(lp.detailsh, 5)); - rtengine::guidedFilter(Y2, Y, Y, radius, epsilon2, multithread); - } - - const auto gauss = - [](float b, float x) -> float { - return xexpf((-SQR(x - b) / 4.0f)); - }; - - // For every pixel luminance, the sum of the gaussian masks - float w_sum = 0.f; - - for (int i = 0; i < 12; ++i) { - w_sum += gauss(centers[i], 0.f); - } - - const auto process_pixel = - [&](float y) -> float { - // convert to log space - const float luma = rtengine::max(log2(rtengine::max(y, 0.f)), -18.0f); - - // build the correction as the sum of the contribution of each - // luminance channel to current pixel - float correction = 0.0f; - - for (int c = 0; c < 12; ++c) - { - correction += gauss(centers[c], luma) * factors[c]; - } - - correction /= w_sum; - - return correction; - }; - - LUTf lut(65536); - - for (int i = 0; i < 65536; ++i) { - float y = float(i) / 65535.f; - float c = process_pixel(y); - lut[i] = c; - } - - -#ifdef __SSE2__ - vfloat vfactors[12]; - vfloat vcenters[12]; - - for (int i = 0; i < 12; ++i) { - vfactors[i] = F2V(factors[i]); - vcenters[i] = F2V(centers[i]); - } - - const auto vgauss = - [](vfloat b, vfloat x) -> vfloat { - static const vfloat fourv = F2V(4.f); - return xexpf((-SQR(x - b) / fourv)); - }; - - vfloat zerov = F2V(0.f); - vfloat vw_sum = F2V(w_sum); - - const vfloat noisev = F2V(-18.f); - const vfloat xlog2v = F2V(xlogf(2.f)); - - const auto vprocess_pixel = - [&](vfloat y) -> vfloat { - const vfloat luma = vmaxf(xlogf(vmaxf(y, zerov)) / xlog2v, noisev); - - vfloat correction = zerov; - - for (int c = 0; c < 12; ++c) - { - correction += vgauss(vcenters[c], luma) * vfactors[c]; - } - - correction /= vw_sum; - - return correction; - }; - - - vfloat v1 = F2V(1.f); - vfloat v65535 = F2V(65535.f); -#endif // __SSE2__ - - -#ifdef _OPENMP - #pragma omp parallel for if (multithread) -#endif - for (int y = 0; y < H; ++y) { - int x = 0; - - -#ifdef __SSE2__ - - for (; x < W - 3; x += 4) { - vfloat cY = LVFU(Y[y][x]); - vmask m = vmaskf_gt(cY, v1); - vfloat corr; - - if (_mm_movemask_ps((vfloat)m)) { - corr = vprocess_pixel(cY); - } else { - corr = lut[cY * v65535]; - } - - STVF(R[y][x], LVF(R[y][x]) * corr); - STVF(G[y][x], LVF(G[y][x]) * corr); - STVF(B[y][x], LVF(B[y][x]) * corr); - } - -#endif // __SSE2__ - - for (; x < W; ++x) { - float cY = Y[y][x]; - float corr = cY > 1.f ? process_pixel(cY) : lut[cY * 65535.f]; - R[y][x] *= corr; - G[y][x] *= corr; - B[y][x] *= corr; - } - } - + ToneEqualizerParams params; + params.regularization = lp.detailsh; + std::copy(lp.mullocsh, lp.mullocsh + params.bands.size(), params.bands.begin()); + ImProcFunctions::toneEqualizer(R, G, B, params, workingProfile, scale, multithread, false); } void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float stren, int sk) { diff --git a/rtengine/iptoneequalizer.cc b/rtengine/iptoneequalizer.cc new file mode 100644 index 000000000..c177b8f98 --- /dev/null +++ b/rtengine/iptoneequalizer.cc @@ -0,0 +1,362 @@ +#include "color.h" +#include "guidedfilter.h" +#include "iccstore.h" +#include "imagefloat.h" +#include "improcfun.h" +#include "sleef.h" +#include "StopWatch.h" + + +namespace +{ + +const std::vector> colormap = { + {0.5f, 0.f, 0.5f}, + {0.5f, 0.f, 0.5f}, + {0.5f, 0.f, 0.5f}, + {0.5f, 0.f, 0.5f}, + {0.5f, 0.f, 0.5f}, + {0.5f, 0.f, 0.5f}, // blacks + {0.f, 0.f, 1.f}, // shadows + {0.5f, 0.5f, 0.5f}, // midtones + {1.f, 1.f, 0.f}, // highlights + {1.f, 0.f, 0.f}, // whites + {1.f, 0.f, 0.f}, + {1.f, 0.f, 0.f} +}; + +} + + +namespace rtengine +{ + +void ImProcFunctions::toneEqualizer( + array2D &R, array2D &G, array2D &B, + const struct ToneEqualizerParams ¶ms, + const Glib::ustring &workingProfile, + double scale, + bool multithread, + bool show_color_map) +// adapted from the tone equalizer of darktable +/* + Copyright 2019 Alberto Griggio + Small adaptation to Local Adjustment 10 2019 Jacques Desmis + This file is part of darktable, + copyright (c) 2018 Aurelien Pierre. + + 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 . +*/ + +{ + // BENCHFUN + + const int W = R.getWidth(); + const int H = R.getHeight(); + array2D Y(W, H); + + const auto log2 = + [](float x) -> float { + static const float l2 = xlogf(2); + return xlogf(x) / l2; + }; + + const auto exp2 = + [](float x) -> float { + return pow_F(2.f, x); + }; + // Build the luma channels: band-pass filters with gaussian windows of + // std 2 EV, spaced by 2 EV + const float centers[12] = { + -18.0f, -16.0f, -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, + -4.0f, -2.0f, 0.0f, 2.0f, 4.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] = { + conv(params.bands[0], 2.f, 3.f), // -18 EV + 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 + conv(params.bands[0], 2.f, 3.f), // -10 EV + conv(params.bands[0], 2.f, 3.f), // -8 EV + conv(params.bands[1], 2.f, 3.f), // -6 EV + conv(params.bands[2], 2.5f, 2.5f), // -4 EV + conv(params.bands[3], 3.f, 2.f), // -2 EV + 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 + }; + + TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(workingProfile); + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + Y[y][x] = Color::rgbLuminance(R[y][x], G[y][x], B[y][x], ws); + } + } + + int detail = LIM(params.regularization + 5, 0, 5); + int radius = detail / scale + 0.5; + float epsilon2 = 0.01f + 0.002f * rtengine::max(detail - 3, 0); + + if (radius > 0) { + rtengine::guidedFilterLog(10.f, Y, radius, epsilon2, multithread); + } + + if (params.regularization > 0) { + array2D Y2(W, H); + constexpr float base_epsilon = 0.02f; + constexpr float base_posterization = 5.f; + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + float l = LIM(log2(rtengine::max(Y[y][x], 1e-9f)), centers[0], centers[11]); + float ll = round(l * base_posterization) / base_posterization; + Y2[y][x] = Y[y][x]; + Y[y][x] = exp2(ll); + } + } + + radius = 350.0 / scale; + epsilon2 = base_epsilon / float(6 - rtengine::min(params.regularization, 5)); + rtengine::guidedFilter(Y2, Y, Y, radius, epsilon2, multithread); + } + + const auto gauss = + [](float b, float x) -> float { + return xexpf((-SQR(x - b) / 4.0f)); + }; + + // For every pixel luminance, the sum of the gaussian masks + float w_sum = 0.f; + + for (int i = 0; i < 12; ++i) { + w_sum += gauss(centers[i], 0.f); + } + + const auto process_pixel = + [&](float y) -> float { + // convert to log space + const float luma = rtengine::max(log2(rtengine::max(y, 0.f)), -18.0f); + + // build the correction as the sum of the contribution of each + // luminance channel to current pixel + float correction = 0.0f; + + for (int c = 0; c < 12; ++c) + { + correction += gauss(centers[c], luma) * factors[c]; + } + + correction /= w_sum; + + return correction; + }; + + std::vector> cur_colormap; + if (show_color_map) { + lcmsMutex->lock(); + cmsHPROFILE in = ICCStore::getInstance()->getsRGBProfile(); + cmsHPROFILE out = ICCStore::getInstance()->workingSpace(workingProfile); + cmsHTRANSFORM xform = cmsCreateTransform(in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock(); + + for (auto &c : colormap) { + cur_colormap.push_back(c); + auto &cc = cur_colormap.back(); + cmsDoTransform(xform, &cc[0], &cc[0], 1); + } + + cmsDeleteTransform(xform); + } + + const auto process_colormap = + [&](float y) -> std::array + { + std::array ret = { 0.f, 0.f, 0.f }; + + // convert to log space + const float luma = max(log2(max(y, 0.f)), -18.0f); + + // build the correction as the sum of the contribution of each + // luminance channel to current pixel + for (int c = 0; c < 12; ++c) { + float w = gauss(centers[c], luma); + for (int i = 0; i < 3; ++i) { + ret[i] += w * cur_colormap[c][i]; + } + } + for (int i = 0; i < 3; ++i) { + ret[i] = LIM01(ret[i] / w_sum); + } + + return ret; + }; + + +#ifdef __SSE2__ + vfloat vfactors[12]; + vfloat vcenters[12]; + + for (int i = 0; i < 12; ++i) { + vfactors[i] = F2V(factors[i]); + vcenters[i] = F2V(centers[i]); + } + + const auto vgauss = + [](vfloat b, vfloat x) -> vfloat { + static const vfloat fourv = F2V(4.f); + return xexpf((-SQR(x - b) / fourv)); + }; + + vfloat zerov = F2V(0.f); + vfloat vw_sum = F2V(w_sum); + + const vfloat noisev = F2V(-18.f); + const vfloat xlog2v = F2V(xlogf(2.f)); + + const auto vprocess_pixel = + [&](vfloat y) -> vfloat { + const vfloat luma = vmaxf(xlogf(vmaxf(y, zerov)) / xlog2v, noisev); + + vfloat correction = zerov; + + for (int c = 0; c < 12; ++c) + { + correction += vgauss(vcenters[c], luma) * vfactors[c]; + } + + correction /= vw_sum; + + return correction; + }; + + + vfloat v1 = F2V(1.f); + vfloat v65535 = F2V(65535.f); +#endif // __SSE2__ + + + if (show_color_map) { + LUTf lut_r(65537), lut_g(65537), lut_b(65537); + for (int i = 0; i < 65536; ++i) { + float y = float(i)/65535.f; + auto rgb = process_colormap(y); + lut_r[i] = rgb[0]; + lut_g[i] = rgb[1]; + lut_b[i] = rgb[2]; + } + lut_r[65536] = cur_colormap.back()[0]; + lut_g[65536] = cur_colormap.back()[1]; + lut_b[65536] = cur_colormap.back()[2]; + +#ifdef _OPENMP +# pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + float cY = Y[y][x] * 65535.f; + R[y][x] = lut_r[cY]; + G[y][x] = lut_g[cY]; + B[y][x] = lut_b[cY]; + } + } + return; + } + + + LUTf lut(65536); + + for (int i = 0; i < 65536; ++i) { + float y = float(i) / 65535.f; + float c = process_pixel(y); + lut[i] = c; + } + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + int x = 0; + + +#ifdef __SSE2__ + + for (; x < W - 3; x += 4) { + vfloat cY = LVFU(Y[y][x]); + vmask m = vmaskf_gt(cY, v1); + vfloat corr; + + if (_mm_movemask_ps((vfloat)m)) { + corr = vprocess_pixel(cY); + } else { + corr = lut[cY * v65535]; + } + + STVF(R[y][x], LVF(R[y][x]) * corr); + STVF(G[y][x], LVF(G[y][x]) * corr); + STVF(B[y][x], LVF(B[y][x]) * corr); + } + +#endif // __SSE2__ + + for (; x < W; ++x) { + float cY = Y[y][x]; + float corr = cY > 1.f ? process_pixel(cY) : lut[cY * 65535.f]; + R[y][x] *= corr; + G[y][x] *= corr; + B[y][x] *= corr; + } + } + +} + +bool ImProcFunctions::toneEqualizer(Imagefloat *rgb) +{ + if (!params->toneEqualizer.enabled) { + return false; + } + + BENCHFUN + + const float gain = 1.f / 65535.f * std::pow(2.f, -params->toneEqualizer.pivot); + + rgb->multiply(gain, multiThread); + + const int W = rgb->getWidth(); + const int H = rgb->getHeight(); + + array2D R(W, H, rgb->r.ptrs, ARRAY2D_BYREFERENCE); + array2D G(W, H, rgb->g.ptrs, ARRAY2D_BYREFERENCE); + array2D B(W, H, rgb->b.ptrs, ARRAY2D_BYREFERENCE); + + bool show_color_map = params->toneEqualizer.show_colormap; + toneEqualizer(R, G, B, params->toneEqualizer, params->icm.workingProfile, scale, multiThread, show_color_map); + + rgb->multiply(1.f/gain, multiThread); + + return show_color_map; +} + +} diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9a9e4fef1..555af6879 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1786,6 +1786,30 @@ bool SHParams::operator !=(const SHParams& other) const return !(*this == other); } +ToneEqualizerParams::ToneEqualizerParams() : + enabled(false), + bands{0, 0, 0, 0, 0}, + regularization(4), + show_colormap(false), + pivot(0) +{ +} + +bool ToneEqualizerParams::operator ==(const ToneEqualizerParams &other) const +{ + return + enabled == other.enabled + && bands == other.bands + && regularization == other.regularization + && show_colormap == other.show_colormap + && pivot == other.pivot; +} + +bool ToneEqualizerParams::operator !=(const ToneEqualizerParams &other) const +{ + return !(*this == other); +} + CropParams::CropParams() : enabled(false), x(-1), @@ -5814,6 +5838,8 @@ void ProcParams::setDefaults() sh = {}; + toneEqualizer = {}; + crop = {}; coarse = {}; @@ -6241,6 +6267,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->sh.radius, "Shadows & Highlights", "Radius", sh.radius, keyFile); saveToKeyfile(!pedited || pedited->sh.lab, "Shadows & Highlights", "Lab", sh.lab, keyFile); +// Tone equalizer + saveToKeyfile(!pedited || pedited->toneEqualizer.enabled, "ToneEqualizer", "Enabled", toneEqualizer.enabled, keyFile); + for (size_t i = 0; i < toneEqualizer.bands.size(); ++i) { + saveToKeyfile(!pedited || pedited->toneEqualizer.bands, "ToneEqualizer", "Band" + std::to_string(i), toneEqualizer.bands[i], keyFile); + } + saveToKeyfile(!pedited || pedited->toneEqualizer.regularization, "ToneEqualizer", "Regularization", toneEqualizer.regularization, keyFile); + saveToKeyfile(!pedited || pedited->toneEqualizer.pivot, "ToneEqualizer", "Pivot", toneEqualizer.pivot, keyFile); + // Crop saveToKeyfile(!pedited || pedited->crop.enabled, "Crop", "Enabled", crop.enabled, keyFile); saveToKeyfile(!pedited || pedited->crop.x, "Crop", "X", crop.x, keyFile); @@ -8226,6 +8260,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } + if (keyFile.has_group("ToneEqualizer")) { + assignFromKeyfile(keyFile, "ToneEqualizer", "Enabled", pedited, 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); + } + assignFromKeyfile(keyFile, "ToneEqualizer", "Regularization", pedited, toneEqualizer.regularization, pedited->toneEqualizer.regularization); + assignFromKeyfile(keyFile, "ToneEqualizer", "Pivot", pedited, 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); @@ -10447,6 +10490,7 @@ bool ProcParams::operator ==(const ProcParams& other) const && fattal == other.fattal && defringe == other.defringe && sh == other.sh + && toneEqualizer == other.toneEqualizer && crop == other.crop && coarse == other.coarse && rotate == other.rotate diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 04229867b..5a86b40a0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -827,6 +827,22 @@ struct SHParams { bool operator !=(const SHParams& other) const; }; +/** + * Tone equalizer parameters. + */ +struct ToneEqualizerParams { + bool enabled; + std::array bands; + int regularization; + bool show_colormap; + double pivot; + + ToneEqualizerParams(); + + bool operator ==(const ToneEqualizerParams &other) const; + bool operator !=(const ToneEqualizerParams &other) const; +}; + /** * Parameters of the cropping */ @@ -2547,6 +2563,7 @@ public: EPDParams epd; ///< Edge Preserving Decomposition parameters FattalToneMappingParams fattal; ///< Fattal02 tone mapping SHParams sh; ///< Shadow/highlight enhancement parameters + ToneEqualizerParams toneEqualizer; ///< Tone equalizer parameters CropParams crop; ///< Crop parameters CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters CommonTransformParams commonTrans; ///< Common transformation parameters (autofill) diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 7976bdc7a..1d56f2638 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -159,6 +159,7 @@ set(NONCLISOURCEFILES thumbimageupdater.cc thumbnail.cc tonecurve.cc + toneequalizer.cc toolbar.cc toolpanel.cc toolpanelcoord.cc diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index a2f96cac3..3fe3d61eb 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -51,6 +51,7 @@ Adjuster::Adjuster( grid(nullptr), label(nullptr), imageIcon1(imgIcon1), + imageIcon2(imgIcon2), automatic(nullptr), adjusterListener(nullptr), spinChange(options.adjusterMinDelay, options.adjusterMaxDelay), @@ -76,8 +77,8 @@ Adjuster::Adjuster( setExpandAlignProperties(imageIcon1, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); } - if (imgIcon2) { - setExpandAlignProperties(imgIcon2, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + if (imageIcon2) { + setExpandAlignProperties(imageIcon2, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); } set_column_spacing(0); @@ -120,9 +121,9 @@ Adjuster::Adjuster( attach_next_to(*imageIcon1, *slider, Gtk::POS_LEFT, 1, 1); } - if (imgIcon2) { - attach_next_to(*imgIcon2, *slider, Gtk::POS_RIGHT, 1, 1); - attach_next_to(*spin, *imgIcon2, Gtk::POS_RIGHT, 1, 1); + if (imageIcon2) { + attach_next_to(*imageIcon2, *slider, Gtk::POS_RIGHT, 1, 1); + attach_next_to(*spin, *imageIcon2, Gtk::POS_RIGHT, 1, 1); } else { attach_next_to(*spin, *slider, Gtk::POS_RIGHT, 1, 1); } @@ -140,9 +141,9 @@ Adjuster::Adjuster( grid->attach_next_to(*imageIcon1, *slider, Gtk::POS_LEFT, 1, 1); } - if (imgIcon2) { - grid->attach_next_to(*imgIcon2, Gtk::POS_RIGHT, 1, 1); - grid->attach_next_to(*reset, *imgIcon2, Gtk::POS_RIGHT, 1, 1); + if (imageIcon2) { + grid->attach_next_to(*imageIcon2, Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*reset, *imageIcon2, Gtk::POS_RIGHT, 1, 1); } else { grid->attach_next_to(*reset, *slider, Gtk::POS_RIGHT, 1, 1); } @@ -683,3 +684,13 @@ void Adjuster::setDelay(unsigned int min_delay_ms, unsigned int max_delay_ms) spinChange.setDelay(min_delay_ms, max_delay_ms); sliderChange.setDelay(min_delay_ms, max_delay_ms); } + +void Adjuster::showIcons(bool yes) +{ + if (imageIcon1) { + imageIcon1->set_visible(yes); + } + if (imageIcon2) { + imageIcon2->set_visible(yes); + } +} diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index abafbd730..76b46b094 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -41,6 +41,7 @@ protected: Gtk::Grid* grid; Gtk::Label* label; Gtk::Image *imageIcon1; + Gtk::Image *imageIcon2; MyHScale* slider; MySpinButton* spin; Gtk::Button* reset; @@ -133,4 +134,5 @@ public: void trimValue (int &val) const; void setLogScale(double base, double pivot, bool anchorMiddle = false); void setDelay(unsigned int min_delay_ms, unsigned int max_delay_ms = 0); + void showIcons(bool yes); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 529d57da6..ff48a58b1 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -317,6 +317,11 @@ void ParamsEdited::set(bool v) sh.stonalwidth = v; sh.radius = v; sh.lab = v; + toneEqualizer.enabled = v; + toneEqualizer.bands = v; + toneEqualizer.regularization = v; + toneEqualizer.show_colormap = v; + toneEqualizer.pivot = v; crop.enabled = v; crop.x = v; crop.y = v; @@ -1031,6 +1036,11 @@ void ParamsEdited::initFrom(const std::vector& crop.ratio = crop.ratio && p.crop.ratio == other.crop.ratio; crop.orientation = crop.orientation && p.crop.orientation == other.crop.orientation; crop.guide = crop.guide && p.crop.guide == other.crop.guide; + toneEqualizer.enabled = toneEqualizer.enabled && p.toneEqualizer.enabled == other.toneEqualizer.enabled; + toneEqualizer.bands = toneEqualizer.bands && p.toneEqualizer.bands == other.toneEqualizer.bands; + toneEqualizer.regularization = toneEqualizer.regularization && p.toneEqualizer.regularization == other.toneEqualizer.regularization; + toneEqualizer.show_colormap = toneEqualizer.show_colormap && p.toneEqualizer.show_colormap == other.toneEqualizer.show_colormap; + toneEqualizer.pivot = toneEqualizer.pivot && p.toneEqualizer.pivot == other.toneEqualizer.pivot; coarse.rotate = coarse.rotate && p.coarse.rotate == other.coarse.rotate; coarse.hflip = coarse.hflip && p.coarse.hflip == other.coarse.hflip; coarse.vflip = coarse.vflip && p.coarse.vflip == other.coarse.vflip; @@ -3194,6 +3204,26 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.sh.lab = mods.sh.lab; } + if (toneEqualizer.enabled) { + toEdit.toneEqualizer.enabled = mods.toneEqualizer.enabled; + } + + if (toneEqualizer.bands) { + toEdit.toneEqualizer.bands = mods.toneEqualizer.bands; + } + + if (toneEqualizer.regularization) { + toEdit.toneEqualizer.regularization = mods.toneEqualizer.regularization; + } + + if (toneEqualizer.show_colormap) { + toEdit.toneEqualizer.show_colormap = mods.toneEqualizer.show_colormap; + } + + if (toneEqualizer.pivot) { + toEdit.toneEqualizer.pivot = mods.toneEqualizer.pivot; + } + if (crop.enabled) { toEdit.crop.enabled = mods.crop.enabled; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 94abed470..d70336a54 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -358,6 +358,14 @@ struct SHParamsEdited { bool lab; }; +struct ToneEqualizerParamsEdited { + bool enabled; + bool bands; + bool regularization; + bool show_colormap; + bool pivot; +}; + struct CropParamsEdited { bool enabled; bool x; @@ -1545,6 +1553,7 @@ struct ParamsEdited { FattalToneMappingParamsEdited fattal; ImpulseDenoiseParamsEdited impulseDenoise; SHParamsEdited sh; + ToneEqualizerParamsEdited toneEqualizer; CropParamsEdited crop; CoarseTransformParamsEdited coarse; CommonTransformParamsEdited commonTrans; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index b3c49dfd7..08cf23f72 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -219,6 +219,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren wb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WHITEBALANCE"))); exposure = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXPOSURE"))); sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS"))); + toneEqualizer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_TONE_EQUALIZER"))); epd = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EPD"))); fattal = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_TM_FATTAL"))); pcvignette = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PCVIGNETTE"))); @@ -331,6 +332,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[0]->pack_start (*wb, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*exposure, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*sh, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*toneEqualizer, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*epd, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*fattal, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*pcvignette, Gtk::PACK_SHRINK, 2); @@ -496,6 +498,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren wbConn = wb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); exposureConn = exposure->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); shConn = sh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + toneEqualizerConn = toneEqualizer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); epdConn = epd->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); fattalConn = fattal->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); pcvignetteConn = pcvignette->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); @@ -701,6 +704,7 @@ void PartialPasteDlg::basicToggled () ConnectionBlocker wbBlocker(wbConn); ConnectionBlocker exposureBlocker(exposureConn); ConnectionBlocker shBlocker(shConn); + ConnectionBlocker toneEqualizerBlocker(toneEqualizerConn); ConnectionBlocker epdBlocker(epdConn); ConnectionBlocker fattalBlocker(fattalConn); ConnectionBlocker pcvignetteBlocker(pcvignetteConn); @@ -712,6 +716,7 @@ void PartialPasteDlg::basicToggled () wb->set_active (basic->get_active ()); exposure->set_active (basic->get_active ()); sh->set_active (basic->get_active ()); + toneEqualizer->set_active (basic->get_active ()); epd->set_active (basic->get_active ()); fattal->set_active (basic->get_active ()); pcvignette->set_active (basic->get_active ()); @@ -889,6 +894,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.sh = falsePE.sh; } + if (!toneEqualizer->get_active ()) { + filterPE.toneEqualizer = falsePE.toneEqualizer; + } + if (!epd->get_active ()) { filterPE.epd = falsePE.epd; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 19e1eb462..fc45bd5e4 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -133,6 +133,7 @@ public: Gtk::CheckButton* exposure; Gtk::CheckButton* localcontrast; Gtk::CheckButton* sh; + Gtk::CheckButton* toneEqualizer; Gtk::CheckButton* epd; Gtk::CheckButton* fattal; Gtk::CheckButton* retinex; @@ -225,6 +226,7 @@ public: sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, advancedConn; sigc::connection locallabConn; sigc::connection wbConn, exposureConn, localcontrastConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn; + sigc::connection toneEqualizerConn; sigc::connection spotConn, sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, defringeConn, epdConn, fattalConn, dirpyreqConn, waveletConn, retinexConn, dehazeConn; sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn, softlightConn; sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index cc8e9ad81..01aba228f 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -462,6 +462,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh || pparams->epd != pp.epd || pparams->fattal != pp.fattal || pparams->sh != pp.sh + || pparams->toneEqualizer != pp.toneEqualizer || pparams->crop != pp.crop || pparams->coarse != pp.coarse || pparams->commonTrans != pp.commonTrans diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc new file mode 100644 index 000000000..366376ea4 --- /dev/null +++ b/rtgui/toneequalizer.cc @@ -0,0 +1,169 @@ +/* + * Adapted from ART. + * + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "eventmapper.h" +#include "toneequalizer.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + + +ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, "toneequalizer", M("TP_TONE_EQUALIZER_LABEL"), false, true) +{ + auto m = ProcEventMapper::getInstance(); + EvEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_ENABLED"); + EvBands = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_BANDS"); + EvRegularization = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION"); + EvColormap = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP"); + EvPivot = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_PIVOT"); + + std::array images = { + "purple", + "blue", + "gray", + "yellow", + "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]->setAdjusterListener(this); + pack_start(*bands[i]); + bands[i]->showIcons(false); + } + + pivot = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_PIVOT"), -12, 12, 0.05, 0)); + pivot->setLogScale(64, 0, true); + pivot->setAdjusterListener(this); + pack_start(*pivot); + + pack_start(*Gtk::manage(new Gtk::HSeparator())); + regularization = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_DETAIL"), -5, 5, 1, 5)); + regularization->setAdjusterListener(this); + pack_start(*regularization); + + show_colormap = Gtk::manage(new Gtk::CheckButton(M("TP_TONE_EQUALIZER_SHOW_COLOR_MAP"))); + pack_start(*show_colormap); + show_colormap->signal_toggled().connect(sigc::mem_fun(this, &ToneEqualizer::colormapToggled)); + + show_all_children (); +} + + +void ToneEqualizer::read(const ProcParams *pp, const ParamsEdited* pedited) +{ + disableListener(); + + setEnabled(pp->toneEqualizer.enabled); + + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->setValue(pp->toneEqualizer.bands[i]); + bands[i]->showIcons(pp->toneEqualizer.show_colormap); + } + regularization->setValue(pp->toneEqualizer.regularization); + + pivot->setValue(pp->toneEqualizer.pivot); + show_colormap->set_active(pp->toneEqualizer.show_colormap); + + enableListener(); +} + + +void ToneEqualizer::write(ProcParams *pp, ParamsEdited* pedited) +{ + for (size_t i = 0; i < bands.size(); ++i) { + pp->toneEqualizer.bands[i] = bands[i]->getValue(); + } + pp->toneEqualizer.enabled = getEnabled(); + pp->toneEqualizer.regularization = regularization->getValue(); + pp->toneEqualizer.show_colormap = show_colormap->get_active(); + pp->toneEqualizer.pivot = pivot->getValue(); +} + + +void ToneEqualizer::setDefaults(const ProcParams *defParams, const ParamsEdited* pedited) +{ + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->setDefault(defParams->toneEqualizer.bands[i]); + } + regularization->setDefault(defParams->toneEqualizer.regularization); + + pivot->setDefault(defParams->toneEqualizer.pivot); + inital_params = defParams->toneEqualizer; +} + + +void ToneEqualizer::adjusterChanged(Adjuster *a, double newval) +{ + if (listener && getEnabled()) { + if (a == regularization) { + listener->panelChanged(EvRegularization, Glib::ustring::format(a->getValue())); + } else if (a == pivot) { + listener->panelChanged(EvPivot, Glib::ustring::format(a->getValue())); + } else { + Glib::ustring s; + for (size_t i = 0; i < bands.size(); ++i) { + s += Glib::ustring::format((int)bands[i]->getValue()) + " "; + } + listener->panelChanged(EvBands, s); + } + } +} + + +void ToneEqualizer::adjusterAutoToggled(Adjuster *a) +{ +} + + +void ToneEqualizer::enabledChanged() +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged(EvEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged(EvEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvEnabled, M("GENERAL_DISABLED")); + } + } +} + + +void ToneEqualizer::colormapToggled() +{ + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->showIcons(show_colormap->get_active()); + } + if (listener && getEnabled()) { + listener->panelChanged(EvColormap, show_colormap->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} + + +void ToneEqualizer::trimValues(rtengine::procparams::ProcParams *pp) +{ + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->trimValue(pp->toneEqualizer.bands[i]); + } + regularization->trimValue(pp->toneEqualizer.regularization); + pivot->trimValue(pp->toneEqualizer.pivot); +} + diff --git a/rtgui/toneequalizer.h b/rtgui/toneequalizer.h new file mode 100644 index 000000000..f4fed79af --- /dev/null +++ b/rtgui/toneequalizer.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- + * + * Adapted from ART. + * + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ToneEqualizer: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { +public: + ToneEqualizer(); + + 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; + void adjusterChanged(Adjuster *a, double newval) override; + void adjusterAutoToggled(Adjuster *a) override; + void enabledChanged() override; + + void trimValues(rtengine::procparams::ProcParams *pp) override; + +private: + void colormapToggled(); + + std::array bands; + Adjuster *regularization; + Adjuster *pivot; + Gtk::CheckButton *show_colormap; + + rtengine::ProcEvent EvEnabled; + rtengine::ProcEvent EvBands; + rtengine::ProcEvent EvRegularization; + rtengine::ProcEvent EvColormap; + rtengine::ProcEvent EvPivot; + + rtengine::procparams::ToneEqualizerParams inital_params; +}; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 2c506710f..b61b059f6 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -47,6 +47,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit coarse = Gtk::manage (new CoarsePanel ()); toneCurve = Gtk::manage (new ToneCurve ()); shadowshighlights = Gtk::manage (new ShadowsHighlights ()); + toneEqualizer = Gtk::manage (new ToneEqualizer ()); impulsedenoise = Gtk::manage (new ImpulseDenoise ()); defringe = Gtk::manage (new Defringe ()); spot = Gtk::manage (new Spot ()); @@ -118,6 +119,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (colorPanel, chmixer); addfavoritePanel (colorPanel, blackwhite); addfavoritePanel (exposurePanel, shadowshighlights); + addfavoritePanel (exposurePanel, toneEqualizer); addfavoritePanel (detailsPanel, spot); addfavoritePanel (detailsPanel, sharpening); addfavoritePanel (detailsPanel, localContrast); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 13686d6e3..3f7afacc6 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -78,6 +78,7 @@ #include "softlight.h" #include "spot.h" #include "tonecurve.h" +#include "toneequalizer.h" #include "toolbar.h" #include "toolpanel.h" #include "vibrance.h" @@ -133,6 +134,7 @@ protected: Crop* crop; ToneCurve* toneCurve; ShadowsHighlights* shadowshighlights; + ToneEqualizer* toneEqualizer; LocalContrast *localContrast; Spot* spot; Defringe* defringe; From 3e2337bfae4ae74e1c1286d916a4f8eb7d6b2e61 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Jun 2022 16:57:40 -0700 Subject: [PATCH 059/326] Add tone equalizer to batch editor --- rtdata/languages/default | 1 + rtengine/procparams.cc | 4 +- rtengine/procparams.h | 1 + rtgui/addsetids.h | 3 ++ rtgui/adjuster.cc | 2 + rtgui/batchtoolpanelcoord.cc | 4 ++ rtgui/paramsedited.cc | 25 +++++++++--- rtgui/paramsedited.h | 3 +- rtgui/preferences.cc | 6 +++ rtgui/toneequalizer.cc | 79 +++++++++++++++++++++++++++++++++--- rtgui/toneequalizer.h | 8 +++- 11 files changed, 119 insertions(+), 17 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 6dd32ef7b..3ec76b494 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -3848,6 +3848,7 @@ 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_BANDS;Bands TP_TONE_EQUALIZER_DETAIL;Regularization TP_TONE_EQUALIZER_LABEL;Tone Equalizer TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 555af6879..edc7d7980 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -6270,7 +6270,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Tone equalizer saveToKeyfile(!pedited || pedited->toneEqualizer.enabled, "ToneEqualizer", "Enabled", toneEqualizer.enabled, keyFile); for (size_t i = 0; i < toneEqualizer.bands.size(); ++i) { - saveToKeyfile(!pedited || pedited->toneEqualizer.bands, "ToneEqualizer", "Band" + std::to_string(i), toneEqualizer.bands[i], keyFile); + saveToKeyfile(!pedited || pedited->toneEqualizer.bands[i], "ToneEqualizer", "Band" + std::to_string(i), toneEqualizer.bands[i], keyFile); } saveToKeyfile(!pedited || pedited->toneEqualizer.regularization, "ToneEqualizer", "Regularization", toneEqualizer.regularization, keyFile); saveToKeyfile(!pedited || pedited->toneEqualizer.pivot, "ToneEqualizer", "Pivot", toneEqualizer.pivot, keyFile); @@ -8263,7 +8263,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("ToneEqualizer")) { assignFromKeyfile(keyFile, "ToneEqualizer", "Enabled", pedited, 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); + assignFromKeyfile(keyFile, "ToneEqualizer", "Band" + std::to_string(i), pedited, 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 5a86b40a0..ddee7cbf3 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include #include diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 6f68c6ae7..8a2ae0466 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -10,6 +10,9 @@ enum { ADDSET_SH_HIGHLIGHTS, ADDSET_SH_SHADOWS, ADDSET_SH_LOCALCONTRAST, // not used anymore + ADDSET_TONE_EQUALIZER_BANDS, + ADDSET_TONE_EQUALIZER_PIVOT, + ADDSET_TONE_EQUALIZER_REGULARIZATION, ADDSET_LC_BRIGHTNESS, ADDSET_LC_CONTRAST, ADDSET_SHARP_AMOUNT, diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 3fe3d61eb..c9382832d 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -689,8 +689,10 @@ void Adjuster::showIcons(bool yes) { if (imageIcon1) { imageIcon1->set_visible(yes); + imageIcon1->set_no_show_all(!yes); } if (imageIcon2) { imageIcon2->set_visible(yes); + imageIcon2->set_no_show_all(!yes); } } diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 9e74ddb90..82f47b619 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -219,6 +219,7 @@ void BatchToolPanelCoordinator::initSession () chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER] ); blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES], options.baBehav[ADDSET_BLACKWHITE_GAMMA]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS]); + toneEqualizer->setAdjusterBehavior(options.baBehav[ADDSET_TONE_EQUALIZER_BANDS], options.baBehav[ADDSET_TONE_EQUALIZER_REGULARIZATION], options.baBehav[ADDSET_TONE_EQUALIZER_PIVOT]); dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2], options.baBehav[ADDSET_WA_THRES], options.baBehav[ADDSET_WA_CHRO], options.baBehav[ADDSET_WA_CHROMA], options.baBehav[ADDSET_WA_CONTRAST], options.baBehav[ADDSET_WA_SKINPROTECT], options.baBehav[ADDSET_WA_RESCHRO], options.baBehav[ADDSET_WA_TMRS], options.baBehav[ADDSET_WA_EDGS], options.baBehav[ADDSET_WA_SCALE], options.baBehav[ADDSET_WA_RESCON], options.baBehav[ADDSET_WA_RESCONH], options.baBehav[ADDSET_WA_THRR], options.baBehav[ADDSET_WA_THRRH], options.baBehav[ADDSET_WA_RADIUS], options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD], options.baBehav[ADDSET_WA_EDGVAL], options.baBehav[ADDSET_WA_STRENGTH], options.baBehav[ADDSET_WA_GAMMA], options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA], options.baBehav[ADDSET_DIRPYRDN_LUMDET], options.baBehav[ADDSET_DIRPYRDN_CHROMA], options.baBehav[ADDSET_DIRPYRDN_CHROMARED], options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA], options.baBehav[ADDSET_DIRPYRDN_PASSES]); @@ -242,6 +243,9 @@ void BatchToolPanelCoordinator::initSession () if (options.baBehav[ADDSET_TC_SATURATION]) { pparams.toneCurve.saturation = 0;} if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) { pparams.sh.highlights = 0; } if (options.baBehav[ADDSET_SH_SHADOWS]) { pparams.sh.shadows = 0; } + if (options.baBehav[ADDSET_TONE_EQUALIZER_BANDS]) { pparams.toneEqualizer.bands = {}; } + if (options.baBehav[ADDSET_TONE_EQUALIZER_PIVOT]) { pparams.toneEqualizer.pivot = 0; } + if (options.baBehav[ADDSET_TONE_EQUALIZER_REGULARIZATION]) { pparams.toneEqualizer.regularization = 0; } if (options.baBehav[ADDSET_LC_BRIGHTNESS]) { pparams.labCurve.brightness = 0; } if (options.baBehav[ADDSET_LC_CONTRAST]) { pparams.labCurve.contrast = 0; } if (options.baBehav[ADDSET_LC_CHROMATICITY]) { pparams.labCurve.chromaticity = 0; } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ff48a58b1..598e15673 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -318,7 +318,7 @@ void ParamsEdited::set(bool v) sh.radius = v; sh.lab = v; toneEqualizer.enabled = v; - toneEqualizer.bands = v; + toneEqualizer.bands.fill(v); toneEqualizer.regularization = v; toneEqualizer.show_colormap = v; toneEqualizer.pivot = v; @@ -1037,7 +1037,9 @@ void ParamsEdited::initFrom(const std::vector& crop.orientation = crop.orientation && p.crop.orientation == other.crop.orientation; crop.guide = crop.guide && p.crop.guide == other.crop.guide; toneEqualizer.enabled = toneEqualizer.enabled && p.toneEqualizer.enabled == other.toneEqualizer.enabled; - toneEqualizer.bands = toneEqualizer.bands && p.toneEqualizer.bands == other.toneEqualizer.bands; + for (size_t i = 0; i < toneEqualizer.bands.size(); ++i) { + toneEqualizer.bands[i] = toneEqualizer.bands[i] && p.toneEqualizer.bands[i] == other.toneEqualizer.bands[i]; + } toneEqualizer.regularization = toneEqualizer.regularization && p.toneEqualizer.regularization == other.toneEqualizer.regularization; toneEqualizer.show_colormap = toneEqualizer.show_colormap && p.toneEqualizer.show_colormap == other.toneEqualizer.show_colormap; toneEqualizer.pivot = toneEqualizer.pivot && p.toneEqualizer.pivot == other.toneEqualizer.pivot; @@ -3208,12 +3210,20 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.toneEqualizer.enabled = mods.toneEqualizer.enabled; } - if (toneEqualizer.bands) { - toEdit.toneEqualizer.bands = mods.toneEqualizer.bands; + for (size_t i = 0; i < toneEqualizer.bands.size(); ++i) { + if (toneEqualizer.bands[i]) { + toEdit.toneEqualizer.bands[i] = + dontforceSet && options.baBehav[ADDSET_TONE_EQUALIZER_BANDS] + ? toEdit.toneEqualizer.bands[i] + mods.toneEqualizer.bands[i] + : mods.toneEqualizer.bands[i]; + } } if (toneEqualizer.regularization) { - toEdit.toneEqualizer.regularization = mods.toneEqualizer.regularization; + toEdit.toneEqualizer.regularization = + dontforceSet && options.baBehav[ADDSET_TONE_EQUALIZER_REGULARIZATION] + ? toEdit.toneEqualizer.regularization + mods.toneEqualizer.regularization + : mods.toneEqualizer.regularization; } if (toneEqualizer.show_colormap) { @@ -3221,7 +3231,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (toneEqualizer.pivot) { - toEdit.toneEqualizer.pivot = mods.toneEqualizer.pivot; + toEdit.toneEqualizer.pivot = + dontforceSet && options.baBehav[ADDSET_TONE_EQUALIZER_PIVOT] + ? toEdit.toneEqualizer.pivot + mods.toneEqualizer.pivot + : mods.toneEqualizer.pivot; } if (crop.enabled) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index d70336a54..f34eba69b 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include namespace rtengine @@ -360,7 +361,7 @@ struct SHParamsEdited { struct ToneEqualizerParamsEdited { bool enabled; - bool bands; + std::array bands; bool regularization; bool show_colormap; bool pivot; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c6c2eb61b..2df816b44 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -227,6 +227,12 @@ Gtk::Widget* Preferences::getBatchProcPanel() appendBehavList(mi, M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), ADDSET_SH_HIGHLIGHTS, false); appendBehavList(mi, M("TP_SHADOWSHLIGHTS_SHADOWS"), ADDSET_SH_SHADOWS, false); + mi = behModel->append(); + mi->set_value(behavColumns.label, M("TP_TONE_EQUALIZER_LABEL")); + appendBehavList(mi, M("TP_TONE_EQUALIZER_BANDS"), ADDSET_TONE_EQUALIZER_BANDS, false); + appendBehavList(mi, M("TP_TONE_EQUALIZER_PIVOT"), ADDSET_TONE_EQUALIZER_PIVOT, false); + appendBehavList(mi, M("TP_TONE_EQUALIZER_DETAIL"), ADDSET_TONE_EQUALIZER_REGULARIZATION, false); + mi = behModel->append(); mi->set_value(behavColumns.label, M("TP_LABCURVE_LABEL")); appendBehavList(mi, M("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false); diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc index 366376ea4..27d35d514 100644 --- a/rtgui/toneequalizer.cc +++ b/rtgui/toneequalizer.cc @@ -59,9 +59,9 @@ ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, "toneequalizer", M("TP_T regularization->setAdjusterListener(this); pack_start(*regularization); - show_colormap = Gtk::manage(new Gtk::CheckButton(M("TP_TONE_EQUALIZER_SHOW_COLOR_MAP"))); + show_colormap = Gtk::manage(new CheckBox(M("TP_TONE_EQUALIZER_SHOW_COLOR_MAP"), multiImage)); pack_start(*show_colormap); - show_colormap->signal_toggled().connect(sigc::mem_fun(this, &ToneEqualizer::colormapToggled)); + show_colormap->setCheckBoxListener(this); show_all_children (); } @@ -71,6 +71,16 @@ void ToneEqualizer::read(const ProcParams *pp, const ParamsEdited* pedited) { disableListener(); + if (pedited) { + set_inconsistent(multiImage && !pedited->toneEqualizer.enabled); + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->setEditedState(pedited->toneEqualizer.bands[i] ? Edited : UnEdited); + } + regularization->setEditedState(pedited->toneEqualizer.regularization ? Edited : UnEdited); + pivot->setEditedState(pedited->toneEqualizer.pivot ? Edited : UnEdited); + show_colormap->setEdited(pedited->toneEqualizer.show_colormap ? Edited : UnEdited); + } + setEnabled(pp->toneEqualizer.enabled); for (size_t i = 0; i < bands.size(); ++i) { @@ -80,7 +90,7 @@ void ToneEqualizer::read(const ProcParams *pp, const ParamsEdited* pedited) regularization->setValue(pp->toneEqualizer.regularization); pivot->setValue(pp->toneEqualizer.pivot); - show_colormap->set_active(pp->toneEqualizer.show_colormap); + show_colormap->setValue(pp->toneEqualizer.show_colormap); enableListener(); } @@ -93,8 +103,19 @@ void ToneEqualizer::write(ProcParams *pp, ParamsEdited* pedited) } pp->toneEqualizer.enabled = getEnabled(); pp->toneEqualizer.regularization = regularization->getValue(); - pp->toneEqualizer.show_colormap = show_colormap->get_active(); + pp->toneEqualizer.show_colormap = show_colormap->getLastActive(); pp->toneEqualizer.pivot = pivot->getValue(); + + if (pedited) { + auto &edited = pedited->toneEqualizer; + edited.enabled = !get_inconsistent(); + for (size_t i = 0; i < bands.size(); ++i) { + edited.bands[i] = bands[i]->getEditedState(); + } + edited.regularization = regularization->getEditedState(); + edited.pivot = pivot->getEditedState(); + edited.show_colormap = show_colormap->getEdited(); + } } @@ -107,6 +128,21 @@ void ToneEqualizer::setDefaults(const ProcParams *defParams, const ParamsEdited* pivot->setDefault(defParams->toneEqualizer.pivot); inital_params = defParams->toneEqualizer; + + if (pedited) { + auto &edited = pedited->toneEqualizer; + for (size_t i = 0; i < bands.size(); ++i) { + bands[i]->setDefaultEditedState(edited.bands[i] ? Edited : UnEdited); + } + regularization->setDefaultEditedState(edited.regularization ? Edited : UnEdited); + pivot->setDefaultEditedState(edited.pivot ? Edited : UnEdited); + } else { + for (auto band : bands) { + band->setDefaultEditedState(Irrelevant); + } + regularization->setDefaultEditedState(Irrelevant); + pivot->setDefaultEditedState(Irrelevant); + } } @@ -147,13 +183,44 @@ void ToneEqualizer::enabledChanged() } +void ToneEqualizer::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode(batchMode); + if (batchMode) { + for (auto band : bands) { + band->showEditedCB(); + } + regularization->showEditedCB(); + pivot->showEditedCB(); + } +} + + +void ToneEqualizer::setAdjusterBehavior(bool bands_add, bool regularization_add, bool pivot_add) +{ + for (auto band : bands) { + band->setAddMode(bands_add); + } + regularization->setAddMode(regularization_add); + pivot->setAddMode(pivot_add); +} + + +void ToneEqualizer::checkBoxToggled(CheckBox *c, CheckValue newval) +{ + if (c == show_colormap) { + colormapToggled(); + } +} + + void ToneEqualizer::colormapToggled() { for (size_t i = 0; i < bands.size(); ++i) { - bands[i]->showIcons(show_colormap->get_active()); + bands[i]->showIcons(show_colormap->getLastActive()); } if (listener && getEnabled()) { - listener->panelChanged(EvColormap, show_colormap->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + listener->panelChanged(EvColormap, show_colormap->getLastActive() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); } } diff --git a/rtgui/toneequalizer.h b/rtgui/toneequalizer.h index f4fed79af..657167f05 100644 --- a/rtgui/toneequalizer.h +++ b/rtgui/toneequalizer.h @@ -23,9 +23,10 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "toolpanel.h" -class ToneEqualizer: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { +class ToneEqualizer: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CheckBoxListener { public: ToneEqualizer(); @@ -35,6 +36,9 @@ public: void adjusterChanged(Adjuster *a, double newval) override; void adjusterAutoToggled(Adjuster *a) override; void enabledChanged() override; + void setBatchMode(bool batchMode) override; + void setAdjusterBehavior(bool bands_add, bool regularization_add, bool pivot_add); + void checkBoxToggled(CheckBox* c, CheckValue newval) override; void trimValues(rtengine::procparams::ProcParams *pp) override; @@ -44,7 +48,7 @@ private: std::array bands; Adjuster *regularization; Adjuster *pivot; - Gtk::CheckButton *show_colormap; + CheckBox *show_colormap; rtengine::ProcEvent EvEnabled; rtengine::ProcEvent EvBands; From c4ea272d6580a7dc50cfda7bd1d4260c8f2af11c Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:14:05 -0700 Subject: [PATCH 060/326] Fix tone equalizer causing double LA application Change the tone equalizer event refresh type to force correct computation of local of local adjustments of local adjustments. Idea from from https://github.com/Beep6581/RawTherapee/issues/6069#issuecomment-765263602. --- rtgui/toneequalizer.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc index 27d35d514..fd60d4936 100644 --- a/rtgui/toneequalizer.cc +++ b/rtgui/toneequalizer.cc @@ -29,11 +29,11 @@ using namespace rtengine::procparams; ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, "toneequalizer", M("TP_TONE_EQUALIZER_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); - EvEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_ENABLED"); - EvBands = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_BANDS"); - EvRegularization = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION"); - EvColormap = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP"); - EvPivot = m->newEvent(RGBCURVE, "HISTORY_MSG_TONE_EQUALIZER_PIVOT"); + EvEnabled = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_ENABLED"); + EvBands = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_BANDS"); + EvRegularization = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION"); + EvColormap = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP"); + EvPivot = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_PIVOT"); std::array images = { "purple", From a877ac4878cba816e1e378244775d2ea7321412e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 26 Jun 2022 16:06:34 -0700 Subject: [PATCH 061/326] Add pivot to local adjustments tone equalizer --- rtdata/languages/default | 2 ++ rtengine/improcfun.h | 4 +-- rtengine/iplocallab.cc | 22 +++++------- rtengine/iptoneequalizer.cc | 67 ++++++++++++++++++++----------------- rtengine/procparams.cc | 4 +++ rtengine/procparams.h | 1 + rtgui/locallabtools.cc | 18 +++++++++- rtgui/locallabtools.h | 3 ++ rtgui/paramsedited.cc | 7 ++++ rtgui/paramsedited.h | 1 + 10 files changed, 82 insertions(+), 47 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3ec76b494..3064c13e3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1475,6 +1475,7 @@ 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_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -3433,6 +3434,7 @@ TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle lin 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 diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 70aed428c..12487cdbd 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -492,8 +492,8 @@ enum class BlurType { void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); //void shadowsHighlights(LabImage *lab); void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal); - bool toneEqualizer(Imagefloat *rgb); - static void toneEqualizer(array2D &R, array2D &G, array2D &B, const procparams::ToneEqualizerParams & params, const Glib::ustring &workingProfile, double scale, bool multithread, bool show_color_map); + void toneEqualizer(Imagefloat *rgb); + void toneEqualizer(Imagefloat *rgb, const procparams::ToneEqualizerParams ¶ms, const Glib::ustring &workingProfile, double scale, bool multiThread); void softLight(LabImage *lab, const procparams::SoftLightParams &softLightParams); void labColorCorrectionRegions(LabImage *lab); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 7a427b0eb..005b960a5 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -702,6 +702,7 @@ struct local_params { float mulloc[6]; int mullocsh[5]; int detailsh; + double tePivot; float threshol; float chromacb; float strengt; @@ -1691,6 +1692,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.detailsh = locallab.spots.at(sp).detailSH; + lp.tePivot = locallab.spots.at(sp).tePivot; lp.threshol = thresho; lp.chromacb = chromcbdl; lp.expvib = locallab.spots.at(sp).expvibrance && lp.activspot ; @@ -2257,12 +2259,14 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, } } -void tone_eq(array2D &R, array2D &G, array2D &B, const struct local_params & lp, const Glib::ustring &workingProfile, double scale, bool multithread) +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; + params.pivot = lp.tePivot; std::copy(lp.mullocsh, lp.mullocsh + params.bands.size(), params.bands.begin()); - ImProcFunctions::toneEqualizer(R, G, B, params, workingProfile, scale, multithread, false); + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float stren, int sk) { @@ -7586,12 +7590,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp } if (tonequ) { - tmpImage->normalizeFloatTo1(); - array2D Rtemp(GW, GH, tmpImage->r.ptrs, ARRAY2D_BYREFERENCE); - array2D Gtemp(GW, GH, tmpImage->g.ptrs, ARRAY2D_BYREFERENCE); - array2D Btemp(GW, GH, tmpImage->b.ptrs, ARRAY2D_BYREFERENCE); - tone_eq(Rtemp, Gtemp, Btemp, lp, params->icm.workingProfile, sk, multiThread); - tmpImage->normalizeFloatTo65535(); + tone_eq(this, tmpImage.get(), lp, params->icm.workingProfile, sk, multiThread); } rgb2lab(*tmpImage, *temp, params->icm.workingProfile); @@ -15766,12 +15765,7 @@ void ImProcFunctions::Lab_Local( } if (tonequ) { - tmpImage->normalizeFloatTo1(); - array2D Rtemp(bfw, bfh, tmpImage->r.ptrs, ARRAY2D_BYREFERENCE); - array2D Gtemp(bfw, bfh, tmpImage->g.ptrs, ARRAY2D_BYREFERENCE); - array2D Btemp(bfw, bfh, tmpImage->b.ptrs, ARRAY2D_BYREFERENCE); - tone_eq(Rtemp, Gtemp, Btemp, lp, params->icm.workingProfile, scal, multiThread); - tmpImage->normalizeFloatTo65535(); + tone_eq(this, tmpImage, lp, params->icm.workingProfile, scal, multiThread); } rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); diff --git a/rtengine/iptoneequalizer.cc b/rtengine/iptoneequalizer.cc index c177b8f98..a661d6b41 100644 --- a/rtengine/iptoneequalizer.cc +++ b/rtengine/iptoneequalizer.cc @@ -25,19 +25,13 @@ const std::vector> colormap = { {1.f, 0.f, 0.f} }; -} - -namespace rtengine -{ - -void ImProcFunctions::toneEqualizer( +void toneEqualizer( array2D &R, array2D &G, array2D &B, - const struct ToneEqualizerParams ¶ms, + const rtengine::ToneEqualizerParams ¶ms, const Glib::ustring &workingProfile, double scale, - bool multithread, - bool show_color_map) + bool multithread) // adapted from the tone equalizer of darktable /* Copyright 2019 Alberto Griggio @@ -102,18 +96,18 @@ void ImProcFunctions::toneEqualizer( conv(params.bands[4], 3.f, 2.f) // 4 EV }; - TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(workingProfile); + rtengine::TMatrix ws = rtengine::ICCStore::getInstance()->workingSpaceMatrix(workingProfile); #ifdef _OPENMP #pragma omp parallel for if (multithread) #endif for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { - Y[y][x] = Color::rgbLuminance(R[y][x], G[y][x], B[y][x], ws); + Y[y][x] = rtengine::Color::rgbLuminance(R[y][x], G[y][x], B[y][x], ws); } } - int detail = LIM(params.regularization + 5, 0, 5); + int detail = rtengine::LIM(params.regularization + 5, 0, 5); int radius = detail / scale + 0.5; float epsilon2 = 0.01f + 0.002f * rtengine::max(detail - 3, 0); @@ -131,7 +125,7 @@ void ImProcFunctions::toneEqualizer( #endif for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { - float l = 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[11]); float ll = round(l * base_posterization) / base_posterization; Y2[y][x] = Y[y][x]; Y[y][x] = exp2(ll); @@ -145,7 +139,7 @@ void ImProcFunctions::toneEqualizer( const auto gauss = [](float b, float x) -> float { - return xexpf((-SQR(x - b) / 4.0f)); + return xexpf((-rtengine::SQR(x - b) / 4.0f)); }; // For every pixel luminance, the sum of the gaussian masks @@ -175,12 +169,12 @@ void ImProcFunctions::toneEqualizer( }; std::vector> cur_colormap; - if (show_color_map) { - lcmsMutex->lock(); - cmsHPROFILE in = ICCStore::getInstance()->getsRGBProfile(); - cmsHPROFILE out = ICCStore::getInstance()->workingSpace(workingProfile); + if (params.show_colormap) { + rtengine::lcmsMutex->lock(); + cmsHPROFILE in = rtengine::ICCStore::getInstance()->getsRGBProfile(); + cmsHPROFILE out = rtengine::ICCStore::getInstance()->workingSpace(workingProfile); cmsHTRANSFORM xform = cmsCreateTransform(in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); - lcmsMutex->unlock(); + rtengine::lcmsMutex->unlock(); for (auto &c : colormap) { cur_colormap.push_back(c); @@ -197,7 +191,7 @@ void ImProcFunctions::toneEqualizer( std::array ret = { 0.f, 0.f, 0.f }; // convert to log space - const float luma = max(log2(max(y, 0.f)), -18.0f); + const float luma = rtengine::max(log2(rtengine::max(y, 0.f)), -18.0f); // build the correction as the sum of the contribution of each // luminance channel to current pixel @@ -208,7 +202,7 @@ void ImProcFunctions::toneEqualizer( } } for (int i = 0; i < 3; ++i) { - ret[i] = LIM01(ret[i] / w_sum); + ret[i] = rtengine::LIM01(ret[i] / w_sum); } return ret; @@ -227,7 +221,7 @@ void ImProcFunctions::toneEqualizer( const auto vgauss = [](vfloat b, vfloat x) -> vfloat { static const vfloat fourv = F2V(4.f); - return xexpf((-SQR(x - b) / fourv)); + return xexpf((-rtengine::SQR(x - b) / fourv)); }; vfloat zerov = F2V(0.f); @@ -258,7 +252,7 @@ void ImProcFunctions::toneEqualizer( #endif // __SSE2__ - if (show_color_map) { + if (params.show_colormap) { LUTf lut_r(65537), lut_g(65537), lut_b(65537); for (int i = 0; i < 65536; ++i) { float y = float(i)/65535.f; @@ -332,15 +326,26 @@ void ImProcFunctions::toneEqualizer( } -bool ImProcFunctions::toneEqualizer(Imagefloat *rgb) +} + + +namespace rtengine { - if (!params->toneEqualizer.enabled) { - return false; + +void ImProcFunctions::toneEqualizer( + Imagefloat *rgb, + const ToneEqualizerParams ¶ms, + const Glib::ustring &workingProfile, + double scale, + bool multiThread) +{ + if (!params.enabled) { + return; } BENCHFUN - const float gain = 1.f / 65535.f * std::pow(2.f, -params->toneEqualizer.pivot); + const float gain = 1.f / 65535.f * std::pow(2.f, -params.pivot); rgb->multiply(gain, multiThread); @@ -351,12 +356,14 @@ bool ImProcFunctions::toneEqualizer(Imagefloat *rgb) array2D G(W, H, rgb->g.ptrs, ARRAY2D_BYREFERENCE); array2D B(W, H, rgb->b.ptrs, ARRAY2D_BYREFERENCE); - bool show_color_map = params->toneEqualizer.show_colormap; - toneEqualizer(R, G, B, params->toneEqualizer, params->icm.workingProfile, scale, multiThread, show_color_map); + ::toneEqualizer(R, G, B, params, workingProfile, scale, multiThread); rgb->multiply(1.f/gain, multiThread); +} - return show_color_map; +void ImProcFunctions::toneEqualizer(Imagefloat *rgb) +{ + toneEqualizer(rgb, params->toneEqualizer, params->icm.workingProfile, scale, multiThread); } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index edc7d7980..52d6be8dd 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3324,6 +3324,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : slomaskSH(0.0), lapmaskSH(0.0), detailSH(0), + tePivot(0.), reparsh(100.), LmaskSHcurve{ static_cast(DCT_NURBS), @@ -4769,6 +4770,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && slomaskSH == other.slomaskSH && lapmaskSH == other.lapmaskSH && detailSH == other.detailSH + && tePivot == other.tePivot && reparsh == other.reparsh && LmaskSHcurve == other.LmaskSHcurve && fatamountSH == other.fatamountSH @@ -6562,6 +6564,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->gammaskSH, "Locallab", "GammaskSH_" + index_str, spot.gammaskSH, keyFile); saveToKeyfile(!pedited || spot_edited->slomaskSH, "Locallab", "SlomaskSH_" + index_str, spot.slomaskSH, keyFile); saveToKeyfile(!pedited || spot_edited->detailSH, "Locallab", "DetailSH_" + index_str, spot.detailSH, keyFile); + saveToKeyfile(!pedited || spot_edited->tePivot, "Locallab", "TePivot_" + index_str, spot.tePivot, keyFile); saveToKeyfile(!pedited || spot_edited->reparsh, "Locallab", "Reparsh_" + index_str, spot.reparsh, keyFile); saveToKeyfile(!pedited || spot_edited->LmaskSHcurve, "Locallab", "LmaskSHCurve_" + index_str, spot.LmaskSHcurve, keyFile); saveToKeyfile(!pedited || spot_edited->fatamountSH, "Locallab", "FatamountSH_" + index_str, spot.fatamountSH, keyFile); @@ -8668,6 +8671,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index ddee7cbf3..ba58cd32c 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1214,6 +1214,7 @@ struct LocallabParams { double slomaskSH; double lapmaskSH; int detailSH; + double tePivot; double reparsh; std::vector LmaskSHcurve; double fatamountSH; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 51da93ab3..250bd958f 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -3971,6 +3971,7 @@ LocallabShadow::LocallabShadow(): } ()), detailSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAILSH"), -5, 5, 1, 0))), + tePivot(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TE_PIVOT"), -12, 12, 0.05, 0))), highlights(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0))), h_tonalwidth(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 70))), shadows(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0))), @@ -4011,7 +4012,8 @@ 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.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + EvlocallabTePivot(ProcEventMapper::getInstance()->newEvent(AUTOEXP, "HISTORY_MSG_LOCALLAB_TE_PIVOT")) { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -4028,6 +4030,7 @@ LocallabShadow::LocallabShadow(): } detailSH->setAdjusterListener(this); + tePivot->setAdjusterListener(this); reparsh->setAdjusterListener(this); highlights->setAdjusterListener(this); @@ -4138,6 +4141,7 @@ LocallabShadow::LocallabShadow(): } pack_start(*detailSH); + pack_start(*tePivot); pack_start(*highlights); pack_start(*h_tonalwidth); pack_start(*shadows); @@ -4358,6 +4362,7 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para decays->setValue((double)spot.decays); detailSH->setValue((double)spot.detailSH); + tePivot->setValue(spot.tePivot); reparsh->setValue(spot.reparsh); highlights->setValue((double)spot.highlights); h_tonalwidth->setValue((double)spot.h_tonalwidth); @@ -4423,6 +4428,7 @@ void LocallabShadow::write(rtengine::procparams::ProcParams* pp, ParamsEdited* p } spot.detailSH = detailSH->getIntValue(); + spot.tePivot = tePivot->getValue(); spot.reparsh = reparsh->getValue(); spot.highlights = highlights->getIntValue(); spot.h_tonalwidth = h_tonalwidth->getIntValue(); @@ -4471,6 +4477,7 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara } detailSH->setDefault((double)defSpot.detailSH); + tePivot->setDefault(defSpot.tePivot); reparsh->setDefault(defSpot.reparsh); highlights->setDefault((double)defSpot.highlights); h_tonalwidth->setDefault((double)defSpot.h_tonalwidth); @@ -4522,6 +4529,13 @@ void LocallabShadow::adjusterChanged(Adjuster* a, double newval) } } + if (a == tePivot) { + if (listener) { + listener->panelChanged(EvlocallabTePivot, + tePivot->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == reparsh) { if (listener) { listener->panelChanged(Evlocallabreparsh, @@ -5038,6 +5052,7 @@ void LocallabShadow::updateShadowGUI2() gamFrame->hide(); detailSH->hide(); + tePivot->hide(); highlights->show(); h_tonalwidth->show(); shadows->show(); @@ -5053,6 +5068,7 @@ void LocallabShadow::updateShadowGUI2() } detailSH->show(); + tePivot->show(); highlights->hide(); h_tonalwidth->hide(); shadows->hide(); diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index e7fcfc1d0..72c6730e8 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -451,6 +451,7 @@ private: Adjuster* const reparsh; const std::array multipliersh; Adjuster* const detailSH; + Adjuster* const tePivot; Adjuster* const highlights; Adjuster* const h_tonalwidth; Adjuster* const shadows; @@ -492,6 +493,8 @@ private: Adjuster* const fatamountSH; Adjuster* const fatanchorSH; + rtengine::ProcEvent EvlocallabTePivot; + sigc::connection shMethodConn, inversshConn, showmaskSHMethodConn, showmaskSHMethodConninv, enaSHMaskConn; public: diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 598e15673..5ef83ed86 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1283,6 +1283,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).slomaskSH = locallab.spots.at(j).slomaskSH && pSpot.slomaskSH == otherSpot.slomaskSH; locallab.spots.at(j).lapmaskSH = locallab.spots.at(j).lapmaskSH && pSpot.lapmaskSH == otherSpot.lapmaskSH; locallab.spots.at(j).detailSH = locallab.spots.at(j).detailSH && pSpot.detailSH == otherSpot.detailSH; + locallab.spots.at(j).tePivot = locallab.spots.at(j).tePivot && pSpot.tePivot == otherSpot.tePivot; locallab.spots.at(j).reparsh = locallab.spots.at(j).reparsh && pSpot.reparsh == otherSpot.reparsh; locallab.spots.at(j).LmaskSHcurve = locallab.spots.at(j).LmaskSHcurve && pSpot.LmaskSHcurve == otherSpot.LmaskSHcurve; locallab.spots.at(j).fatamountSH = locallab.spots.at(j).fatamountSH && pSpot.fatamountSH == otherSpot.fatamountSH; @@ -4182,6 +4183,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).detailSH = mods.locallab.spots.at(i).detailSH; } + if (locallab.spots.at(i).tePivot) { + toEdit.locallab.spots.at(i).tePivot = mods.locallab.spots.at(i).tePivot; + } + if (locallab.spots.at(i).reparsh) { toEdit.locallab.spots.at(i).reparsh = mods.locallab.spots.at(i).reparsh; } @@ -7624,6 +7629,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : slomaskSH(v), lapmaskSH(v), detailSH(v), + tePivot(v), reparsh(v), LmaskSHcurve(v), fatamountSH(v), @@ -8320,6 +8326,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) slomaskSH = v; lapmaskSH = v; detailSH = v; + tePivot = v; reparsh = v; LmaskSHcurve = v; fatamountSH = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index f34eba69b..f5f318088 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -589,6 +589,7 @@ public: bool slomaskSH; bool lapmaskSH; bool detailSH; + bool tePivot; bool reparsh; bool LmaskSHcurve; bool fatamountSH; From efc350228ee943a5c1c48c4c8c868ddf1bb81ac3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 26 Jun 2022 18:37:28 -0700 Subject: [PATCH 062/326] Fix tone equalizer colormap brightness Don't apply pivot to the colormap itself. --- rtengine/iptoneequalizer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/iptoneequalizer.cc b/rtengine/iptoneequalizer.cc index a661d6b41..481d14114 100644 --- a/rtengine/iptoneequalizer.cc +++ b/rtengine/iptoneequalizer.cc @@ -358,7 +358,7 @@ void ImProcFunctions::toneEqualizer( ::toneEqualizer(R, G, B, params, workingProfile, scale, multiThread); - rgb->multiply(1.f/gain, multiThread); + rgb->multiply(params.show_colormap ? 65535.f : 1.f/gain, multiThread); } void ImProcFunctions::toneEqualizer(Imagefloat *rgb) From 38d85581df13108ae8647cb58eca3260bb14da08 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 30 Jun 2022 21:19:30 -0700 Subject: [PATCH 063/326] Fix tone equalizer darkening of extreme luminances Extend the extreme bands' contributions all the way to -infinity and +infinity EVs. --- rtengine/iptoneequalizer.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/rtengine/iptoneequalizer.cc b/rtengine/iptoneequalizer.cc index 481d14114..7fb6c791f 100644 --- a/rtengine/iptoneequalizer.cc +++ b/rtengine/iptoneequalizer.cc @@ -15,13 +15,13 @@ const std::vector> colormap = { {0.5f, 0.f, 0.5f}, {0.5f, 0.f, 0.5f}, {0.5f, 0.f, 0.5f}, - {0.5f, 0.f, 0.5f}, {0.5f, 0.f, 0.5f}, // blacks {0.f, 0.f, 1.f}, // shadows {0.5f, 0.5f, 0.5f}, // midtones {1.f, 1.f, 0.f}, // highlights {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} }; @@ -73,8 +73,8 @@ void toneEqualizer( // Build the luma channels: band-pass filters with gaussian windows of // std 2 EV, spaced by 2 EV const float centers[12] = { - -18.0f, -16.0f, -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, - -4.0f, -2.0f, 0.0f, 2.0f, 4.0f + -16.0f, -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, + -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f }; const auto conv = [&](int v, float lo, float hi) -> float { @@ -82,7 +82,6 @@ void toneEqualizer( return exp2(float(v) / 100.f * f); }; const float factors[12] = { - conv(params.bands[0], 2.f, 3.f), // -18 EV 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 +92,8 @@ void toneEqualizer( conv(params.bands[3], 3.f, 2.f), // -2 EV 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), // 4 EV + conv(params.bands[4], 3.f, 2.f) // 6 EV }; rtengine::TMatrix ws = rtengine::ICCStore::getInstance()->workingSpaceMatrix(workingProfile); @@ -149,10 +149,13 @@ void toneEqualizer( w_sum += gauss(centers[i], 0.f); } + constexpr float luma_lo = -14.f; + constexpr float luma_hi = 4.f; + const auto process_pixel = [&](float y) -> float { // convert to log space - const float luma = rtengine::max(log2(rtengine::max(y, 0.f)), -18.0f); + const float luma = rtengine::LIM(log2(rtengine::max(y, 0.f)), luma_lo, luma_hi); // build the correction as the sum of the contribution of each // luminance channel to current pixel @@ -191,7 +194,7 @@ void toneEqualizer( std::array ret = { 0.f, 0.f, 0.f }; // convert to log space - const float luma = rtengine::max(log2(rtengine::max(y, 0.f)), -18.0f); + const float luma = rtengine::LIM(log2(rtengine::max(y, 0.f)), luma_lo, luma_hi); // build the correction as the sum of the contribution of each // luminance channel to current pixel @@ -227,12 +230,13 @@ void toneEqualizer( vfloat zerov = F2V(0.f); vfloat vw_sum = F2V(w_sum); - const vfloat noisev = F2V(-18.f); + const vfloat vluma_lo = F2V(luma_lo); + const vfloat vluma_hi = F2V(luma_hi); const vfloat xlog2v = F2V(xlogf(2.f)); const auto vprocess_pixel = [&](vfloat y) -> vfloat { - const vfloat luma = vmaxf(xlogf(vmaxf(y, zerov)) / xlog2v, noisev); + const vfloat luma = vminf(vmaxf(xlogf(vmaxf(y, zerov)) / xlog2v, vluma_lo), vluma_hi); vfloat correction = zerov; From a13c8a5a474aad3140c997dac0d011bda9147f98 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 30 Jun 2022 21:58:10 -0700 Subject: [PATCH 064/326] Make default tone eq. regularization consistent Use 0 for the initial and reset value, which is the same as the details in the local adjustments version. --- rtengine/procparams.cc | 2 +- rtgui/toneequalizer.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 52d6be8dd..361ee847c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1789,7 +1789,7 @@ bool SHParams::operator !=(const SHParams& other) const ToneEqualizerParams::ToneEqualizerParams() : enabled(false), bands{0, 0, 0, 0, 0}, - regularization(4), + regularization(0), show_colormap(false), pivot(0) { diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc index fd60d4936..de748c2b7 100644 --- a/rtgui/toneequalizer.cc +++ b/rtgui/toneequalizer.cc @@ -55,7 +55,7 @@ ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, "toneequalizer", M("TP_T pack_start(*pivot); pack_start(*Gtk::manage(new Gtk::HSeparator())); - regularization = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_DETAIL"), -5, 5, 1, 5)); + regularization = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_DETAIL"), -5, 5, 1, 0)); regularization->setAdjusterListener(this); pack_start(*regularization); From 1450b9bb7aebcff58389415f21db1b0af3f78989 Mon Sep 17 00:00:00 2001 From: Bezierr Date: Wed, 20 Jul 2022 12:14:05 +0200 Subject: [PATCH 065/326] Camera and Lens profiles directories In "Preferences", added the possibility to define a "Camera profiles directory" and a "Lens profiles directory" as base paths which enable storing relative paths in the .pp3 files. --- rtdata/languages/default | 2 ++ rtengine/procparams.cc | 36 ++++++++++++++++++++++++++++++++---- rtengine/settings.h | 2 ++ rtgui/options.cc | 19 +++++++++++++++++++ rtgui/options.h | 2 ++ rtgui/preferences.cc | 29 +++++++++++++++++++++++++++-- rtgui/preferences.h | 2 ++ 7 files changed, 86 insertions(+), 6 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index c50b49ddf..d67e6a12b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1845,6 +1845,7 @@ PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing pr PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries PREFERENCES_CACHEOPTS;Cache Options PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory PREFERENCES_CHUNKSIZES;Tiles per thread PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -1927,6 +1928,7 @@ PREFERENCES_INTENT_SATURATION;Saturation PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited PREFERENCES_LANG;Language PREFERENCES_LANGAUTODETECT;Use system language +PREFERENCES_LENSPROFILESDIR;Lens profiles directory PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" PREFERENCES_MENUGROUPFILEOPERATIONS;Group "File operations" diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9a9e4fef1..30a2e303c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -6287,7 +6287,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Lens profile saveToKeyfile(!pedited || pedited->lensProf.lcMode, "LensProfile", "LcMode", lensProf.getMethodString(lensProf.lcMode), keyFile); - saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile), keyFile); + if (options.rtSettings.lensProfilesPath.empty() + || !Glib::path_is_absolute(options.rtSettings.lensProfilesPath)) { + saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile), keyFile); + } else { + // if the "lens profiles directory" in Preferences exists and is an absolute path, try to save + // the path to the LCP file as relative to this directory + saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, false, lensProf.lcpFile), keyFile); + } saveToKeyfile(!pedited || pedited->lensProf.useDist, "LensProfile", "UseDistortion", lensProf.useDist, keyFile); saveToKeyfile(!pedited || pedited->lensProf.useVign, "LensProfile", "UseVignette", lensProf.useVign, keyFile); saveToKeyfile(!pedited || pedited->lensProf.useCA, "LensProfile", "UseCA", lensProf.useCA, keyFile); @@ -7108,7 +7115,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->prsharpening.deconviter, "PostResizeSharpening", "DeconvIterations", prsharpening.deconviter, keyFile); // Color management - saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.inputProfile), keyFile); + if (options.rtSettings.cameraProfilesPath.empty() + || !Glib::path_is_absolute(options.rtSettings.cameraProfilesPath)) { + saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.inputProfile), keyFile); + } else { + // if the "camera profiles directory" in Preferences exists and is an absolute path, try to save + // the path to the Custom Input Profile as relative to this directory + saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, false, icm.inputProfile), keyFile); + } saveToKeyfile(!pedited || pedited->icm.toneCurve, "Color Management", "ToneCurve", icm.toneCurve, keyFile); saveToKeyfile(!pedited || pedited->icm.applyLookTable, "Color Management", "ApplyLookTable", icm.applyLookTable, keyFile); saveToKeyfile(!pedited || pedited->icm.applyBaselineExposureOffset, "Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset, keyFile); @@ -8320,7 +8334,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_key("LensProfile", "LCPFile")) { - lensProf.lcpFile = expandRelativePath(fname, "", keyFile.get_string("LensProfile", "LCPFile")); + if (options.rtSettings.lensProfilesPath.empty() + || !Glib::path_is_absolute(options.rtSettings.lensProfilesPath)) { + lensProf.lcpFile = expandRelativePath(fname, "", keyFile.get_string("LensProfile", "LCPFile")); + } else { + // if the "lens profiles directory" in Preferences exists and is an absolute path, + // use it as a prefix if the path to the LCP file is relative + lensProf.lcpFile = expandRelativePath(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, "", keyFile.get_string("LensProfile", "LCPFile")); + } if (pedited) { pedited->lensProf.lcpFile = true; @@ -9350,7 +9371,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("Color Management")) { if (keyFile.has_key("Color Management", "InputProfile")) { - icm.inputProfile = expandRelativePath(fname, "file:", keyFile.get_string("Color Management", "InputProfile")); + if (options.rtSettings.cameraProfilesPath.empty() + || !Glib::path_is_absolute(options.rtSettings.cameraProfilesPath)) { + icm.inputProfile = expandRelativePath(fname, "file:", keyFile.get_string("Color Management", "InputProfile")); + } else { + // if the "camera profiles directory" in Preferences exists and is an absolute path, + // use it as a prefix if the path to the Custom Input Profile is relative + icm.inputProfile = expandRelativePath(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, "file:", keyFile.get_string("Color Management", "InputProfile")); + } if (pedited) { pedited->icm.inputProfile = true; diff --git a/rtengine/settings.h b/rtengine/settings.h index bc49a2281..19d3b6ed6 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -48,6 +48,8 @@ public: bool verbose; Glib::ustring darkFramesPath; ///< The default directory for dark frames 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 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 fc543709f..fd9e87c8d 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -566,6 +566,9 @@ void Options::setDefaults() rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; + rtSettings.cameraProfilesPath = ""; + rtSettings.lensProfilesPath = ""; + #ifdef WIN32 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" @@ -663,6 +666,8 @@ void Options::setDefaults() lastIccDir = rtSettings.iccDirectory; lastDarkframeDir = rtSettings.darkFramesPath; lastFlatfieldDir = rtSettings.flatFieldsPath; + 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 @@ -791,6 +796,14 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.flatFieldsPath = keyFile.get_string("General", "FlatFieldsPath"); } + if (keyFile.has_key("General", "CameraProfilesPath")) { + rtSettings.cameraProfilesPath = keyFile.get_string("General", "CameraProfilesPath"); + } + + if (keyFile.has_key("General", "LensProfilesPath")) { + rtSettings.lensProfilesPath = keyFile.get_string("General", "LensProfilesPath"); + } + if (keyFile.has_key("General", "Verbose")) { rtSettings.verbose = keyFile.get_boolean("General", "Verbose"); } @@ -2047,6 +2060,8 @@ void Options::readFromFile(Glib::ustring fname) safeDirGet(keyFile, "Dialogs", "LastIccDir", lastIccDir); safeDirGet(keyFile, "Dialogs", "LastDarkframeDir", lastDarkframeDir); safeDirGet(keyFile, "Dialogs", "LastFlatfieldDir", lastFlatfieldDir); + safeDirGet(keyFile, "Dialogs", "LastCameraProfilesDir", lastCameraProfilesDir); + safeDirGet(keyFile, "Dialogs", "LastLensProfilesDir", lastLensProfilesDir); safeDirGet(keyFile, "Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); safeDirGet(keyFile, "Dialogs", "LastLabCurvesDir", lastLabCurvesDir); safeDirGet(keyFile, "Dialogs", "LastRetinexDir", lastRetinexDir); @@ -2150,6 +2165,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_boolean("General", "Verbose", rtSettings.verbose); keyFile.set_integer("General", "Cropsleep", rtSettings.cropsleep); keyFile.set_double("General", "Reduchigh", rtSettings.reduchigh); @@ -2484,6 +2501,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Dialogs", "LastIccDir", lastIccDir); keyFile.set_string("Dialogs", "LastDarkframeDir", lastDarkframeDir); keyFile.set_string("Dialogs", "LastFlatfieldDir", lastFlatfieldDir); + keyFile.set_string("Dialogs", "LastCameraProfilesDir", lastCameraProfilesDir); + keyFile.set_string("Dialogs", "LastLensProfilesDir", lastLensProfilesDir); keyFile.set_string("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); keyFile.set_string("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); keyFile.set_string("Dialogs", "LastRetinexDir", lastRetinexDir); diff --git a/rtgui/options.h b/rtgui/options.h index bc5e41c91..6385709db 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -432,6 +432,8 @@ public: Glib::ustring lastIccDir; Glib::ustring lastDarkframeDir; Glib::ustring lastFlatfieldDir; + 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 c6c2eb61b..a4c7410da 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -589,6 +589,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 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)); @@ -602,7 +603,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () dfconn = darkFrameDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::darkFrameChanged)); - // FLATFIELD + // Flatfield Dir Gtk::Label *ffLab = Gtk::manage(new Gtk::Label(M("PREFERENCES_FLATFIELDSDIR") + ":")); setExpandAlignProperties(ffLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); flatFieldDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); @@ -628,6 +629,25 @@ Gtk::Widget* Preferences::getImageProcessingPanel () dirgrid->attach_next_to(*clutsDir, *clutsDirLabel, Gtk::POS_RIGHT, 1, 1); dirgrid->attach_next_to(*clutsRestartNeeded, *clutsDir, Gtk::POS_RIGHT, 1, 1); + //Camera Profiles Dir + Gtk::Label *cameraProfilesDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_CAMERAPROFILESDIR") + ":")); + setExpandAlignProperties(cameraProfilesDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + cameraProfilesDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_CAMERAPROFILESDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(cameraProfilesDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + 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 + Gtk::Label *lensProfilesDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSPROFILESDIR") + ":")); + setExpandAlignProperties(lensProfilesDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + lensProfilesDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_LENSPROFILESDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(lensProfilesDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + dirgrid->attach_next_to(*lensProfilesDirLabel, *cameraProfilesDirLabel, Gtk::POS_BOTTOM, 1, 1); + dirgrid->attach_next_to(*lensProfilesDir, *lensProfilesDirLabel, Gtk::POS_RIGHT, 1, 1); + + //Pack directories to Image Processing panel cdf->add(*dirgrid); vbImageProcessing->pack_start (*cdf, Gtk::PACK_SHRINK, 4 ); @@ -1889,8 +1909,9 @@ void Preferences::storePreferences() moptions.rtSettings.darkFramesPath = darkFrameDir->get_filename(); moptions.rtSettings.flatFieldsPath = flatFieldDir->get_filename(); - moptions.clutsDir = clutsDir->get_filename(); + moptions.rtSettings.cameraProfilesPath = cameraProfilesDir->get_filename(); + moptions.rtSettings.lensProfilesPath = lensProfilesDir->get_filename(); moptions.baBehav.resize(ADDSET_PARAM_NUM); @@ -2162,6 +2183,10 @@ 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); setc.block(true); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index dfe1e008d..6b0d372af 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -112,6 +112,8 @@ class Preferences final : MyFileChooserButton* darkFrameDir; MyFileChooserButton* flatFieldDir; MyFileChooserButton* clutsDir; + MyFileChooserButton* cameraProfilesDir; + MyFileChooserButton* lensProfilesDir; Gtk::Label *dfLabel; Gtk::Label *ffLabel; From a974fc06f3d06e9cd28c649c38a78104cc7a40d1 Mon Sep 17 00:00:00 2001 From: Bezierr Date: Wed, 27 Jul 2022 16:50:30 +0200 Subject: [PATCH 066/326] replaceBackslash for lens profiles and camera profiles directories When saving .pp3, replace all "\\" by "/" in paths for LCPFile and InputProfile, so they are compatible between Windows and Linux. --- rtengine/procparams.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 30a2e303c..afce81e7a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -42,6 +42,19 @@ using namespace std; namespace { +Glib::ustring replaceBackslash(Glib::ustring path) +{ + size_t pos; + + pos = path.find("\\"); + while (pos != string::npos) { + path.replace(pos, 1, "/"); + pos = path.find("\\", pos); + } + return path; +} + + Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Glib::ustring &prefix, Glib::ustring embedded_fname) { if (embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) { @@ -6293,7 +6306,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo } else { // if the "lens profiles directory" in Preferences exists and is an absolute path, try to save // the path to the LCP file as relative to this directory - saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, false, lensProf.lcpFile), keyFile); + saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", replaceBackslash(relativePathIfInside(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, false, lensProf.lcpFile)), keyFile); } saveToKeyfile(!pedited || pedited->lensProf.useDist, "LensProfile", "UseDistortion", lensProf.useDist, keyFile); saveToKeyfile(!pedited || pedited->lensProf.useVign, "LensProfile", "UseVignette", lensProf.useVign, keyFile); @@ -7121,7 +7134,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo } else { // if the "camera profiles directory" in Preferences exists and is an absolute path, try to save // the path to the Custom Input Profile as relative to this directory - saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, false, icm.inputProfile), keyFile); + saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", replaceBackslash(relativePathIfInside(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, false, icm.inputProfile)), keyFile); } saveToKeyfile(!pedited || pedited->icm.toneCurve, "Color Management", "ToneCurve", icm.toneCurve, keyFile); saveToKeyfile(!pedited || pedited->icm.applyLookTable, "Color Management", "ApplyLookTable", icm.applyLookTable, keyFile); From 1c95dfe099768801fc2df3692f5b0b413c66d542 Mon Sep 17 00:00:00 2001 From: Bezierr Date: Fri, 29 Jul 2022 15:29:35 +0200 Subject: [PATCH 067/326] In filmSimulation.clutFilename, use "/" or "\" depending on OS For OS-independent use of .pp3 files: If OS is WIN32, replace any "/" in filmSimulation.clutFilename with "\\". If OS is not WIN32, replace any "\\" in filmSimulation.clutFilename with "/". --- rtengine/procparams.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index afce81e7a..e875124e3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -9978,7 +9978,23 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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", "ClutFilename", pedited, filmSimulation.clutFilename, pedited->filmSimulation.clutFilename); + #if defined (WIN32) + // if this is Windows, replace any "/" in the filename with "\\" + size_t pos = filmSimulation.clutFilename.find("/"); + while (pos != string::npos) { + filmSimulation.clutFilename.replace(pos, 1, "\\"); + pos = filmSimulation.clutFilename.find("/", pos); + } + #endif + #if !defined (WIN32) + // if this is not Windows, replace any "\\" in the filename with "/" + size_t pos = filmSimulation.clutFilename.find("\\"); + while (pos != string::npos) { + filmSimulation.clutFilename.replace(pos, 1, "/"); + pos = filmSimulation.clutFilename.find("\\", pos); + } + #endif if (keyFile.has_key("Film Simulation", "Strength")) { if (ppVersion < 321) { From 24f5d85c8d2cb57c4405ddbc573167f52dc2d69a Mon Sep 17 00:00:00 2001 From: Bezierr Date: Tue, 23 Aug 2022 16:27:47 +0200 Subject: [PATCH 068/326] Squashed commit of the following: commit e293f0890866ddf934ba1a9dd9fa372364766bb3 Author: Bezierr Date: Tue Aug 23 16:16:23 2022 +0200 Added comment commit 20a50b248dc110eeb4b526c7242920a68216c88c Author: Bezierr Date: Tue Aug 23 14:35:47 2022 +0200 Follow dynamicprofile.cfg symlink instead of overwriting it If dynamicprofile.cfg is a symlink, write the contents to this symlink's target instead of overwriting it. commit bad2f8c37a0d27e612150dce3219593b2f996f9c Author: Bezierr Date: Thu Aug 11 17:20:08 2022 +0200 Make dynamicprofile.cfg OS independent dynamicprofile.cfg contains OS-dependent paths to the profiles. To fix this, replace "/" or "\", depending on OS, with the correct delimiter. commit cd84120876be111c23dac5376eb5b6f6cb0a7328 Author: Bezierr Date: Thu Aug 11 16:33:39 2022 +0200 Relative paths also for Dark Frame and Flat File (a) Extended the "relative path" functionality to the (already existing, but apparently not used) directories for FlatField and DarkFrame (b) Simpler, cleaner implementation commit a338b8726451323505bb4cff1888c562fd88929d Author: Bezierr Date: Sun Aug 7 18:03:46 2022 +0200 Preference of RAW path over rtSettings path (a) Give path relative to a camera or lens profile in the same folder as the raw file precendence over path relative to rtSettings. (b) Replace backslash/slash when reading file paths, not when writing them. --- rtengine/dynamicprofile.cc | 26 ++++++++- rtengine/procparams.cc | 116 ++++++++++++++++++++----------------- rtgui/options.cc | 4 +- 3 files changed, 89 insertions(+), 57 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 28516a1ee..db1baf4b8 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -218,6 +219,22 @@ bool DynamicProfileRules::loadRules() try { rule.profilepath = kf.get_string (group, "profilepath"); + #if defined (WIN32) + // if this is Windows, replace any "/" in the path with "\\" + int pos = rule.profilepath.find("/"); + while (pos != -1) { + rule.profilepath.replace(pos, 1, "\\"); + pos = rule.profilepath.find("/", pos); + } + #endif + #if !defined (WIN32) + // if this is not Windows, replace any "\\" in the path with "/" + int pos = rule.profilepath.find("\\"); + while (pos != -1) { + rule.profilepath.replace(pos, 1, "/"); + pos = rule.profilepath.find("\\", pos); + } + #endif } catch (Glib::KeyFileError &) { dynamicRules.pop_back(); } @@ -251,7 +268,14 @@ bool DynamicProfileRules::storeRules() kf.set_string (group, "profilepath", rule.profilepath); } - return kf.save_to_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg")); + std::string fn = Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"); + if (Glib::file_test(fn, Glib::FILE_TEST_IS_SYMLINK)) { + // file is symlink; use target instead + // symlinks apparently are not recognízed on Windows + return kf.save_to_file (g_file_read_link (fn.c_str(), NULL)); + } else { + return kf.save_to_file (fn); + } } const std::vector &DynamicProfileRules::getRules() diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e875124e3..c787c7b0c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -42,19 +42,6 @@ using namespace std; namespace { -Glib::ustring replaceBackslash(Glib::ustring path) -{ - size_t pos; - - pos = path.find("\\"); - while (pos != string::npos) { - path.replace(pos, 1, "/"); - pos = path.find("\\", pos); - } - return path; -} - - Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Glib::ustring &prefix, Glib::ustring embedded_fname) { if (embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) { @@ -77,6 +64,40 @@ Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Gl return absPath; } +Glib::ustring expandRelativePath2(const Glib::ustring &procparams_fname, const Glib::ustring &procparams_fname2, const Glib::ustring &prefix, Glib::ustring embedded_fname) +{ + #if defined (WIN32) + // if this is Windows, replace any "/" in the filename with "\\" + size_t pos = embedded_fname.find("/"); + while (pos != string::npos) { + embedded_fname.replace(pos, 1, "\\"); + pos = embedded_fname.find("/", pos); + } + #endif + #if !defined (WIN32) + // if this is not Windows, replace any "\\" in the filename with "/" + size_t pos = embedded_fname.find("\\"); + while (pos != string::npos) { + embedded_fname.replace(pos, 1, "/"); + pos = embedded_fname.find("\\", pos); + } + #endif + + // if embedded_fname is not already an absolute path, + // try to convert it using procparams_fname (the directory of the raw file) as prefix + Glib::ustring rPath = expandRelativePath(procparams_fname, prefix, embedded_fname); + if (rPath.length() >= prefix.length() + && !Glib::file_test(rPath.substr(prefix.length()), Glib::FILE_TEST_IS_REGULAR) + && !procparams_fname2.empty() + && Glib::path_is_absolute(procparams_fname2)) { + // embedded_fname is not a valid path; + // try with procparams_fname2 (the path defined in Preferences) as a prefix + rPath = expandRelativePath(procparams_fname2 + G_DIR_SEPARATOR_S, prefix, embedded_fname); + } + return(rPath); +} + + Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname) { if (fnameAbsolute || embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) { @@ -105,6 +126,25 @@ Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool f return prefix + embedded_fname.substr(dir1.length()); } +Glib::ustring relativePathIfInside2(const Glib::ustring &procparams_fname, const Glib::ustring &procparams_fname2, bool fnameAbsolute, Glib::ustring embedded_fname) +{ + // try to convert embedded_fname to a path relative to procparams_fname + // (the directory of the raw file) + // (note: fnameAbsolute seems to be always true, so this will never return a relative path) + Glib::ustring rPath = relativePathIfInside(procparams_fname, fnameAbsolute, embedded_fname); + if ((Glib::path_is_absolute(rPath) + || (rPath.length() >= 5 && rPath.substr(0, 5) == "file:" && Glib::path_is_absolute(rPath.substr(5)))) + && !procparams_fname2.empty() + && Glib::path_is_absolute(procparams_fname2)) { + // if path is not relative to the directory of the raw file, + // try to convert embedded_fname to a path relative to procparams_fname2 + // (the path defined in Preferences) + rPath = relativePathIfInside(procparams_fname2 + G_DIR_SEPARATOR_S, false, embedded_fname); + } + return(rPath); +} + + void getFromKeyfile( const Glib::KeyFile& keyfile, const Glib::ustring& group_name, @@ -6300,14 +6340,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Lens profile saveToKeyfile(!pedited || pedited->lensProf.lcMode, "LensProfile", "LcMode", lensProf.getMethodString(lensProf.lcMode), keyFile); - if (options.rtSettings.lensProfilesPath.empty() - || !Glib::path_is_absolute(options.rtSettings.lensProfilesPath)) { - saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile), keyFile); - } else { - // if the "lens profiles directory" in Preferences exists and is an absolute path, try to save - // the path to the LCP file as relative to this directory - saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", replaceBackslash(relativePathIfInside(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, false, lensProf.lcpFile)), keyFile); - } + saveToKeyfile(!pedited || pedited->lensProf.lcpFile, "LensProfile", "LCPFile", relativePathIfInside2(fname, options.rtSettings.lensProfilesPath, fnameAbsolute, lensProf.lcpFile), keyFile); saveToKeyfile(!pedited || pedited->lensProf.useDist, "LensProfile", "UseDistortion", lensProf.useDist, keyFile); saveToKeyfile(!pedited || pedited->lensProf.useVign, "LensProfile", "UseVignette", lensProf.useVign, keyFile); saveToKeyfile(!pedited || pedited->lensProf.useCA, "LensProfile", "UseCA", lensProf.useCA, keyFile); @@ -7128,14 +7161,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->prsharpening.deconviter, "PostResizeSharpening", "DeconvIterations", prsharpening.deconviter, keyFile); // Color management - if (options.rtSettings.cameraProfilesPath.empty() - || !Glib::path_is_absolute(options.rtSettings.cameraProfilesPath)) { - saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.inputProfile), keyFile); - } else { - // if the "camera profiles directory" in Preferences exists and is an absolute path, try to save - // the path to the Custom Input Profile as relative to this directory - saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", replaceBackslash(relativePathIfInside(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, false, icm.inputProfile)), keyFile); - } + saveToKeyfile(!pedited || pedited->icm.inputProfile, "Color Management", "InputProfile", relativePathIfInside2(fname, options.rtSettings.cameraProfilesPath, fnameAbsolute, icm.inputProfile), keyFile); saveToKeyfile(!pedited || pedited->icm.toneCurve, "Color Management", "ToneCurve", icm.toneCurve, keyFile); saveToKeyfile(!pedited || pedited->icm.applyLookTable, "Color Management", "ApplyLookTable", icm.applyLookTable, keyFile); saveToKeyfile(!pedited || pedited->icm.applyBaselineExposureOffset, "Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset, keyFile); @@ -7507,9 +7533,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->colorToning.labregionsShowMask, "ColorToning", "LabRegionsShowMask", colorToning.labregionsShowMask, keyFile); // Raw - saveToKeyfile(!pedited || pedited->raw.darkFrame, "RAW", "DarkFrame", relativePathIfInside(fname, fnameAbsolute, raw.dark_frame), keyFile); + saveToKeyfile(!pedited || pedited->raw.darkFrame, "RAW", "DarkFrame", relativePathIfInside2(fname, options.rtSettings.darkFramesPath, fnameAbsolute, raw.dark_frame), keyFile); saveToKeyfile(!pedited || pedited->raw.df_autoselect, "RAW", "DarkFrameAuto", raw.df_autoselect, keyFile); - saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file), keyFile); + saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside2(fname, options.rtSettings.flatFieldsPath, fnameAbsolute, raw.ff_file), keyFile); saveToKeyfile(!pedited || pedited->raw.ff_AutoSelect, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurRadius, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurType, "RAW", "FlatFieldBlurType", raw.ff_BlurType, keyFile); @@ -8347,14 +8373,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_key("LensProfile", "LCPFile")) { - if (options.rtSettings.lensProfilesPath.empty() - || !Glib::path_is_absolute(options.rtSettings.lensProfilesPath)) { - lensProf.lcpFile = expandRelativePath(fname, "", keyFile.get_string("LensProfile", "LCPFile")); - } else { - // if the "lens profiles directory" in Preferences exists and is an absolute path, - // use it as a prefix if the path to the LCP file is relative - lensProf.lcpFile = expandRelativePath(options.rtSettings.lensProfilesPath + G_DIR_SEPARATOR_S, "", keyFile.get_string("LensProfile", "LCPFile")); - } + lensProf.lcpFile = expandRelativePath2(fname, options.rtSettings.lensProfilesPath, "", keyFile.get_string("LensProfile", "LCPFile")); if (pedited) { pedited->lensProf.lcpFile = true; @@ -9384,20 +9403,12 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("Color Management")) { if (keyFile.has_key("Color Management", "InputProfile")) { - if (options.rtSettings.cameraProfilesPath.empty() - || !Glib::path_is_absolute(options.rtSettings.cameraProfilesPath)) { - icm.inputProfile = expandRelativePath(fname, "file:", keyFile.get_string("Color Management", "InputProfile")); - } else { - // if the "camera profiles directory" in Preferences exists and is an absolute path, - // use it as a prefix if the path to the Custom Input Profile is relative - icm.inputProfile = expandRelativePath(options.rtSettings.cameraProfilesPath + G_DIR_SEPARATOR_S, "file:", keyFile.get_string("Color Management", "InputProfile")); - } + icm.inputProfile = expandRelativePath2(fname, options.rtSettings.cameraProfilesPath, "file:", keyFile.get_string("Color Management", "InputProfile")); if (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); @@ -10169,23 +10180,20 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("RAW")) { if (keyFile.has_key("RAW", "DarkFrame")) { - raw.dark_frame = expandRelativePath(fname, "", keyFile.get_string("RAW", "DarkFrame")); + raw.dark_frame = expandRelativePath2(fname, options.rtSettings.darkFramesPath, "", keyFile.get_string("RAW", "DarkFrame")); if (pedited) { pedited->raw.darkFrame = true; } } - assignFromKeyfile(keyFile, "RAW", "DarkFrameAuto", pedited, raw.df_autoselect, pedited->raw.df_autoselect); - if (keyFile.has_key("RAW", "FlatFieldFile")) { - raw.ff_file = expandRelativePath(fname, "", keyFile.get_string("RAW", "FlatFieldFile")); + raw.ff_file = expandRelativePath2(fname, options.rtSettings.flatFieldsPath, "", keyFile.get_string("RAW", "FlatFieldFile")); if (pedited) { pedited->raw.ff_file = true; } } - assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", pedited, raw.ff_AutoSelect, pedited->raw.ff_AutoSelect); assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", pedited, raw.ff_BlurRadius, pedited->raw.ff_BlurRadius); assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", pedited, raw.ff_BlurType, pedited->raw.ff_BlurType); diff --git a/rtgui/options.cc b/rtgui/options.cc index fd9e87c8d..b4729f9d5 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -659,8 +659,8 @@ void Options::setDefaults() rtSettings.leveldnliss = 0; rtSettings.leveldnautsimpl = 0; -// rtSettings.colortoningab =0.7; -//rtSettings.decaction =0.3; +// rtSettings.colortoningab =0.7; +// rtSettings.decaction =0.3; // rtSettings.ciebadpixgauss=false; rtSettings.rgbcurveslumamode_gamut = true; lastIccDir = rtSettings.iccDirectory; From 136bc371546b878fc6c8133f8f92ad6de8131b89 Mon Sep 17 00:00:00 2001 From: Bezierr Date: Thu, 1 Sep 2022 14:48:29 +0200 Subject: [PATCH 069/326] Change according to review --- rtengine/dynamicprofile.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index db1baf4b8..64dc14d3c 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -221,16 +221,16 @@ bool DynamicProfileRules::loadRules() rule.profilepath = kf.get_string (group, "profilepath"); #if defined (WIN32) // if this is Windows, replace any "/" in the path with "\\" - int pos = rule.profilepath.find("/"); - while (pos != -1) { + size_t pos = rule.profilepath.find("/"); + while (pos != Glib::ustring::npos) { rule.profilepath.replace(pos, 1, "\\"); pos = rule.profilepath.find("/", pos); } #endif #if !defined (WIN32) // if this is not Windows, replace any "\\" in the path with "/" - int pos = rule.profilepath.find("\\"); - while (pos != -1) { + size_t pos = rule.profilepath.find("\\"); + while (pos != Glib::ustring::npos) { rule.profilepath.replace(pos, 1, "/"); pos = rule.profilepath.find("\\", pos); } From 7b51a079cd489a2be78a72a129785e0e44b6b43c Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 2 Dec 2022 10:03:19 +0100 Subject: [PATCH 070/326] Basic support for Fujifilm X-T5 and X-H2 Closes #6624 --- rtengine/camconst.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index a2fa76806..189d8f3f4 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1543,6 +1543,12 @@ Camera constants: "ranges": { "white": 4040 } }, + { // Quality B + "make_model": [ "FUJIFILM X-T5", "FUJIFILM X-H2" ], + "dcraw_matrix": [ 11809, -5358, -1141, -4248, 12164, 2343, -514, 1097, 5848 ], // RawSpeed / DNG + "raw_crop": [ 0, 5, 7752, 5184 ] + }, + { // Quality C, Leica C-Lux names can differ? "make_model" : [ "LEICA C-LUX", "LEICA CAM-DC25" ], "dcraw_matrix" : [7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898] From abbdbe81bce66f48f97f227f566f493ea3725479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Fri, 2 Dec 2022 13:23:34 +0100 Subject: [PATCH 071/326] Add CodeQL workflow --- .github/workflows/codeql.yml | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..b90d30e27 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,89 @@ +name: "CodeQL" + +on: + push: + branches: [ 'dev' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'dev' ] + schedule: + - cron: '56 5 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + build_type: [release] + language: [ 'cpp', 'python' ] + + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Install dependencies + run: | + 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 + + - name: Configure build + run: | + export REF_NAME_FILTERED="$(echo '${{github.ref_name}}' | sed 's/[^A-z0-9_.-]//g')" + echo "Setting cache suffix." + if [ '${{github.ref_type}}' == 'tag' ]; then + export CACHE_SUFFIX="" + else + export CACHE_SUFFIX="5-$REF_NAME_FILTERED" + fi + export CACHE_SUFFIX="$CACHE_SUFFIX-AppImage" + echo "Cache suffix is '$CACHE_SUFFIX'." + echo "Making build directory." + mkdir build + echo "Changing working directory to the build directory." + cd build + echo "Running CMake configure." + cmake \ + -DCMAKE_BUILD_TYPE='${{matrix.build_type}}' \ + -DCACHE_NAME_SUFFIX="$CACHE_SUFFIX" \ + -DPROC_TARGET_NUMBER="1" \ + -DBUILD_BUNDLE="ON" \ + -DBUNDLE_BASE_INSTALL_DIR="/" \ + -DOPTION_OMP="ON" \ + -DWITH_LTO="OFF" \ + -DWITH_PROF="OFF" \ + -DWITH_SAN="OFF" \ + -DWITH_SYSTEM_KLT="OFF" \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLENSFUNDBDIR="../share/lensfun/version_1" \ + .. + echo "Recording filtered ref name." + echo "REF_NAME_FILTERED=$REF_NAME_FILTERED" >> $GITHUB_ENV + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + + - name: Build RawTherapee + working-directory: ./build + run: | + echo "Running make install." + make -j$(nproc) install DESTDIR=AppDir/usr/bin + echo "Moving usr/bin/share to usr/share." + mv AppDir/usr/bin/share AppDir/usr/ + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From 4223f114cbec46812082e3168c9ee0efaf9d0fc2 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 3 Dec 2022 17:49:26 -0800 Subject: [PATCH 072/326] Clean up merge --- rtengine/dcp.cc | 31 ++++++++++++++----------------- rtengine/dcp.h | 4 ++-- rtengine/imagedata.cc | 26 +++++++++++++++----------- rtengine/imagedata.h | 16 +++++++++++----- rtengine/imageio.cc | 1 - rtengine/improcfun.cc | 2 +- rtengine/simpleprocess.cc | 5 ----- rtgui/thumbnail.cc | 1 - rtgui/thumbnail.h | 1 - 9 files changed, 43 insertions(+), 44 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index feca2422a..5fe078fa3 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include #include "dcp.h" @@ -2182,8 +2185,7 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) && lastdot <= sname.size() - 4 && !sname.casefold().compare(lastdot, 4, ".dcp") ) { - const Glib::ustring cam_short_name = sname.substr(0, lastdot).uppercase(); - file_std_profiles[cam_short_name] = fname; // They will be loaded and cached on demand + file_std_profiles[sname.substr(0, lastdot).casefold_collate_key()] = fname; // They will be loaded and cached on demand } } else { // Directory @@ -2194,11 +2196,10 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) for (const auto& alias : getAliases(rt_profile_dir)) { const Glib::ustring alias_name = Glib::ustring(alias.first).uppercase(); - const Glib::ustring real_name = Glib::ustring(alias.second).uppercase(); - const std::map::const_iterator real = file_std_profiles.find(real_name); + const std::map::const_iterator real = file_std_profiles.find(Glib::ustring(alias.second).casefold_collate_key()); if (real != file_std_profiles.end()) { - file_std_profiles[alias_name] = real->second; + file_std_profiles[alias_name.casefold_collate_key()] = real->second; } } } @@ -2220,19 +2221,19 @@ bool DCPStore::isValidDCPFileName(const Glib::ustring& filename) const DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const { + const auto key = filename.casefold_collate_key(); MyMutex::MyLock lock(mutex); + const std::map::const_iterator iter = profile_cache.find(key); - const std::map::iterator r = profile_cache.find(filename); - - if (r != profile_cache.end()) { - return r->second; + if (iter != profile_cache.end()) { + return iter->second; } DCPProfile* const res = new DCPProfile(filename); if (res->isValid()) { // Add profile - profile_cache[filename] = res; + profile_cache[key] = res; if (options.rtSettings.verbose) { printf("DCP profile '%s' loaded from disk\n", filename.c_str()); } @@ -2245,13 +2246,9 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const DCPProfile* DCPStore::getStdProfile(const Glib::ustring& requested_cam_short_name) const { - const Glib::ustring name = requested_cam_short_name.uppercase(); - - // Warning: do NOT use map.find(), since it does not seem to work reliably here - for (const auto& file_std_profile : file_std_profiles) { - if (file_std_profile.first == name) { - return getProfile(file_std_profile.second); - } + const std::map::const_iterator iter = file_std_profiles.find(requested_cam_short_name.casefold_collate_key()); + if (iter != file_std_profiles.end()) { + return getProfile(iter->second); } // profile not found, looking if we're in loadAll=false mode diff --git a/rtengine/dcp.h b/rtengine/dcp.h index d05fdb4cc..378a70bf1 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -170,10 +170,10 @@ private: std::vector profileDir; // these contain standard profiles from RT. keys are all in uppercase, file path is value - std::map file_std_profiles; + std::map file_std_profiles; // Maps file name to profile as cache - mutable std::map profile_cache; + mutable std::map profile_cache; }; } diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 3478bfc9f..eb8fed1d8 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -26,7 +26,6 @@ #include "imagedata.h" #include "imagesource.h" -#include "procparams.h" #include "rt_math.h" #include "utils.h" @@ -35,6 +34,20 @@ using namespace rtengine; +namespace +{ + +const std::string& validateUft8(const std::string& str, const std::string& on_error = "???") +{ + if (Glib::ustring(str).validate()) { + return str; + } + + return on_error; +} + +} + namespace rtengine { extern const Settings *settings; @@ -59,15 +72,6 @@ Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) } // namespace rtengine -const std::string& validateUft8(const std::string& str, const std::string& on_error = "???") -{ - if (Glib::ustring(str).validate()) { - return str; - } - - return on_error; -} - FramesMetaData* FramesMetaData::fromFile(const Glib::ustring& fname) { return new FramesData(fname); @@ -644,7 +648,7 @@ std::string FramesMetaData::expcompToString(double expcomp, bool maskZeroexpcomp double FramesMetaData::shutterFromString(std::string s) { - const std::string::size_type i = s.find_first_of ('/'); + const std::string::size_type i = s.find_first_of('/'); if (i == std::string::npos) { return std::atof(s.c_str()); diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index cd1922c6f..f692d4267 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -21,18 +21,24 @@ #include #include #include -#include + #include -#include "rawimage.h" -#include "rtengine.h" +#include "imageio.h" + +namespace Glib +{ + +class ustring; + +} namespace rtengine { Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname); // TODO: Global function? -class FramesData : +class FramesData final : public FramesMetaData { private: @@ -56,7 +62,7 @@ private: bool isHDR; public: - FramesData(const Glib::ustring& fname); + explicit FramesData(const Glib::ustring& fname); void setDCRawFrameCount(unsigned int frameCount); unsigned int getFrameCount() const override; diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index f95d5db24..26ea87a44 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "rt_math.h" #include "procparams.h" diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index a5bf9ddd4..a1f115820 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5589,7 +5589,7 @@ double ImProcFunctions::getAutoDistor(const Glib::ustring &fname, int thumb_size int w_thumb = -1, h_thumb = thumb_size; eSensorType sensorType = rtengine::ST_NONE; - Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, w_thumb, h_thumb, 1, FALSE); + Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw(fname, sensorType, w_thumb, h_thumb, 1, FALSE); if (!thumb) { return 0.0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 87b97807c..596720e80 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1733,17 +1733,12 @@ private: MetadataInfo info(imgsrc->getFileName()); switch (params.metadata.mode) { case MetaDataParams::TUNNEL: - // Sending back the whole first root, which won't necessarily be the selected frame number - // and may contain subframe depending on initial raw's hierarchy - // readyImg->setMetadata (ii->getMetaData()->getRootExifData ()); readyImg->setMetadata(std::move(info)); break; case MetaDataParams::EDIT: info.setExif(params.exif); info.setIptc(params.iptc); readyImg->setMetadata(std::move(info)); - // ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy - // readyImg->setMetadata (ii->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); break; default: // case MetaDataParams::STRIP // nothing to do diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index b05605350..e50d7ac77 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -43,7 +43,6 @@ #include "paramsedited.h" #include "ppversion.h" #include "procparamchangers.h" -#include "profilestorecombobox.h" #include "version.h" diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 17e26e3c9..93d1deb93 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -26,7 +26,6 @@ #include "cacheimagedata.h" #include "threadutils.h" #include "thumbnaillistener.h" -#include "../rtengine/procparams.h" namespace rtengine { From ec84e172246f6c9121b326c3a9a6372ab71c70a4 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 3 Dec 2022 22:21:30 -0800 Subject: [PATCH 073/326] Restore cleanups to rtengine/dcp.* --- rtengine/dcp.cc | 140 ++++++++++++++++------------------ rtengine/dcp.h | 35 ++++----- rtengine/dcrop.cc | 2 +- rtengine/imagesource.h | 6 +- rtengine/improccoordinator.cc | 2 +- rtengine/improcfun.cc | 4 +- rtengine/improcfun.h | 5 +- rtengine/rawimagesource.cc | 2 +- rtengine/rawimagesource.h | 2 +- rtengine/rtthumbnail.cc | 2 +- rtengine/simpleprocess.cc | 2 +- 11 files changed, 98 insertions(+), 104 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 5fe078fa3..a858a0e71 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -38,13 +38,6 @@ #include "utils.h" #include "../rtgui/options.h" -namespace rtengine -{ - -extern const Settings* settings; - -} - using namespace rtengine; namespace @@ -55,7 +48,7 @@ namespace DCPProfile::Matrix invert3x3(const DCPProfile::Matrix& a) { DCPProfile::Matrix res = a; - if (!invertMatrix(a, res) && settings->verbose) { + if (!invertMatrix(a, res)) { std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl; } return res; @@ -340,8 +333,6 @@ double xyCoordToTemperature(const std::array& white_xy) // Search for line pair coordinate is between. double last_dt = 0.0; - double last_dv = 0.0; - double last_du = 0.0; for (uint32_t index = 1; index <= 30; ++index) { // Convert slope to delta-u and delta-v, with length 1. @@ -377,23 +368,11 @@ double xyCoordToTemperature(const std::array& white_xy) // Interpolate the temperature. res = 1.0e6 / (temp_table[index - 1].r * f + temp_table[index].r * (1.0 - f)); - - // Find delta from black body point to test coordinate. - uu = u - (temp_table [index - 1].u * f + temp_table [index].u * (1.0 - f)); - vv = v - (temp_table [index - 1].v * f + temp_table [index].v * (1.0 - f)); - // Interpolate vectors along slope. - du = du * (1.0 - f) + last_du * f; - dv = dv * (1.0 - f) + last_dv * f; - len = sqrt (du * du + dv * dv); - du /= len; - dv /= len; break; } // Try next line pair. last_dt = dt; - last_du = du; - last_dv = dv; } return res; @@ -486,9 +465,7 @@ public: { if (!file_) { #ifndef NDEBUG - if (settings->verbose) { - std::cerr << "ERROR: No file opened." << std::endl; - } + std::cerr << "ERROR: No file opened." << std::endl; #endif return false; } @@ -500,7 +477,7 @@ public: std::uint16_t bo; std::fread(&bo, 1, 2, file_); order_ = ByteOrder(bo); - + get2(); // Skip // Seek to IFD @@ -528,7 +505,7 @@ public: { return tags_.find(id) != tags_.end(); } - + std::string toString(int id) const { const Tags::const_iterator tag = tags_.find(id); @@ -558,24 +535,28 @@ public: } return 0; } + case BYTE: { if (offset < tag->second.value.size()) { return tag->second.value[offset]; } return 0; } + case SSHORT: { if (offset + 1 < tag->second.value.size()) { return static_cast(sget2(tag->second.value.data() + offset)); } return 0; } + case SHORT: { if (offset + 1 < tag->second.value.size()) { return sget2(tag->second.value.data() + offset); } return 0; } + case SLONG: case LONG: { if (offset + 3 < tag->second.value.size()) { @@ -583,6 +564,7 @@ public: } return 0; } + case SRATIONAL: case RATIONAL: { if (offset + 7 < tag->second.value.size()) { @@ -594,27 +576,29 @@ public: } return 0; } + case FLOAT: { return toDouble(id, offset); } + default: { return 0; } } } - + int toShort(int id, std::size_t offset = 0) const { return toInt(id, offset, SHORT); } - + double toDouble(int id, std::size_t offset = 0) const { const Tags::const_iterator tag = tags_.find(id); if (tag == tags_.end()) { return 0.0; } - + switch (tag->second.type) { case SBYTE: { if (offset < tag->second.value.size()) { @@ -622,24 +606,28 @@ public: } return 0.0; } + case BYTE: { if (offset < tag->second.value.size()) { return tag->second.value[offset]; } return 0.0; } + case SSHORT: { if (offset + 1 < tag->second.value.size()) { return static_cast(sget2(tag->second.value.data() + offset)); } return 0.0; } + case SHORT: { if (offset + 1 < tag->second.value.size()) { return sget2(tag->second.value.data() + offset); } return 0.0; } + case SLONG: case LONG: { if (offset + 3 < tag->second.value.size()) { @@ -647,6 +635,7 @@ public: } return 0.0; } + case SRATIONAL: case RATIONAL: { if (offset + 7 < tag->second.value.size()) { @@ -659,14 +648,17 @@ public: } return 0.0; } + case FLOAT: { union IntFloat { std::uint32_t i; float f; } conv; + conv.i = sget4(tag->second.value.data() + offset); - return conv.f; // IEEE FLOATs are already C format, they just need a recast + return conv.f; // IEEE FLOATs are already C format, they just need a recast } + default: { return 0.0; } @@ -689,9 +681,9 @@ private: TagType type; unsigned int count; }; - + using Tags = std::unordered_map; - + std::uint16_t sget2(const std::uint8_t* s) const { if (order_ == INTEL) { @@ -700,7 +692,7 @@ private: return s[0] << 8 | s[1]; } } - + std::uint32_t sget4(const std::uint8_t* s) const { if (order_ == INTEL) { @@ -709,16 +701,16 @@ private: return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; } } - + std::uint16_t get2() - { + { std::uint16_t res = std::numeric_limits::max(); std::fread(&res, 1, 2, file_); return sget2(reinterpret_cast(&res)); } - + std::uint32_t get4() - { + { std::uint32_t res = std::numeric_limits::max(); std::fread(&res, 1, 4, file_); return sget4(reinterpret_cast(&res)); @@ -734,32 +726,32 @@ private: case UNDEFINED: { return 1; } - + case SHORT: case SSHORT: { return 2; } - + case LONG: case SLONG: case FLOAT: { return 4; } - + case RATIONAL: case SRATIONAL: case DOUBLE: { return 8; } } - + return 1; } bool parseTag(Tag& tag) { tag.id = get2(); - tag.type = TagType(get2()); + tag.type = TagType(get2()); tag.count = std::max(1U, get4()); // Filter out invalid tags @@ -767,7 +759,7 @@ private: // (only a small part of it will actually be parsed though) if ( tag.type == INVALID - || tag.type > DOUBLE + || tag.type > DOUBLE || tag.count > 10 * 1024 * 1024 ) { tag.type = INVALID; @@ -798,19 +790,19 @@ private: // Seek back to the saved position std::fseek(file_, saved_position, SEEK_SET); - + return true; } - + FILE* const file_; - + Tags tags_; ByteOrder order_; }; } // namespace -struct DCPProfile::ApplyState::Data { +struct DCPProfileApplyState::Data { float pro_photo[3][3]; float work[3][3]; bool already_pro_photo; @@ -819,14 +811,12 @@ struct DCPProfile::ApplyState::Data { float bl_scale; }; -DCPProfile::ApplyState::ApplyState() : +DCPProfileApplyState::DCPProfileApplyState() : data(new Data{}) { } -DCPProfile::ApplyState::~ApplyState() -{ -} +DCPProfileApplyState::~DCPProfileApplyState() = default; DCPProfile::DCPProfile(const Glib::ustring& filename) : has_color_matrix_1(false), @@ -1124,7 +1114,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : FILE* const file = g_fopen(filename.c_str(), "rb"); if (file == nullptr) { - //printf ("Unable to load DCP profile '%s' !", filename.c_str()); + printf ("Unable to load DCP profile '%s' !", filename.c_str()); return; } @@ -1170,9 +1160,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Color Matrix (one is always there) if (!md.find(TAG_KEY_COLOR_MATRIX_1)) { - if (settings->verbose) { - std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; - } + std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; fclose(file); return; } @@ -1408,25 +1396,25 @@ void DCPProfile::apply( const TMatrix work_matrix = ICCStore::getInstance()->workingSpaceInverseMatrix(working_space); + const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant); // Camera RGB to XYZ D50 matrix + const std::vector delta_base = makeHueSatMap(white_balance, preferred_illuminant); if (delta_base.empty()) { apply_hue_sat_map = false; } - const Matrix xyz_cam = makeXyzCam(white_balance, pre_mul, cam_wb_matrix, preferred_illuminant); // Camera RGB to XYZ D50 matrix - if (!apply_hue_sat_map) { // The fast path: No LUT --> Calculate matrix for direct conversion raw -> working space float mat[3][3] = {}; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - + double temp = 0.0; for (int k = 0; k < 3; ++k) { - mat[i][j] += work_matrix[i][k] * xyz_cam[k][j]; + temp += work_matrix[i][k] * xyz_cam[k][j]; } - + mat[i][j] = temp; } } @@ -1452,11 +1440,11 @@ void DCPProfile::apply( for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - + double temp = 0.0; for (int k = 0; k < 3; ++k) { - pro_photo[i][j] += prophoto_xyz[i][k] * xyz_cam[k][j]; + temp += prophoto_xyz[i][k] * xyz_cam[k][j]; } - + pro_photo[i][j] = temp; } } @@ -1464,11 +1452,11 @@ void DCPProfile::apply( for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - + double temp = 0.0; for (int k = 0; k < 3; ++k) { - work[i][j] += work_matrix[i][k] * xyz_prophoto[k][j]; + temp += work_matrix[i][k] * xyz_prophoto[k][j]; } - + work[i][j] = temp; } } @@ -1510,7 +1498,7 @@ void DCPProfile::apply( } } -void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out) +void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out) { as_out.data->use_tone_curve = use_tone_curve; as_out.data->apply_look_table = apply_look_table; @@ -1539,9 +1527,11 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { + double temp = 0.0; for (int k = 0; k < 3; k++) { - as_out.data->pro_photo[i][j] += prophoto_xyz[i][k] * mWork[k][j]; + temp += prophoto_xyz[i][k] * mWork[k][j]; } + as_out.data->pro_photo[i][j] = temp; } } @@ -1550,18 +1540,20 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { + double temp = 0.0; for (int k = 0; k < 3; k++) { - as_out.data->work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; + temp += mWork[i][k] * xyz_prophoto[k][j]; } + as_out.data->work[i][j] = temp; } } } } -void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const ApplyState& as_in) const +void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const { -#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) +#define FCLIP(a) ((a)>0.f?((a)<65535.5f?(a):65535.5f):0.f) #define CLIP01(a) ((a)>0?((a)<1?(a):1):0) float exp_scale = as_in.data->bl_scale; @@ -2000,7 +1992,7 @@ std::vector DCPProfile::makeHueSatMap(const ColorTemp& wh return res; } -void DCPProfile::hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const +inline void DCPProfile::hsdApply(const HsdTableInfo& table_info, const std::vector& table_base, float& h, float& s, float& v) const { // Apply the HueSatMap. Ported from Adobes reference implementation. float hue_shift; @@ -2234,7 +2226,7 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const if (res->isValid()) { // Add profile profile_cache[key] = res; - if (options.rtSettings.verbose) { + if (settings->verbose) { printf("DCP profile '%s' loaded from disk\n", filename.c_str()); } return res; diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 378a70bf1..573349348 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -36,24 +36,11 @@ namespace rtengine class ColorTemp; class Imagefloat; +class DCPProfileApplyState; class DCPProfile final { public: - class ApplyState final - { - public: - ApplyState(); - ~ApplyState(); - - private: - struct Data; - - std::unique_ptr data; - - friend class DCPProfile; - }; - struct Illuminants { short light_source_1; short light_source_2; @@ -85,10 +72,10 @@ public: const ColorTemp& white_balance, const Triple& pre_mul, const Matrix& cam_wb_matrix, - bool apply_hue_sat_map + bool apply_hue_sat_map = true ) const; - void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out); - void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const; + void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, DCPProfileApplyState& as_out); + void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const; private: struct HsbModify { @@ -149,6 +136,20 @@ private: AdobeToneCurve tone_curve; }; +class DCPProfileApplyState final +{ +public: + DCPProfileApplyState(); + ~DCPProfileApplyState(); + +private: + struct Data; + + const std::unique_ptr data; + + friend class DCPProfile; +}; + class DCPStore final : public NonCopyable { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index d644d2d1e..790a2bf0d 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1152,7 +1152,7 @@ void Crop::update(int todo) } */ double rrm, ggm, bbm; - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, as); LUTu histToneCurve; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 67bec48dd..d89681137 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -28,7 +28,6 @@ #include "rtengine.h" #include "colortemp.h" #include "array2D.h" -#include "dcp.h" template class LUT; @@ -42,8 +41,9 @@ namespace rtengine { class ColorTemp; -class Imagefloat; class DCPProfile; +class DCPProfileApplyState; +class Imagefloat; class RetinexgaintransmissionCurve; class RetinextransmissionCurve; @@ -137,7 +137,7 @@ public: virtual ImageMatrices* getImageMatrices () = 0; virtual bool isRAW () const = 0; - virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &as) + virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) { return nullptr; }; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 128420359..804e81ac0 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1300,7 +1300,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double ggm = 33.; double bbm = 33.; - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params->icm, as); ipf.rgbProc(oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation, diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index a1f115820..861cc8d7d 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2021,7 +2021,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, - double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { rgbProc(working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, @@ -2035,7 +2035,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, - DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) + DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { std::unique_ptr stop; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f21e9d7be..c11f0810b 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -49,6 +49,7 @@ namespace rtengine class ColorAppearance; class ColorGradientCurve; class DCPProfile; +class DCPProfileApplyState; class FlatCurve; class FramesMetaData; class LensCorrection; @@ -168,13 +169,13 @@ enum class BlurType { const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, - const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, - int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); + int hlcomprthresh, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 21258c9a7..8f8a71553 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -980,7 +980,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima } } -DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as) +DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileApplyState &as) { if (cmp.inputProfile == "(camera)" || cmp.inputProfile == "(none)") { return nullptr; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index fecde5d96..16677b1da 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -184,7 +184,7 @@ public: void getAutoExpHistogram (LUTu & histogram, int& histcompr) override; void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override; void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, std::vector &outCurve) override; - DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfile::ApplyState &as) override; + 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); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5d6fa3aeb..30855b1f1 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1355,7 +1355,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT LabImage* labView = new LabImage (fw, fh); DCPProfile *dcpProf = nullptr; - DCPProfile::ApplyState as; + DCPProfileApplyState as; if (isRaw) { cmsHPROFILE dummy; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 596720e80..6ae805d94 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1282,7 +1282,7 @@ private: } autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfile::ApplyState as; + DCPProfileApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params.icm, as); LUTu histToneCurve; From caa23df465745006ff1c45104b7e240a4f2adc83 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 6 May 2019 09:27:44 +0200 Subject: [PATCH 074/326] report "Unknown" for unknown lenses (cherry picked from commit 36d7710ee270d776729d926b7c4ba028713bdb06) --- rtengine/imagedata.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index eb8fed1d8..1977061db 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -283,6 +283,9 @@ FramesData::FramesData(const Glib::ustring &fname) : if (lens.empty()) { lens = "Unknown"; } + if (lens.empty()) { + lens = "Unknown"; + } std::string datetime_taken; if (find_exif_tag("Exif.Image.DateTimeOriginal")) { From 1a771fa2110b4d537d612291fbdcb7665805ad2b Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 14 May 2019 07:03:07 -0700 Subject: [PATCH 075/326] more work on synchronizing metadata with xmp sidecars (cherry picked from commit 81bbff6e6ae87bd35e8050a1cc621297ca24939b) --- rtengine/CMakeLists.txt | 1 + rtengine/imagedata.cc | 28 +--- rtengine/imagedata.h | 4 - rtengine/imageio.cc | 92 ++++------- rtengine/imageio.h | 24 +-- rtengine/improccoordinator.cc | 63 ++++---- rtengine/metadata.cc | 291 ++++++++++++++++++++++++++++++++++ rtengine/metadata.h | 80 ++++++++++ rtengine/procparams.h | 5 + rtengine/settings.h | 16 +- rtengine/simpleprocess.cc | 29 ++-- rtgui/exifpanel.cc | 7 +- rtgui/iptcpanel.cc | 7 +- rtgui/options.cc | 53 ++++++- rtgui/preferences.cc | 47 +++++- rtgui/preferences.h | 3 + rtgui/thumbnail.cc | 32 ++++ rtgui/thumbnail.h | 2 + 18 files changed, 611 insertions(+), 173 deletions(-) create mode 100644 rtengine/metadata.cc create mode 100644 rtengine/metadata.h diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index c50abb88c..01424543b 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -145,6 +145,7 @@ set(RTENGINESOURCEFILES lj92.c lmmse_demosaic.cc loadinitial.cc + metadata.cc munselllch.cc myfile.cc panasonic_decoders.cc diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 1977061db..e7cf2b4c2 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -22,11 +22,11 @@ #include #include #include -#include #include "imagedata.h" #include "imagesource.h" #include "rt_math.h" +#include "metadata.h" #include "utils.h" #pragma GCC diagnostic warning "-Wextra" @@ -52,24 +52,6 @@ namespace rtengine { extern const Settings *settings; -Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) -{ -#ifdef EXV_UNICODE_PATH - glong ws_size = 0; - gunichar2* const ws = g_utf8_to_utf16(fname.c_str(), -1, nullptr, &ws_size, nullptr); - std::wstring wfname; - wfname.reserve(ws_size); - for (glong i = 0; i < ws_size; ++i) { - wfname.push_back(ws[i]); - } - g_free(ws); - auto image = Exiv2::ImageFactory::open(wfname); -#else - auto image = Exiv2::ImageFactory::open(fname); -#endif - return image; -} - } // namespace rtengine FramesMetaData* FramesMetaData::fromFile(const Glib::ustring& fname) @@ -106,9 +88,9 @@ FramesData::FramesData(const Glib::ustring &fname) : lens.clear(); try { - auto image = open_exiv2(fname); - image->readMetadata(); - const auto& exif = image->exifData(); + Exiv2Metadata meta(fname); + meta.load(); + const auto& exif = meta.exifData(); ok_ = true; // taken and adapted from darktable (src/common/exif.cc) @@ -189,7 +171,7 @@ FramesData::FramesData(const Glib::ustring &fname) : /* TODO: Implement ratings in exiv2 situations. See PR #5325 - + // Look for Rating metadata in the following order: // 1. EXIF // 2. XMP diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index f692d4267..b1a29dc39 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -22,8 +22,6 @@ #include #include -#include - #include "imageio.h" namespace Glib @@ -36,8 +34,6 @@ class ustring; namespace rtengine { -Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname); // TODO: Global function? - class FramesData final : public FramesMetaData { diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 26ea87a44..475792e83 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -79,39 +79,7 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) } -MetadataInfo::MetadataInfo(const Glib::ustring& src) : - src_(src), - exif_(new rtengine::procparams::ExifPairs), - iptc_(new rtengine::procparams::IPTCPairs) -{ -} - -const Glib::ustring& MetadataInfo::filename() const -{ - return src_; -} - -const rtengine::procparams::ExifPairs& MetadataInfo::exif() const -{ - return *exif_; -} - -const rtengine::procparams::IPTCPairs& MetadataInfo::iptc() const -{ - return *iptc_; -} - -void MetadataInfo::setExif(const rtengine::procparams::ExifPairs &exif) -{ - *exif_ = exif; -} - -void MetadataInfo::setIptc(const rtengine::procparams::IPTCPairs &iptc) -{ - *iptc_ = iptc; -} - -void ImageIO::setMetadata(MetadataInfo info) +void ImageIO::setMetadata(Exiv2Metadata info) { metadataInfo = std::move(info); } @@ -1181,9 +1149,9 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, (bps == 16 || bps == 32) && isFloat ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT); /* - + TODO: Re-apply fix from #5787 - + [out]() { const std::vector default_tags = rtexif::ExifManager::getDefaultTIFFTags(nullptr); @@ -1388,32 +1356,34 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const } try { - auto src = open_exiv2(metadataInfo.filename()); - auto dst = open_exiv2(fname); - src->readMetadata(); - dst->setMetadata(*src); - dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; - for (const auto& p : metadataInfo.exif()) { - try { - dst->exifData()[p.first] = p.second; - } catch (const Exiv2::AnyError& exc) { - } - } - for (const auto& p : metadataInfo.iptc()) { - try { - auto& v = p.second; - if (!v.empty()) { - dst->iptcData()[p.first] = v[0]; - for (size_t j = 1; j < v.size(); ++j) { - Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); - d.setValue(v[j]); - dst->iptcData().add(d); - } - } - } catch (const Exiv2::AnyError& exc) { - } - } - dst->writeMetadata(); + metadataInfo.load(); + metadataInfo.saveToImage(fname); + // auto src = open_exiv2(metadataInfo.filename()); + // auto dst = open_exiv2(fname); + // src->readMetadata(); + // dst->setMetadata(*src); + // dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; + // for (const auto& p : metadataInfo.exif()) { + // try { + // dst->exifData()[p.first] = p.second; + // } catch (const Exiv2::AnyError& exc) { + // } + // } + // for (const auto& p : metadataInfo.iptc()) { + // try { + // auto& v = p.second; + // if (!v.empty()) { + // dst->iptcData()[p.first] = v[0]; + // for (size_t j = 1; j < v.size(); ++j) { + // Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); + // d.setValue(v[j]); + // dst->iptcData().add(d); + // } + // } + // } catch (const Exiv2::AnyError& exc) { + // } + // } + // dst->writeMetadata(); return true; } catch (const Exiv2::AnyError& exc) { std::cout << "EXIF ERROR: " << exc.what() << std::endl; diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 3283d5816..26e7164e6 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -24,6 +24,7 @@ #include "iimage.h" #include "imagedimensions.h" #include "imageformat.h" +#include "metadata.h" #include "rtengine.h" enum { @@ -52,25 +53,6 @@ class ColorTemp; class ProgressListener; class Imagefloat; -class MetadataInfo final -{ -public: - explicit MetadataInfo(const Glib::ustring& src = {}); - - const Glib::ustring& filename() const; - - const rtengine::procparams::ExifPairs& exif() const; - const rtengine::procparams::IPTCPairs& iptc() const; - - void setExif(const rtengine::procparams::ExifPairs &exif); - void setIptc(const rtengine::procparams::IPTCPairs &iptc); - -private: - Glib::ustring src_; - std::unique_ptr exif_; - std::unique_ptr iptc_; -}; - class ImageIO : virtual public ImageDatas { @@ -84,7 +66,7 @@ protected: MyMutex imutex; IIOSampleFormat sampleFormat; IIOSampleArrangement sampleArrangement; - MetadataInfo metadataInfo; + Exiv2Metadata metadataInfo; private: void deleteLoadedProfileData( ); @@ -124,7 +106,7 @@ public: cmsHPROFILE getEmbeddedProfile () const; void getEmbeddedProfileData (int& length, unsigned char*& pdata) const; - void setMetadata(MetadataInfo info); + void setMetadata(Exiv2Metadata info); void setOutputProfile(const std::string& pdata); bool saveMetadata(const Glib::ustring &fname) const; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 804e81ac0..b74a137ff 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,6 +31,7 @@ #include "image8.h" #include "imagefloat.h" #include "improcfun.h" +#include "metadata.h" #include "labimage.h" #include "lcp.h" #include "procparams.h" @@ -320,7 +321,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) RAWParams rp = params->raw; ColorManagementParams cmp = params->icm; LCurveParams lcur = params->labCurve; - + if (!highDetailNeeded) { // if below 100% magnification, take a fast path if (rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::NONE) && rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)) { @@ -528,8 +529,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lastAwbauto = ""; autoWB.useDefaults(params->wb.equal); } - - + + } currWB = autoWB; @@ -542,11 +543,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (autowb && awbListener && params->wb.method == "autitcgreen") { awbListener->WBChanged(params->wb.temperature, params->wb.green, studgood); - } + } if (autowb && awbListener && params->wb.method == "autold") { awbListener->WBChanged(params->wb.temperature, params->wb.green, -1.f); - } + } /* GammaValues g_a; @@ -748,7 +749,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) whiteev = new float[sizespot]; bool *Autogr = nullptr; Autogr = new bool[sizespot]; - + float *locx = nullptr; locx = new float[sizespot]; float *locy = nullptr; @@ -761,7 +762,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) centx = new float[sizespot]; float *centy = nullptr; centy = new float[sizespot]; - + for (int sp = 0; sp < sizespot; sp++) { log[sp] = params->locallab.spots.at(sp).explog; autocomput[sp] = params->locallab.spots.at(sp).autocompute; @@ -865,7 +866,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // if ((todo & (M_LUMINANCE + M_COLOR)) || (todo & M_AUTOEXP)) { // if (todo & M_RGBCURVE) { if (((todo & (M_AUTOEXP | M_RGBCURVE)) || (todo & M_CROP)) && params->locallab.enabled && !params->locallab.spots.empty()) { - + ipf.rgb2lab(*oprevi, *oprevl, params->icm.workingProfile); nprevl->CopyFrom(oprevl); @@ -964,7 +965,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const bool llmaslogutili = locllmaslogCurve.Set(params->locallab.spots.at(sp).LLmaskcurveL); const bool lcmaslogutili = locccmaslogCurve.Set(params->locallab.spots.at(sp).CCmaskcurveL); const bool lhmaslogutili = lochhmaslogCurve.Set(params->locallab.spots.at(sp).HHmaskcurveL); - + 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); @@ -1053,7 +1054,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) int xxe = xend * ww; int yys = ysta * hh; int yye = yend * hh; - + if(istm) { //calculate mean and sigma on full image for RT-spot use by normalize_mean_dt ipf.mean_sig (nprevl->L, meantme, stdtme, xxs, xxe, yys, yye); } @@ -1073,7 +1074,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float stdtm = stdtms[sp] = stdtme; float meanreti = meanretis[sp] = meanretie; float stdreti = stdretis[sp] = stdretie; - + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lumar, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, sca); @@ -1125,7 +1126,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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, lochhhmas_Curve, lhhmas_utili, loclmasCurveblwav, lmasutiliblwav, @@ -1145,13 +1146,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) meantm, stdtm, meanreti, stdreti); - + if(istm) { //calculate mean and sigma on full image for use by normalize_mean_dt float meanf = 0.f; float stdf = 0.f; ipf.mean_sig (savenormtm.get()->L, meanf, stdf, xxs, xxe, yys, yye); - - //using 2 unused variables noiselumc and softradiustm + + //using 2 unused variables noiselumc and softradiustm params->locallab.spots.at(sp).noiselumc = (int) meanf; params->locallab.spots.at(sp).softradiustm = stdf ; } @@ -1160,7 +1161,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float meanf = 0.f; float stdf = 0.f; ipf.mean_sig (savenormreti.get()->L, meanf, stdf,xxs, xxe, yys, yye ); - //using 2 unused variables sensihs and sensiv + //using 2 unused variables sensihs and sensiv params->locallab.spots.at(sp).sensihs = (int) meanf; params->locallab.spots.at(sp).sensiv = (int) stdf; } @@ -1207,9 +1208,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //************************************************************* // end locallab //************************************************************* - + } - + if ((todo & M_RGBCURVE) || (todo & M_CROP)) { //complexCurve also calculated pre-curves histogram depending on crop CurveFactory::complexCurve(params->toneCurve.expcomp, params->toneCurve.black / 65535.0, @@ -1412,7 +1413,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bool proedge = WaveParams.expedge; bool profin = WaveParams.expfinal; bool proton = WaveParams.exptoning; - bool pronois = WaveParams.expnoise; + bool pronois = WaveParams.expnoise; if(WaveParams.showmask) { // WaveParams.showmask = false; @@ -1436,7 +1437,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expedge = false; WaveParams.expfinal = false; WaveParams.exptoning = false; - WaveParams.expnoise = false; + WaveParams.expnoise = false; } ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); @@ -1449,7 +1450,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expfinal = profin; WaveParams.exptoning = proton; WaveParams.expnoise = pronois; - + if (WaveParams.softrad > 0.f) { array2D ble(pW, pH); @@ -1479,7 +1480,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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; @@ -1505,11 +1506,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Color::XYZ2Lab(X, Y, Z, L, a, b); nprevl->L[ir][jr] = L; } - + delete tmpImage; } - + } if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { @@ -1518,7 +1519,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float mL0; float mC0; float background = 0.f; - int show = 0; + int show = 0; @@ -1560,8 +1561,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete unshar; unshar = NULL; - - + + /* if (WaveParams.softrad > 0.f) { array2D ble(pW, pH); @@ -1606,7 +1607,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } - + } ipf.softLight(nprevl, params->softlight); @@ -1689,7 +1690,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // acListener->wbCamChanged(params->wb.temperature, params->wb.green); //real temp and tint // acListener->wbCamChanged(params->wb.temperature, 1.f); //real temp and tint = 1. // } - + } else { // CIECAM is disabled, we free up its image buffer to save some space if (ncie) { @@ -2127,7 +2128,7 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou // Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window double rm, gm, bm; params->wb.method = "autold";//same result as before muliple Auto WB - + // imgsrc->getAutoWBMultipliers(rm, gm, bm); double tempitc = 5000.; double greenitc = 1.; @@ -2374,7 +2375,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a im = tempImage; } - im->setMetadata(MetadataInfo(imgsrc->getFileName())); + im->setMetadata(Exiv2Metadata(imgsrc->getFileName(), false)); im->saveTIFF(fname, 16, false, true); delete im; diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc new file mode 100644 index 000000000..15ab7db44 --- /dev/null +++ b/rtengine/metadata.cc @@ -0,0 +1,291 @@ +/* -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Griggio + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#include +#include +#include "metadata.h" +#include "settings.h" +#include "../rtgui/version.h" +#include "../rtgui/pathutils.h" + + +namespace rtengine { + +extern const Settings *settings; + + +namespace { + +Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) +{ +#ifdef EXV_UNICODE_PATH + glong ws_size = 0; + gunichar2* const ws = g_utf8_to_utf16(fname.c_str(), -1, nullptr, &ws_size, nullptr); + std::wstring wfname; + wfname.reserve(ws_size); + for (glong i = 0; i < ws_size; ++i) { + wfname.push_back(ws[i]); + } + g_free(ws); + auto image = Exiv2::ImageFactory::open(wfname); +#else + auto image = Exiv2::ImageFactory::open(Glib::filename_from_utf8(fname)); +#endif + return image; +} + +} // namespace + + +Exiv2Metadata::Exiv2Metadata(): + src_(""), + merge_xmp_(false), + image_(nullptr), + exif_(new rtengine::procparams::ExifPairs), + iptc_(new rtengine::procparams::IPTCPairs) +{ +} + + +Exiv2Metadata::Exiv2Metadata(const Glib::ustring &path): + src_(""), + merge_xmp_(settings->metadata_xmp_sync != Settings::MetadataXmpSync::NONE), + image_(nullptr), + exif_(new rtengine::procparams::ExifPairs), + iptc_(new rtengine::procparams::IPTCPairs) +{ +} + + +Exiv2Metadata::Exiv2Metadata(const Glib::ustring &path, bool merge_xmp_sidecar): + src_(path), + merge_xmp_(merge_xmp_sidecar), + image_(nullptr), + exif_(new rtengine::procparams::ExifPairs), + iptc_(new rtengine::procparams::IPTCPairs) +{ +} + + +void Exiv2Metadata::load() const +{ + if (!src_.empty() && !image_.get()) { + auto img = open_exiv2(src_); + image_.reset(img.release()); + image_->readMetadata(); + + if (merge_xmp_) { + do_merge_xmp(image_.get()); + } + } +} + +Exiv2::ExifData& Exiv2Metadata::exifData() +{ + return image_.get() ? image_->exifData() : exif_data_; +} + +const Exiv2::ExifData& Exiv2Metadata::exifData() const +{ + return const_cast(this)->exifData(); +} + +Exiv2::IptcData& Exiv2Metadata::iptcData() +{ + return image_.get() ? image_->iptcData() : iptc_data_; +} + +const Exiv2::IptcData& Exiv2Metadata::iptcData() const +{ + return const_cast(this)->iptcData(); +} + +Exiv2::XmpData& Exiv2Metadata::xmpData() +{ + return image_.get() ? image_->xmpData() : xmp_data_; +} + +const Exiv2::XmpData& Exiv2Metadata::xmpData() const +{ + return const_cast(this)->xmpData(); +} + +const Glib::ustring& Exiv2Metadata::filename() const +{ + return src_; +} + +const rtengine::procparams::ExifPairs& Exiv2Metadata::exif() const +{ + return *exif_; +} + +const rtengine::procparams::IPTCPairs& Exiv2Metadata::iptc() const +{ + return *iptc_; +} + +void Exiv2Metadata::setExif(const rtengine::procparams::ExifPairs &exif) +{ + *exif_ = exif; +} + +void Exiv2Metadata::setIptc(const rtengine::procparams::IPTCPairs &iptc) +{ + *iptc_ = iptc; +} + +void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const +{ + auto xmp = getXmpSidecar(src_); + Exiv2::ExifData exif; + Exiv2::IptcData iptc; + Exiv2::moveXmpToExif(xmp, exif); + Exiv2::moveXmpToIptc(xmp, iptc); + + for (auto &datum : exif) { + dst->exifData()[datum.key()] = datum; + } + for (auto &datum : iptc) { + dst->iptcData()[datum.key()] = datum; + } + for (auto &datum : xmp) { + dst->xmpData()[datum.key()] = datum; + } +} + + +void Exiv2Metadata::saveToImage(const Glib::ustring &path) const +{ + auto dst = open_exiv2(path); + dst->readMetadata(); + if (image_.get()) { + dst->setMetadata(*image_); + if (merge_xmp_) { + do_merge_xmp(dst.get()); + } + } else { + dst->setExifData(exif_data_); + dst->setIptcData(iptc_data_); + dst->setXmpData(xmp_data_); + } + + dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; + import_exif_pairs(dst->exifData()); + import_iptc_pairs(dst->iptcData()); + dst->writeMetadata(); +} + + +void Exiv2Metadata::import_exif_pairs(Exiv2::ExifData &out) const +{ + for (auto &p : *exif_) { + try { + out[p.first] = p.second; + } catch (Exiv2::AnyError &exc) {} + } +} + + +void Exiv2Metadata::import_iptc_pairs(Exiv2::IptcData &out) const +{ + for (auto &p : *iptc_) { + try { + auto &v = p.second; + if (v.size() >= 1) { + out[p.first] = v[0]; + for (size_t j = 1; j < v.size(); ++j) { + Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); + d.setValue(v[j]); + out.add(d); + } + } + } catch (Exiv2::AnyError &exc) {} + } +} + + +void Exiv2Metadata::saveToXmp(const Glib::ustring &path) const +{ + Exiv2::XmpData xmp; + Exiv2::copyExifToXmp(exifData(), xmp); + Exiv2::copyIptcToXmp(iptcData(), xmp); + for (auto &datum : xmpData()) { + xmp[datum.key()] = datum; + } + Exiv2::ExifData exif; + Exiv2::IptcData iptc; + import_exif_pairs(exif); + import_iptc_pairs(iptc); + Exiv2::copyExifToXmp(exif, xmp); + Exiv2::copyIptcToXmp(iptc, xmp); + + std::string data; + bool err = false; + if (Exiv2::XmpParser::encode(data, xmp, Exiv2::XmpParser::omitPacketWrapper|Exiv2::XmpParser::useCompactFormat) != 0) { + err = true; + } else { + FILE *out = g_fopen(path.c_str(), "wb"); + if (!out || fputs(data.c_str(), out) == EOF) { + err = true; + } + if (out) { + fclose(out); + } + } + + class Error: public Exiv2::AnyError { + public: + Error(const std::string &msg): msg_(msg) {} + const char *what() const throw() { return msg_.c_str(); } + int code() const throw() { return 0; } + + private: + std::string msg_; + }; + if (err) { + throw Error("error saving XMP sidecar " + path); + } +} + + +Glib::ustring Exiv2Metadata::xmpSidecarPath(const Glib::ustring &path) +{ + Glib::ustring fn = path; + if (settings->xmp_sidecar_style == Settings::XmpSidecarStyle::STD) { + fn = removeExtension(fn); + } + return fn + ".xmp"; +} + + +Exiv2::XmpData Exiv2Metadata::getXmpSidecar(const Glib::ustring &path) +{ + Exiv2::XmpData ret; + auto fname = xmpSidecarPath(path); + if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { + auto image = open_exiv2(fname); + image->readMetadata(); + ret = image->xmpData(); + } + return ret; +} + +} // namespace rtengine diff --git a/rtengine/metadata.h b/rtengine/metadata.h new file mode 100644 index 000000000..8de384479 --- /dev/null +++ b/rtengine/metadata.h @@ -0,0 +1,80 @@ +/* -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Griggio + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#pragma once + +#include +#include +#include +#include "procparams.h" + +namespace rtengine { + +class Exiv2Metadata final +{ +public: + Exiv2Metadata(); + explicit Exiv2Metadata(const Glib::ustring& path); + Exiv2Metadata(const Glib::ustring& path, bool merge_xmp_sidecar); + + void load() const; + + Exiv2::ExifData& exifData(); + const Exiv2::ExifData& exifData() const; + + Exiv2::IptcData& iptcData(); + const Exiv2::IptcData& iptcData() const; + + Exiv2::XmpData& xmpData(); + const Exiv2::XmpData& xmpData() const; + + const Glib::ustring& filename() const; + const rtengine::procparams::ExifPairs& exif() const; + const rtengine::procparams::IPTCPairs& iptc() const; + void setExif(const rtengine::procparams::ExifPairs& exif); + void setIptc(const rtengine::procparams::IPTCPairs& iptc); + + void saveToImage(const Glib::ustring& path) const; + void saveToXmp(const Glib::ustring& path) const; + + static Glib::ustring xmpSidecarPath(const Glib::ustring& path); + static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path); + +private: + void do_merge_xmp(Exiv2::Image* dst) const; + void import_exif_pairs(Exiv2::ExifData& out) const; + void import_iptc_pairs(Exiv2::IptcData& out) const; + + Glib::ustring src_; + bool merge_xmp_; + mutable std::shared_ptr image_; + std::unique_ptr exif_; + std::unique_ptr iptc_; + Exiv2::ExifData exif_data_; + Exiv2::IptcData iptc_data_; + Exiv2::XmpData xmp_data_; +}; + +// Glib::ustring get_xmp_sidecar_path(const Glib::ustring &path); +// Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname, +// bool merge_xmp_sidecar); +// Exiv2::XmpData read_exiv2_xmp(const Glib::ustring &fname); + +} // namespace rtengine diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f72d12f81..4a1eb47e3 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1773,6 +1773,11 @@ public: return pairs.erase(key); } + bool empty() const + { + return pairs.empty(); + } + Glib::ustring& operator[](const Glib::ustring& key) { return pairs[key]; diff --git a/rtengine/settings.h b/rtengine/settings.h index 0fb4996df..f9ba55257 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -1,4 +1,5 @@ -/* +/* -*- C++ -*- + * * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath @@ -112,6 +113,19 @@ public: }; ThumbnailInspectorMode thumbnail_inspector_mode; + enum class XmpSidecarStyle { + STD, // FILENAME.xmp for FILENAME.ext + EXT // FILENAME.ext.xmp for FILENAME.ext + }; + XmpSidecarStyle xmp_sidecar_style; + + enum class MetadataXmpSync { + NONE, + READ, + READ_WRITE + }; + MetadataXmpSync metadata_xmp_sync; + /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ static Settings* create(); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 6ae805d94..0b6406b62 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -37,6 +37,7 @@ #include "mytime.h" #include "guidedfilter.h" #include "color.h" +#include "metadata.h" #undef THREAD_PRIORITY_NORMAL @@ -945,10 +946,10 @@ private: if (params.locallab.enabled && params.locallab.spots.size() > 0) { ipf.rgb2lab(*baseImg, *labView, params.icm.workingProfile); - + MyTime t1, t2; t1.set(); - + const std::unique_ptr reservView(new LabImage(*labView, true)); const std::unique_ptr lastorigView(new LabImage(*labView, true)); std::unique_ptr savenormtmView; @@ -994,7 +995,7 @@ private: LocLLmaskCurve locllmas_Curve; LocHHmaskCurve lochhmas_Curve; LocHHmaskCurve lochhhmas_Curve; - + LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; LocwavCurve loclmasCurve_wav; @@ -1073,7 +1074,7 @@ private: const bool lcmaslogutili = locccmaslogCurve.Set(params.locallab.spots.at(sp).CCmaskcurveL); const bool llmaslogutili = locllmaslogCurve.Set(params.locallab.spots.at(sp).LLmaskcurveL); const bool lhmaslogutili = lochhmaslogCurve.Set(params.locallab.spots.at(sp).HHmaskcurveL); - + 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); @@ -1129,7 +1130,7 @@ private: float stdtme; float meanretie; float stdretie; - + 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 { @@ -1148,8 +1149,8 @@ private: float Tmax; // No Locallab mask is shown in exported picture - ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, - lllocalcurve, locallutili, + ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, + lllocalcurve, locallutili, cllocalcurve, localclutili, lclocalcurve, locallcutili, loclhCurve, lochhCurve, locchCurve, @@ -1164,7 +1165,7 @@ private: lmasklclocalcurve, localmasklcutili, lmaskloglocalcurve, localmasklogutili, lmasklocal_curve, localmask_utili, - + 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, @@ -1428,8 +1429,8 @@ private: bool proedge = WaveParams.expedge; bool profin = WaveParams.expfinal; bool proton = WaveParams.exptoning; - bool pronois = WaveParams.expnoise; - + bool pronois = WaveParams.expnoise; + /* if(WaveParams.showmask) { WaveParams.showmask = false; @@ -1456,7 +1457,7 @@ private: WaveParams.expedge = false; WaveParams.expfinal = false; WaveParams.exptoning = false; - WaveParams.expnoise = false; + WaveParams.expnoise = false; } ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); @@ -1468,7 +1469,7 @@ private: WaveParams.expfinal = profin; WaveParams.exptoning = proton; WaveParams.expnoise = pronois; - + if (WaveParams.softrad > 0.f) { array2D ble(fw, fh); array2D guid(fw, fh); @@ -1523,7 +1524,7 @@ private: } delete tmpImage; } - + } if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { @@ -1730,7 +1731,7 @@ private: readyImg = tempImage; } - MetadataInfo info(imgsrc->getFileName()); + Exiv2Metadata info(imgsrc->getFileName()); switch (params.metadata.mode) { case MetaDataParams::TUNNEL: readyImg->setMetadata(std::move(info)); diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index f452c2491..7438240e9 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -25,6 +25,7 @@ #include "options.h" #include "../rtengine/imagedata.h" +#include "../rtengine/metadata.h" #include "../rtengine/procparams.h" using namespace rtengine; @@ -225,9 +226,9 @@ void ExifPanel::refreshTags() } try { - auto img = open_exiv2(fn); - img->readMetadata(); - auto& exif = img->exifData(); + rtengine::Exiv2Metadata meta(fn); + meta.load(); + auto& exif = meta.exifData(); for (const auto& p : *changeList) { try { diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 0f8471b92..724b54aa1 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -24,6 +24,7 @@ #include "rtimage.h" #include "../rtengine/imagedata.h" +#include "../rtengine/metadata.h" #include "../rtengine/procparams.h" using namespace rtengine; @@ -493,9 +494,9 @@ void IPTCPanel::setImageData (const FramesMetaData* id) embeddedData->clear(); if (id) { try { - auto img = open_exiv2(id->getFileName()); - img->readMetadata(); - auto& iptc = img->iptcData(); + rtengine::Exiv2Metadata meta(id->getFileName()); + meta.load(); + auto& iptc = meta.iptcData(); for (const auto& tag : iptc) { if (iptc_keys.find(tag.key()) != iptc_keys.end()) { (*embeddedData)[tag.key()].push_back(tag.toString()); diff --git a/rtgui/options.cc b/rtgui/options.cc index ce03db434..cf2cbaad3 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -626,7 +626,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; @@ -682,6 +682,9 @@ void Options::setDefaults() cropAutoFit = false; rtSettings.thumbnail_inspector_mode = rtengine::Settings::ThumbnailInspectorMode::JPEG; + + rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::STD; + rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::NONE; } Options* Options::copyFrom(Options* other) @@ -1488,11 +1491,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"); } @@ -1755,8 +1758,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"); @@ -2030,6 +2033,27 @@ void Options::readFromFile(Glib::ustring fname) } } + if (keyFile.has_group("Metadata")) { + if (keyFile.has_key("Metadata", "XMPSidecarStyle")) { + std::string val = keyFile.get_string("Metadata", "XMPSidecarStyle"); + if (val == "ext") { + rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::EXT; + } else { + rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle::STD; + } + } + if (keyFile.has_key("Metadata", "XMPSynchronization")) { + std::string val = keyFile.get_string("Metadata", "XMPSynchronization"); + if (val == "read") { + rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::READ; + } else if (val == "readwrite") { + rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::READ_WRITE; + } else { + rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync::NONE; + } + } + } + // -------------------------------------------------------------------------------------------------------- filterOutParsedExtensions(); @@ -2448,6 +2472,25 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Lensfun", "DBDirectory", rtSettings.lensfunDbDirectory); + switch (rtSettings.xmp_sidecar_style) { + case rtengine::Settings::XmpSidecarStyle::EXT: + keyFile.set_string("Metadata", "XMPSidecarStyle", "ext"); + break; + default: + keyFile.set_string("Metadata", "XMPSidecarStyle", "std"); + } + + switch (rtSettings.metadata_xmp_sync) { + case rtengine::Settings::MetadataXmpSync::READ: + keyFile.set_string("Metadata", "XMPSynchronization", "read"); + break; + case rtengine::Settings::MetadataXmpSync::READ_WRITE: + keyFile.set_string("Metadata", "XMPSynchronization", "readwrite"); + break; + default: + keyFile.set_string("Metadata", "XMPSynchronization", "none"); + } + keyData = keyFile.to_data(); } catch (Glib::KeyFileError &e) { diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 9d9603297..62c243802 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); @@ -581,9 +581,36 @@ Gtk::Widget* Preferences::getImageProcessingPanel () fdp->add(*vbdp); vbImageProcessing->pack_start (*fdp, Gtk::PACK_SHRINK, 4); -// Gtk::Frame* fdf = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_DARKFRAME")) ); -// Gtk::Box* hb42 = Gtk::manage (new Gtk::Box ()); -// darkFrameDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + // Metadata + Gtk::Frame *mf = Gtk::manage(new Gtk::Frame(M("PREFERENCES_METADATA"))); + Gtk::Grid *mtbl = Gtk::manage(new Gtk::Grid()); + setExpandAlignProperties(mtbl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + metadataSyncCombo = Gtk::manage(new Gtk::ComboBoxText()); + metadataSyncCombo->set_active(0); + metadataSyncCombo->append(M("PREFERENCES_METADATA_SYNC_NONE")); + metadataSyncCombo->append(M("PREFERENCES_METADATA_SYNC_READ")); + metadataSyncCombo->append(M("PREFERENCES_METADATA_SYNC_READWRITE")); + Gtk::Label *mlbl = Gtk::manage(new Gtk::Label(M("PREFERENCES_METADATA_SYNC") + ": ")); + mtbl->attach(*mlbl, 0, 0, 1, 1); + mtbl->attach_next_to(*metadataSyncCombo, *mlbl, Gtk::POS_RIGHT, 1, 1); + setExpandAlignProperties(mlbl, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(metadataSyncCombo, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + xmpSidecarCombo = Gtk::manage(new Gtk::ComboBoxText()); + xmpSidecarCombo->set_active(0); + xmpSidecarCombo->append(M("PREFERENCES_XMP_SIDECAR_MODE_STD")); + xmpSidecarCombo->append(M("PREFERENCES_XMP_SIDECAR_MODE_EXT")); + + mlbl = Gtk::manage(new Gtk::Label(M("PREFERENCES_XMP_SIDECAR_MODE") + ": ")); + mtbl->attach(*mlbl, 0, 2, 1, 1); + mtbl->attach_next_to(*xmpSidecarCombo, *mlbl, Gtk::POS_RIGHT, 1, 1); + setExpandAlignProperties(mlbl, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(xmpSidecarCombo, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + mf->add(*mtbl); + vbImageProcessing->pack_start(*mf, Gtk::PACK_SHRINK, 4); + // Directories Gtk::Frame* cdf = Gtk::manage(new Gtk::Frame(M("PREFERENCES_DIRECTORIES"))); Gtk::Grid* dirgrid = Gtk::manage(new Gtk::Grid()); @@ -1104,7 +1131,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); @@ -1870,6 +1897,9 @@ void Preferences::storePreferences() moptions.cropGuides = Options::CropGuidesMode(cropGuidesCombo->get_active_row_number()); moptions.cropAutoFit = cropAutoFitCB->get_active(); + + 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()); } void Preferences::fillPreferences() @@ -2053,7 +2083,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); @@ -2120,6 +2150,9 @@ void Preferences::fillPreferences() txtSndLngEditProcDone->set_text(moptions.sndLngEditProcDone); spbSndLngEditProcDoneSecs->set_value(moptions.sndLngEditProcDoneSecs); #endif + + metadataSyncCombo->set_active(int(moptions.rtSettings.metadata_xmp_sync)); + xmpSidecarCombo->set_active(int(moptions.rtSettings.xmp_sidecar_style)); } /* diff --git a/rtgui/preferences.h b/rtgui/preferences.h index df4e3327a..86e81424d 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -223,6 +223,9 @@ class Preferences final : Gtk::ComboBoxText *cropGuidesCombo; Gtk::CheckButton *cropAutoFitCB; + Gtk::ComboBoxText *metadataSyncCombo; + Gtk::ComboBoxText *xmpSidecarCombo; + Glib::ustring storedValueRaw; Glib::ustring storedValueImg; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index e50d7ac77..31ca8bc1f 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -33,6 +33,7 @@ #include #include "../rtengine/dynamicprofile.h" +#include "../rtengine/metadata.h" #include "../rtengine/profilestore.h" #include "../rtengine/settings.h" #include "guiutils.h" @@ -1026,6 +1027,10 @@ void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) if (updateCacheImageData) { cfs.save (getCacheFileName ("data", ".txt")); } + + if (updatePParams && pparamsValid) { + saveMetadata(); + } } Thumbnail::~Thumbnail () @@ -1204,6 +1209,33 @@ void Thumbnail::getCamWB(double& temp, double& green) const } } +void Thumbnail::saveMetadata() +{ + if (options.rtSettings.metadata_xmp_sync != rtengine::Settings::MetadataXmpSync::READ_WRITE) { + return; + } + + if (pparams->exif.empty() && pparams->iptc.empty()) { + return; + } + + auto fn = rtengine::Exiv2Metadata::xmpSidecarPath(fname); + try { + auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname); + rtengine::Exiv2Metadata meta; + meta.xmpData() = std::move(xmp); + meta.setExif(pparams->exif); + meta.setIptc(pparams->iptc); + meta.saveToXmp(fn); + if (options.rtSettings.verbose) { + std::cout << "saved edited metadata for " << fname << " to " + << fn << std::endl; + } + } catch (Exiv2::AnyError &exc) { + std::cerr << "ERROR saving metadata for " << fname << " to " << fn + << ": " << exc.what() << std::endl; + } +} void Thumbnail::getSpotWB(int x, int y, int rect, double& temp, double& green) { if (tpp) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 93d1deb93..85701142d 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -88,6 +88,8 @@ class Thumbnail Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fext) const; + void saveMetadata(); + public: Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5); From a4b08016463546245724296fc22e00f29ee8b53f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 15 May 2019 05:57:14 -0700 Subject: [PATCH 076/326] fixed bugs in metadata saving (cherry picked from commit 880b1d3d865a7820051cf3023cc58802daca28b0) --- rtdata/languages/default | 84 ++++++++++++++++++++++------------------ rtengine/init.cc | 4 ++ rtengine/metadata.cc | 49 ++++++++++++++++------- rtengine/metadata.h | 3 ++ 4 files changed, 88 insertions(+), 52 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 595f03e7e..3f51e1d90 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1644,7 +1644,7 @@ PARTIALPASTE_LENSPROFILE;Profiled lens correction PARTIALPASTE_LOCALCONTRAST;Local contrast PARTIALPASTE_LOCALLAB;Local Adjustments PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings -PARTIALPASTE_LOCGROUP;Local +PARTIALPASTE_LOCGROUP;Local PARTIALPASTE_METADATA;Metadata mode PARTIALPASTE_METAGROUP;Metadata settings PARTIALPASTE_PCVIGNETTE;Vignette filter @@ -1789,6 +1789,11 @@ PREFERENCES_MENUGROUPLABEL;Group "Color label" PREFERENCES_MENUGROUPPROFILEOPERATIONS;Group "Processing profile operations" PREFERENCES_MENUGROUPRANK;Group "Rank" PREFERENCES_MENUOPTIONS;Context Menu Options +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 @@ -1864,6 +1869,9 @@ PREFERENCES_TP_LABEL;Tool panel: PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles PREFERENCES_WORKFLOW;Layout +PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style +PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) +PREFERENCES_XMP_SIDECAR_MODE_EXT;Darktable-like (FILENAME.ext.xmp for FILENAME.ext) PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling PROFILEPANEL_COPYPPASTE;Parameters to copy PROFILEPANEL_GLOBALPROFILES;Bundled profiles @@ -2057,7 +2065,7 @@ TP_COLORAPP_CHROMA_S;Saturation (S) TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02/16 corresponds to the color of a stimulus in relation to its own brightness, differs from L*a*b* and RGB saturation. TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02/16 corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions, differs from L*a*b* and RGB chroma. TP_COLORAPP_CIECAT_DEGREE;CAT02/16 adaptation -TP_COLORAPP_CONTRAST;Contrast (J) +TP_COLORAPP_CONTRAST;Contrast (J) TP_COLORAPP_CONTRAST_Q;Contrast (Q) TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM02/16 is based on brightness, differs from L*a*b* and RGB contrast. TP_COLORAPP_CONTRAST_TOOLTIP;Contrast (J) in CIECAM02/16 is based on lightness, differs from L*a*b* and RGB contrast. @@ -2104,7 +2112,7 @@ TP_COLORAPP_MOD16;CIECAM16 TP_COLORAPP_NEUTRAL;Reset TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values TP_COLORAPP_PRESETCAT02;Preset cat02/16 automatic - Symmetric mode -TP_COLORAPP_PRESETCAT02_TIP;Set combobox, sliders, temp, green so that Cat02/16 automatic is preset.\nYou can change illuminant shooting conditions.\nYou must change Cat02/16 adaptation Viewing conditions if needed.\nYou can change Temperature and Tint Viewing conditions if needed, and other settings if needed.\nAll auto checkbox are disabled +TP_COLORAPP_PRESETCAT02_TIP;Set combobox, sliders, temp, green so that Cat02/16 automatic is preset.\nYou can change illuminant shooting conditions.\nYou must change Cat02/16 adaptation Viewing conditions if needed.\nYou can change Temperature and Tint Viewing conditions if needed, and other settings if needed.\nAll auto checkbox are disabled TP_COLORAPP_RSTPRO;Red & skin-tones protection TP_COLORAPP_RSTPRO_TOOLTIP;Red & skin-tones protection affects both sliders and curves. 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. @@ -2522,13 +2530,13 @@ 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_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_BLURRESIDFRA;Blur Residual 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_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 @@ -2553,11 +2561,11 @@ 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_CHRRT;Chroma 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_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_CIRCRADIUS;Spot size TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the RT-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_CLARIFRA;Clarity & Sharp mask/Blend & Soften Images TP_LOCALLAB_CLARILRES;Merge luma TP_LOCALLAB_CLARISOFT;Soft radius TP_LOCALLAB_CLARISOFT_TOOLTIP;The ‘Soft radius’ slider (guided filter algorithm) reduces halos and irregularities for both Clarity and Sharp Mask and for all pyramid wavelet processes. To deactivate, set slider to zero. @@ -2589,7 +2597,7 @@ 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_CSTHRESHOLD;Wavelet levels TP_LOCALLAB_CSTHRESHOLDBLUR;Wavelet level selection TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance "Super" TP_LOCALLAB_CURVCURR;Normal @@ -2613,19 +2621,19 @@ TP_LOCALLAB_DELTAD;Delta balance TP_LOCALLAB_DELTAEC;ΔE Image 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_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_DENOI1_EXP;Denoise based on luminance mask TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). +TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). 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_DENOIS;Denoise -TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. +TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. 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 (deltaE). -TP_LOCALLAB_DEPTH;Depth +TP_LOCALLAB_DEPTH;Depth TP_LOCALLAB_DETAIL;Local contrast TP_LOCALLAB_DETAILFRA;Edge detection - DCT TP_LOCALLAB_DETAILSH;Details @@ -2663,12 +2671,12 @@ TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with ‘Exposure compensation f 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 Locallab version: more tools and more possibilities for working on individual detail levels.\ne.g. Wavelet-level tone mapping. +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 Locallab version: 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 RT-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 @@ -2711,10 +2719,10 @@ 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_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_GRADSTRCHRO;Chroma gradient strength TP_LOCALLAB_GRADSTRHUE;Hue gradient strength TP_LOCALLAB_GRADSTRHUE2;Hue gradient strength TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength @@ -2758,7 +2766,7 @@ 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_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_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 @@ -2804,9 +2812,9 @@ 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.\nTakes into account exposure compensation in the main-menu Exposure tab.\nAlso calculates the absolute luminance at the time of shooting. TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables (mainly Contrast 'J' and Saturation 's', and also Contrast (Q) , Brightness (Q), Lightness (J), 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_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_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;Strength @@ -2877,16 +2885,16 @@ TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Dark-tone limit below which the Retinex (Lu 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_MASKLCTHRMID;Gray area luma denoise -TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise +TP_LOCALLAB_MASKLCTHRMID;Gray area luma denoise +TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) TP_LOCALLAB_MASKRECOTHRES;Recovery threshold -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 RT-spot and place it close to the first spot. The small variations in the spot references allows you to make fine adjustments. +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 RT-spot and place it close to the first spot. The small variations in the spot references allows you to make fine adjustments. TP_LOCALLAB_MED;Medium 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_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) @@ -2935,7 +2943,7 @@ TP_LOCALLAB_MRFOU;Previous Spot TP_LOCALLAB_MRONE;None TP_LOCALLAB_MRTHR;Original Image TP_LOCALLAB_MRTWO;Short Curves 'L' Mask -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_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_NLDENOISE_TOOLTIP;“Detail recovery” acts on a Laplacian transform to target uniform areas rather than areas with detail. TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. @@ -3009,10 +3017,10 @@ TP_LOCALLAB_RETIM;Original Retinex TP_LOCALLAB_RETITOOLFRA;Retinex Tools TP_LOCALLAB_RETI_FFTW_TOOLTIP;FFT improve quality and allow big radius, but increases the treatment time.\nThe treatment time depends on the surface to be treated\nThe treatment time depends on the value of scale (be carefull to high values).\nTo be used preferably for large radius.\n\nDimensions can be reduced by a few pixels to optimize FFTW.\nThis optimization can reduce the treatment time by a factor of 1.5 to 10.\nOptimization not used in Preview 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_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_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 @@ -3097,14 +3105,14 @@ 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_SOFTRETI;Reduce ΔE artifacts TP_LOCALLAB_SOFTRETI_TOOLTIP;Take into account deltaE to improve Transmission map 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_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 @@ -3119,7 +3127,7 @@ TP_LOCALLAB_STRRETI_TOOLTIP;if Strength Retinex < 0.2 only Dehaze is enabled.\ni 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_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! @@ -3129,7 +3137,7 @@ TP_LOCALLAB_SYM;Symmetrical (mouse) TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) TP_LOCALLAB_TARGET_GRAY;Mean luminance (Yb%) TP_LOCALLAB_THRES;Threshold structure -TP_LOCALLAB_THRESDELTAE;ΔE scope threshold +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 @@ -3154,7 +3162,7 @@ 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_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 @@ -3186,13 +3194,13 @@ TP_LOCALLAB_WAT_SIGMALC_TOOLTIP;The effect of the local contrast adjustment is s 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_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_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 @@ -3453,7 +3461,7 @@ 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;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 @@ -3777,11 +3785,11 @@ 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_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_THRESHOLD_TOOLTIP;Only levels below and including the chosen value will be affected by the Highlight luminance range. TP_WAVELET_THRESWAV;Balance threshold TP_WAVELET_THRH;Highlights threshold TP_WAVELET_TILESBIG;Tiles @@ -3863,7 +3871,7 @@ ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: f ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: Alt-f ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - -//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.\nOnly the third Ciecam process (Viewing conditions - Target) is taken into account, as well as part of the second (contrast J, saturation s) , as well as some data from the first process (Scene conditions - Source) which is used for the Log encoding.\nIt also 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_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.\nOnly the third Ciecam process (Viewing conditions - Target) is taken into account, as well as part of the second (contrast J, saturation s) , as well as some data from the first process (Scene conditions - Source) which is used for the Log encoding.\nIt also 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_WAVELET_DENH;Low levels (1234)- Finest details //TP_WAVELET_DENL;High levels - Coarsest details //TP_WAVELET_DENLH;Guided threshold for detail levels 1-4 diff --git a/rtengine/init.cc b/rtengine/init.cc index 1a00f7ff6..a73118e46 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -33,6 +33,7 @@ #include "profilestore.h" #include "../rtgui/threadutils.h" #include "rtlensfun.h" +#include "metadata.h" #include "procparams.h" namespace rtengine @@ -103,6 +104,8 @@ int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& } Color::init (); + Exiv2Metadata::init(); + delete lcmsMutex; lcmsMutex = new MyMutex; fftwMutex = new MyMutex; @@ -111,6 +114,7 @@ int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& void cleanup () { + Exiv2Metadata::cleanup(); ProcParams::cleanup (); Color::cleanup (); RawImageSource::cleanup (); diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 15ab7db44..35ffb8ad5 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -20,6 +20,8 @@ #include #include +#include + #include "metadata.h" #include "settings.h" #include "../rtgui/version.h" @@ -65,7 +67,7 @@ Exiv2Metadata::Exiv2Metadata(): Exiv2Metadata::Exiv2Metadata(const Glib::ustring &path): - src_(""), + src_(path), merge_xmp_(settings->metadata_xmp_sync != Settings::MetadataXmpSync::NONE), image_(nullptr), exif_(new rtengine::procparams::ExifPairs), @@ -154,20 +156,27 @@ void Exiv2Metadata::setIptc(const rtengine::procparams::IPTCPairs &iptc) void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const { - auto xmp = getXmpSidecar(src_); - Exiv2::ExifData exif; - Exiv2::IptcData iptc; - Exiv2::moveXmpToExif(xmp, exif); - Exiv2::moveXmpToIptc(xmp, iptc); + try { + auto xmp = getXmpSidecar(src_); + Exiv2::ExifData exif; + Exiv2::IptcData iptc; + Exiv2::moveXmpToIptc(xmp, iptc); + Exiv2::moveXmpToExif(xmp, exif); - for (auto &datum : exif) { - dst->exifData()[datum.key()] = datum; - } - for (auto &datum : iptc) { - dst->iptcData()[datum.key()] = datum; - } - for (auto &datum : xmp) { - dst->xmpData()[datum.key()] = datum; + for (auto &datum : exif) { + dst->exifData()[datum.key()] = datum; + } + for (auto &datum : iptc) { + dst->iptcData()[datum.key()] = datum; + } + for (auto &datum : xmp) { + dst->xmpData()[datum.key()] = datum; + } + } catch (Exiv2::AnyError &exc) { + if (settings->verbose) { + std::cerr << "Error loading metadata from XMP sidecar: " + << exc.what() << std::endl; + } } } @@ -288,4 +297,16 @@ Exiv2::XmpData Exiv2Metadata::getXmpSidecar(const Glib::ustring &path) return ret; } + +void Exiv2Metadata::init() +{ + Exiv2::XmpParser::initialize(); +} + + +void Exiv2Metadata::cleanup() +{ + Exiv2::XmpParser::terminate(); +} + } // namespace rtengine diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 8de384479..2b7851dd4 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -56,6 +56,9 @@ public: static Glib::ustring xmpSidecarPath(const Glib::ustring& path); static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path); + + static void init(); + static void cleanup(); private: void do_merge_xmp(Exiv2::Image* dst) const; From 2d412d74047922707ac7a34eded5b2a08b044892 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 19 May 2019 22:55:28 +0200 Subject: [PATCH 077/326] metadata: do not copy exif rotate info from the original image -- it might just be plain wrong (cherry picked from commit 8f14684588b3c0aec1aab37f4225c99954f6f587) --- rtengine/metadata.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 35ffb8ad5..7e3bdbf05 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -187,6 +187,11 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const dst->readMetadata(); if (image_.get()) { dst->setMetadata(*image_); + auto it = + dst->exifData().findKey(Exiv2::ExifKey("Exif.Image.Orientation")); + if (it != dst->exifData().end()) { + dst->exifData().erase(it); + } if (merge_xmp_) { do_merge_xmp(dst.get()); } From 77d7e633e5a221d340928b33360acf96d35a8d06 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 19 May 2019 14:42:52 -0700 Subject: [PATCH 078/326] metadata: erase also jpeg thumbnail (cherry picked from commit 88661755506cd48393e69e809cf0559572cb213d) --- rtengine/metadata.cc | 23 ++++++++++++++++++----- rtengine/metadata.h | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 7e3bdbf05..c5049229d 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -187,11 +187,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const dst->readMetadata(); if (image_.get()) { dst->setMetadata(*image_); - auto it = - dst->exifData().findKey(Exiv2::ExifKey("Exif.Image.Orientation")); - if (it != dst->exifData().end()) { - dst->exifData().erase(it); - } + remove_unwanted(dst.get()); if (merge_xmp_) { do_merge_xmp(dst.get()); } @@ -208,6 +204,23 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const } +void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const +{ + static const std::vector keys = { + "Exif.Image.Orientation", + "Exif.Photo.MakerNote" + }; + for (auto &k : keys) { + auto it = dst->exifData().findKey(Exiv2::ExifKey(k)); + if (it != dst->exifData().end()) { + dst->exifData().erase(it); + } + } + Exiv2::ExifThumb thumb(dst->exifData()); + thumb.erase(); +} + + void Exiv2Metadata::import_exif_pairs(Exiv2::ExifData &out) const { for (auto &p : *exif_) { diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 2b7851dd4..5f19fa5a1 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -64,6 +64,7 @@ private: void do_merge_xmp(Exiv2::Image* dst) const; void import_exif_pairs(Exiv2::ExifData& out) const; void import_iptc_pairs(Exiv2::IptcData& out) const; + void remove_unwanted(Exiv2::Image* dst) const; Glib::ustring src_; bool merge_xmp_; From 38d87bae72313a4c24b389ed383bb947a794dc04 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 20 May 2019 09:20:02 +0200 Subject: [PATCH 079/326] metadata: keep makernotes (cherry picked from commit 494ae069d4f9d985b65375e104513f9c85453d5b) --- rtengine/metadata.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index c5049229d..6006f5abe 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -207,8 +207,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const { static const std::vector keys = { - "Exif.Image.Orientation", - "Exif.Photo.MakerNote" + "Exif.Image.Orientation" }; for (auto &k : keys) { auto it = dst->exifData().findKey(Exiv2::ExifKey(k)); From b01b0fbef08f04b5769f57148a0ac7abdec94793 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 20 May 2019 01:56:38 -0700 Subject: [PATCH 080/326] metadata: initialize thumbnail rating from exif (cherry picked from commit 96bd2db0d2e127678bded3bee7aa3275332826c0) --- rtengine/imagedata.cc | 16 ++++++++++------ rtengine/imagedata.h | 2 +- rtengine/rtengine.h | 5 +++-- rtgui/thumbnail.cc | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index e7cf2b4c2..df043c86f 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -287,6 +287,10 @@ FramesData::FramesData(const Glib::ustring &fname) : expcomp = pos->toFloat(); } + if (find_exif_tag("Exif.Image.Rating")) { + rating = pos->toLong(); + } + // ----------------------- // Special file type detection (HDR, PixelShift) // ------------------------ @@ -567,12 +571,6 @@ std::string FramesData::getOrientation() const } -int FramesData::getRating() const -{ - return rating; -} - - void FramesData::setDCRawFrameCount(unsigned int frameCount) { dcrawFrameCount = frameCount; @@ -589,6 +587,12 @@ Glib::ustring FramesData::getFileName() const return fname_; } + +int FramesData::getRating() const +{ + return rating; +} + //------inherited functions--------------// std::string FramesMetaData::apertureToString(double aperture) diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index b1a29dc39..306c3b6f9 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -81,8 +81,8 @@ public: std::string getLens() const override; std::string getSerialNumber() const; std::string getOrientation() const override; - int getRating() const override; Glib::ustring getFileName() const override; + int getRating() const override; }; } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ceb27a504..91ef0a436 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -1,4 +1,5 @@ -/* +/* -*- C++ -*- + * * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath @@ -122,7 +123,7 @@ public: /** @return the orientation of the image */ virtual std::string getOrientation() const = 0; /** @return the rating of the image */ - virtual int getRating () const = 0; + virtual int getRating() const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ virtual bool getPixelShift () const = 0; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 31ca8bc1f..32f80a193 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -387,7 +387,7 @@ void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt) * The result is a complete ProcParams with default values merged with the values * from the loaded ProcParams (sidecar or cache file). */ -void Thumbnail::loadProcParams () +void Thumbnail::loadProcParams() { MyMutex::MyLock lock(mutex); From 0e019b745b730f66f71e4f5f2a62d470d3dd4d5e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 7 Jul 2019 18:00:24 +0200 Subject: [PATCH 081/326] metadata: translate "----" to "Unknown" in lens identification (cherry picked from commit 9b0dce535c7eeda2d20c0ef1fa342b00238a48a1) --- rtengine/imagedata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index df043c86f..c1a5b898d 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -265,7 +265,7 @@ FramesData::FramesData(const Glib::ustring &fname) : if (lens.empty()) { lens = "Unknown"; } - if (lens.empty()) { + if (lens.empty() || lens.find_first_not_of('-') == std::string::npos) { lens = "Unknown"; } From 45acb120a6278cdc0c8731ed763018ebdee8b79d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 26 Jul 2019 08:31:08 -0700 Subject: [PATCH 082/326] improved lens info for fixed-lens cameras (cherry picked from commit a1bcb1a2a65514ae1c8e0bcd3489f83f7a68ead5) --- rtengine/imagedata.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index c1a5b898d..915f723a3 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -261,9 +261,26 @@ FramesData::FramesData(const Glib::ustring &fname) : if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? - } - if (lens.empty()) { - lens = "Unknown"; + } else if (find_exif_tag("Exif.Photo.LensSpecification") && pos->count() == 4) { + const auto round = + [](float f) -> float + { + return int(f * 10.f + 0.5f) / 10.f; + }; + float fl_lo = round(pos->toFloat(0)); + float fl_hi = round(pos->toFloat(1)); + float fn_lo = round(pos->toFloat(2)); + float fn_hi = round(pos->toFloat(3)); + std::ostringstream buf; + buf << fl_lo; + if (fl_lo < fl_hi) { + buf << "-" << fl_hi; + } + buf << "mm F" << fn_lo; + if (fn_lo < fn_hi) { + buf << "-" << fn_hi; + } + lens = buf.str(); } if (lens.empty() || lens.find_first_not_of('-') == std::string::npos) { lens = "Unknown"; From e5c8ceac5f1d8b58d4cbd6292a898759e24cd1b1 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 27 Aug 2019 05:47:15 -0700 Subject: [PATCH 083/326] metadata: fixed detection of Pentax DNG pixelshift images (cherry picked from commit 2bdd3a6c5d79dc61fca39ea39ecd90ba9a12dee5) --- rtengine/imagedata.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 915f723a3..2434fc42b 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -338,7 +338,10 @@ FramesData::FramesData(const Glib::ustring &fname) : if ( !isHDR - && find_exif_tag("Exif.Pentax.Quality") + && ( + find_exif_tag("Exif.Pentax.Quality") + || find_exif_tag("Exif.PentaxDng.Quality") + ) && ( pos->toLong() == 7 || pos->toLong() == 8 From df39e13cf7f50654f8aa9f19d2d6d8efcce46fdf Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 16 Sep 2019 01:30:52 -0700 Subject: [PATCH 084/326] properly handle exif orientation translate the tag value to string using the exiftool way, to be compatible with RT. Fixes issue #4 (cherry picked from commit a4621f54b2ac82b679cf9d865a0a3e4a2ed9c468) --- rtengine/imagedata.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 2434fc42b..3b61d2baa 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -256,7 +256,23 @@ FramesData::FramesData(const Glib::ustring &fname) : } if (find_tag(Exiv2::orientation)) { - orientation = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + static const std::vector ormap = { + "Unknown", + "Horizontal (normal)", + "Mirror horizontal", + "Rotate 180", + "Mirror vertical", + "Mirror horizontal and rotate 270 CW", + "Rotate 90 CW", + "Mirror horizontal and rotate 90 CW", + "Rotate 270 CW", + "Unknown" + }; + auto idx = pos->toLong(); + if (idx >= 0 && idx < long(ormap.size())) { + orientation = ormap[idx]; + } + //orientation = pos->print(&exif); } if (find_tag(Exiv2::lensName)) { From 7c39f35317f275a50b763f56eb88e662a72e94df Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 18 Sep 2019 11:58:01 +0200 Subject: [PATCH 085/326] metadata: removed some harmful tags from the exported images (cherry picked from commit 94c3e87113384f4c20b10f467a1c35e90709d161) --- rtengine/metadata.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 6006f5abe..c8aa3061d 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -207,7 +207,9 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const { static const std::vector keys = { - "Exif.Image.Orientation" + "Exif.Image.Orientation", + "Exif.Image2.JPEGInterchangeFormat", + "Exif.Image2.JPEGInterchangeFormatLength" }; for (auto &k : keys) { auto it = dst->exifData().findKey(Exiv2::ExifKey(k)); From 25d67c12c1c39235f5b4cb78e9c4c7c35a214c9e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 4 Nov 2019 09:14:53 +0100 Subject: [PATCH 086/326] metadata: remove unwanted tags *after* merging XMP sidecars, not before (cherry picked from commit b45666f61ac9c6083bdc22811351d72bf35497bb) --- rtengine/metadata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index c8aa3061d..bfcb3080e 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -187,10 +187,10 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const dst->readMetadata(); if (image_.get()) { dst->setMetadata(*image_); - remove_unwanted(dst.get()); if (merge_xmp_) { do_merge_xmp(dst.get()); } + remove_unwanted(dst.get()); } else { dst->setExifData(exif_data_); dst->setIptcData(iptc_data_); From e3f3b8ae91bb306b07c8aec7b6308a87ad7239c6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 18 Nov 2019 08:02:46 -0800 Subject: [PATCH 087/326] Get date taken from time digitized Used as the fallback if the original data-time isn't available. Original commit message: metadata: use exiftool as a fallback for files not yet supported by exiv2 (e.g cr3) (cherry picked from commit bdcebdecef8cca82b0d8ad7a24d267308b12e04d) --- rtengine/imagedata.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 3b61d2baa..368f46bf8 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -309,6 +309,9 @@ FramesData::FramesData(const Glib::ustring &fname) : else if (find_exif_tag("Exif.Photo.DateTimeOriginal")) { datetime_taken = pos->print(&exif); } + else if (find_exif_tag("Exif.Photo.DateTimeDigitized")) { + datetime_taken = pos->print(&exif); + } if (sscanf(datetime_taken.c_str(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { time.tm_year -= 1900; time.tm_mon -= 1; From e7fdad875a568a93d8f7438c875d42d77748462b Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 9 Dec 2019 04:27:13 -0800 Subject: [PATCH 088/326] metadata: cache recent files for faster operation (cherry picked from commit 6ee014ddb7ab77537289e1f41f13345e5db54710) --- rtengine/metadata.cc | 22 ++++++++++++++++++---- rtengine/metadata.h | 10 +++++----- rtgui/procparamchangers.h | 15 ++++++++------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index bfcb3080e..70e8b785a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "metadata.h" #include "settings.h" @@ -32,9 +33,12 @@ namespace rtengine { extern const Settings *settings; +std::unique_ptr Exiv2Metadata::cache_(nullptr); namespace { +constexpr size_t IMAGE_CACHE_SIZE = 200; + Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) { #ifdef EXV_UNICODE_PATH @@ -88,10 +92,19 @@ Exiv2Metadata::Exiv2Metadata(const Glib::ustring &path, bool merge_xmp_sidecar): void Exiv2Metadata::load() const { - if (!src_.empty() && !image_.get()) { - auto img = open_exiv2(src_); - image_.reset(img.release()); - image_->readMetadata(); + if (!src_.empty() && !image_.get() && Glib::file_test(src_.c_str(), Glib::FILE_TEST_EXISTS)) { + CacheVal val; + auto finfo = Gio::File::create_for_path(src_)->query_info(G_FILE_ATTRIBUTE_TIME_MODIFIED); + if (cache_ && cache_->get(src_, val) && val.second >= finfo->modification_time()) { + image_ = val.first; + } else { + auto img = open_exiv2(src_); + image_.reset(img.release()); + image_->readMetadata(); + if (cache_) { + cache_->set(src_, CacheVal(image_, finfo->modification_time())); + } + } if (merge_xmp_) { do_merge_xmp(image_.get()); @@ -319,6 +332,7 @@ Exiv2::XmpData Exiv2Metadata::getXmpSidecar(const Glib::ustring &path) void Exiv2Metadata::init() { + cache_.reset(new ImageCache(IMAGE_CACHE_SIZE)); Exiv2::XmpParser::initialize(); } diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 5f19fa5a1..57904d4a4 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -24,6 +24,7 @@ #include #include #include "procparams.h" +#include "cache.h" namespace rtengine { @@ -74,11 +75,10 @@ private: Exiv2::ExifData exif_data_; Exiv2::IptcData iptc_data_; Exiv2::XmpData xmp_data_; + + typedef std::pair, Glib::TimeVal> CacheVal; + typedef Cache ImageCache; + static std::unique_ptr cache_; }; -// Glib::ustring get_xmp_sidecar_path(const Glib::ustring &path); -// Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring &fname, -// bool merge_xmp_sidecar); -// Exiv2::XmpData read_exiv2_xmp(const Glib::ustring &fname); - } // namespace rtengine diff --git a/rtgui/procparamchangers.h b/rtgui/procparamchangers.h index 8dd3769c6..0ca76a0eb 100644 --- a/rtgui/procparamchangers.h +++ b/rtgui/procparamchangers.h @@ -1,4 +1,5 @@ -/* +/* -*- C++ -*- + * * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath @@ -16,9 +17,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#define UNKNOWN -1 -#define FILEBROWSER 1 -#define EDITOR 2 -#define BATCHEDITOR 3 -#define CACHEMGR 4 -#define SAFETYUPDATE 5 +constexpr int UNKNOWN = -1; +constexpr int FILEBROWSER = 1; +constexpr int EDITOR = 2; +constexpr int BATCHEDITOR = 3; +constexpr int CACHEMGR = 4; +constexpr int SAFETYUPDATE = 5; From e90ffe979b2d8d41e6d88788f514e8c5cf6a3dc5 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 4 Jan 2020 07:13:24 -0800 Subject: [PATCH 089/326] metadata: catch std::exception instead of Exiv2::AnyError for better robustness (cherry picked from commit 0e2d9332f633b060bd4d5cbcd9d47009bab0c46c) --- rtengine/imagedata.cc | 2 +- rtengine/imageio.cc | 2 +- rtengine/metadata.cc | 6 +++--- rtgui/exifpanel.cc | 4 ++-- rtgui/iptcpanel.cc | 2 +- rtgui/thumbnail.cc | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 368f46bf8..a810bc925 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -499,7 +499,7 @@ FramesData::FramesData(const Glib::ustring &fname) : #endif } } - } catch (const Exiv2::AnyError& e) { + } catch (const std::exception& e) { if (settings->verbose) { std::cerr << "EXIV2 ERROR: " << e.what() << std::endl; } diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 475792e83..b0510e817 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1385,7 +1385,7 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const // } // dst->writeMetadata(); return true; - } catch (const Exiv2::AnyError& exc) { + } catch (const std::exception& exc) { std::cout << "EXIF ERROR: " << exc.what() << std::endl; return false; } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 70e8b785a..ecf4c444f 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -185,7 +185,7 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const for (auto &datum : xmp) { dst->xmpData()[datum.key()] = datum; } - } catch (Exiv2::AnyError &exc) { + } catch (std::exception &exc) { if (settings->verbose) { std::cerr << "Error loading metadata from XMP sidecar: " << exc.what() << std::endl; @@ -240,7 +240,7 @@ void Exiv2Metadata::import_exif_pairs(Exiv2::ExifData &out) const for (auto &p : *exif_) { try { out[p.first] = p.second; - } catch (Exiv2::AnyError &exc) {} + } catch (std::exception &exc) {} } } @@ -258,7 +258,7 @@ void Exiv2Metadata::import_iptc_pairs(Exiv2::IptcData &out) const out.add(d); } } - } catch (Exiv2::AnyError &exc) {} + } catch (std::exception &exc) {} } } diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 7438240e9..5cc4af341 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -233,7 +233,7 @@ void ExifPanel::refreshTags() for (const auto& p : *changeList) { try { exif[p.first] = p.second; - } catch (const Exiv2::AnyError& exc) { + } catch (const std::exception& exc) { } } @@ -258,7 +258,7 @@ void ExifPanel::refreshTags() addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); } } - } catch (const Exiv2::AnyError& exc) { + } catch (const std::exception& exc) { return; } diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 724b54aa1..f476e7513 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -502,7 +502,7 @@ void IPTCPanel::setImageData (const FramesMetaData* id) (*embeddedData)[tag.key()].push_back(tag.toString()); } } - } catch (const Exiv2::AnyError& exc) { + } catch (const std::exception& exc) { embeddedData->clear(); } } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 32f80a193..ce5138d28 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -1231,7 +1231,7 @@ void Thumbnail::saveMetadata() std::cout << "saved edited metadata for " << fname << " to " << fn << std::endl; } - } catch (Exiv2::AnyError &exc) { + } catch (std::exception &exc) { std::cerr << "ERROR saving metadata for " << fname << " to " << fn << ": " << exc.what() << std::endl; } From 200779aa8489d675801c372bdfbb2e9e6d0324a4 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 5 Jan 2020 09:26:29 -0800 Subject: [PATCH 090/326] metadata: better error handling (cherry picked from commit 0e26c15a730854883ae31d164b460d70393c2848) --- rtengine/metadata.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index ecf4c444f..3e5ac9a1e 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -54,6 +54,10 @@ Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) #else auto image = Exiv2::ImageFactory::open(Glib::filename_from_utf8(fname)); #endif + image->readMetadata(); + if (!image->good()) { + throw Exiv2::Error(Exiv2::kerErrorMessage, "exiv2: invalid image"); + } return image; } @@ -100,7 +104,6 @@ void Exiv2Metadata::load() const } else { auto img = open_exiv2(src_); image_.reset(img.release()); - image_->readMetadata(); if (cache_) { cache_->set(src_, CacheVal(image_, finfo->modification_time())); } @@ -197,7 +200,6 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const void Exiv2Metadata::saveToImage(const Glib::ustring &path) const { auto dst = open_exiv2(path); - dst->readMetadata(); if (image_.get()) { dst->setMetadata(*image_); if (merge_xmp_) { @@ -323,7 +325,6 @@ Exiv2::XmpData Exiv2Metadata::getXmpSidecar(const Glib::ustring &path) auto fname = xmpSidecarPath(path); if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { auto image = open_exiv2(fname); - image->readMetadata(); ret = image->xmpData(); } return ret; From e205ff86cc65930c750f5b1bf26470955d170d84 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 5 Feb 2020 11:52:42 +0100 Subject: [PATCH 091/326] fixed compilation problem with exiv2 < 0.27 (cherry picked from commit b4d178fdab61814be8ab93f0ecd7d74f78c4087f) --- rtengine/metadata.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 3e5ac9a1e..40cdffdb1 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -56,7 +56,12 @@ Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) #endif image->readMetadata(); if (!image->good()) { - throw Exiv2::Error(Exiv2::kerErrorMessage, "exiv2: invalid image"); +#if EXIV2_TEST_VERSION(0,27,0) + auto error_code = Exiv2::kerErrorMessage; +#else + auto error_code = 1; +#endif + throw Exiv2::Error(error_code, "exiv2: invalid image"); } return image; } From ea3cf2fe8fc7f8bed057860a48c47064071bb64d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 10 Mar 2020 08:16:39 -0700 Subject: [PATCH 092/326] imageio: do not fail in saving an image if no metadata is available (cherry picked from commit 86d48be88b6f9fe36e5e25185ec4fda7696efc25) --- rtengine/imageio.cc | 75 +++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index b0510e817..af945949f 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -41,6 +41,7 @@ #include "iccjpeg.h" #include "color.h" #include "imagedata.h" +#include "settings.h" #include "jpeg.h" @@ -48,6 +49,8 @@ using namespace std; using namespace rtengine; using namespace rtengine::procparams; +namespace rtengine { extern const Settings *settings; } + namespace { @@ -1355,38 +1358,50 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const return true; } + bool has_meta = true; try { metadataInfo.load(); - metadataInfo.saveToImage(fname); - // auto src = open_exiv2(metadataInfo.filename()); - // auto dst = open_exiv2(fname); - // src->readMetadata(); - // dst->setMetadata(*src); - // dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; - // for (const auto& p : metadataInfo.exif()) { - // try { - // dst->exifData()[p.first] = p.second; - // } catch (const Exiv2::AnyError& exc) { - // } - // } - // for (const auto& p : metadataInfo.iptc()) { - // try { - // auto& v = p.second; - // if (!v.empty()) { - // dst->iptcData()[p.first] = v[0]; - // for (size_t j = 1; j < v.size(); ++j) { - // Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); - // d.setValue(v[j]); - // dst->iptcData().add(d); - // } - // } - // } catch (const Exiv2::AnyError& exc) { - // } - // } - // dst->writeMetadata(); - return true; } catch (const std::exception& exc) { - std::cout << "EXIF ERROR: " << exc.what() << std::endl; - return false; + if (settings->verbose) { + std::cout << "EXIF LOAD ERROR: " << exc.what() << std::endl; + } + has_meta = false; } + + if (has_meta) { + try { + metadataInfo.saveToImage(fname); + // auto src = open_exiv2(metadataInfo.filename()); + // auto dst = open_exiv2(fname); + // src->readMetadata(); + // dst->setMetadata(*src); + // dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; + // for (const auto& p : metadataInfo.exif()) { + // try { + // dst->exifData()[p.first] = p.second; + // } catch (const Exiv2::AnyError& exc) { + // } + // } + // for (const auto& p : metadataInfo.iptc()) { + // try { + // auto& v = p.second; + // if (!v.empty()) { + // dst->iptcData()[p.first] = v[0]; + // for (size_t j = 1; j < v.size(); ++j) { + // Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); + // d.setValue(v[j]); + // dst->iptcData().add(d); + // } + // } + // } catch (const Exiv2::AnyError& exc) { + // } + // } + // dst->writeMetadata(); + } catch (const std::exception& exc) { + std::cout << "EXIF ERROR: " << exc.what() << std::endl; + return false; + } + } + + return true; } From dcc00b40d15974fe8d4b3e1041b0d1d541b5091b Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 14 Mar 2020 21:02:20 +0100 Subject: [PATCH 093/326] metadata: do not include makernotes on export Fixes #31 (cherry picked from commit 3a8d8ece897eb4df61887160a30722bd07a77174) --- rtengine/metadata.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 40cdffdb1..e4d955738 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -229,7 +229,8 @@ void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const static const std::vector keys = { "Exif.Image.Orientation", "Exif.Image2.JPEGInterchangeFormat", - "Exif.Image2.JPEGInterchangeFormatLength" + "Exif.Image2.JPEGInterchangeFormatLength", + "Exif.Photo.MakerNote" }; for (auto &k : keys) { auto it = dst->exifData().findKey(Exiv2::ExifKey(k)); @@ -237,6 +238,26 @@ void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const dst->exifData().erase(it); } } + static const std::vector patterns = { + "Exif.Image.", + "Exif.Photo.", + "Exif.GPSInfo." + }; + for (auto it = dst->exifData().begin(); it != dst->exifData().end(); ) { + bool found = false; + for (auto &pp : patterns) { + if (it->key().find(pp) == 0) { + found = true; + break; + } + } + if (!found) { + it = dst->exifData().erase(it); + } else { + ++it; + } + } + Exiv2::ExifThumb thumb(dst->exifData()); thumb.erase(); } From c1719fbd7d1bb805ea7759b216bae6dfde7a9d7f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 5 Apr 2020 05:04:45 -0700 Subject: [PATCH 094/326] metadata: better handling of makernote tags Tentative fix for #37 (cherry picked from commit 7310eb64978bb1138edbdf02fa58fb64a9326e17) --- rtengine/metadata.cc | 66 +++++++++++++++++++------------------------- rtengine/metadata.h | 2 +- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index e4d955738..dbc1e178a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -37,6 +37,17 @@ std::unique_ptr Exiv2Metadata::cache_(nullptr); namespace { +class Error: public Exiv2::AnyError { +public: + Error(const std::string &msg): msg_(msg) {} + const char *what() const throw() { return msg_.c_str(); } + int code() const throw() { return 0; } + +private: + std::string msg_; +}; + + constexpr size_t IMAGE_CACHE_SIZE = 200; Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) @@ -206,11 +217,14 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const { auto dst = open_exiv2(path); if (image_.get()) { - dst->setMetadata(*image_); + dst->setIptcData(image_->iptcData()); + dst->setXmpData(image_->xmpData()); if (merge_xmp_) { do_merge_xmp(dst.get()); } - remove_unwanted(dst.get()); + auto srcexif = image_->exifData(); + remove_unwanted(srcexif); + dst->setExifData(srcexif); } else { dst->setExifData(exif_data_); dst->setIptcData(iptc_data_); @@ -224,42 +238,29 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const } -void Exiv2Metadata::remove_unwanted(Exiv2::Image *dst) const -{ - static const std::vector keys = { - "Exif.Image.Orientation", - "Exif.Image2.JPEGInterchangeFormat", - "Exif.Image2.JPEGInterchangeFormatLength", - "Exif.Photo.MakerNote" - }; - for (auto &k : keys) { - auto it = dst->exifData().findKey(Exiv2::ExifKey(k)); - if (it != dst->exifData().end()) { - dst->exifData().erase(it); - } - } - static const std::vector patterns = { +void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const +{ + Exiv2::ExifThumb thumb(dst); + thumb.erase(); + + static const std::vector badpatterns = { "Exif.Image.", - "Exif.Photo.", - "Exif.GPSInfo." + "Exif.SubImage" }; - for (auto it = dst->exifData().begin(); it != dst->exifData().end(); ) { + + for (auto it = dst.begin(); it != dst.end(); ) { bool found = false; - for (auto &pp : patterns) { - if (it->key().find(pp) == 0) { + for (auto &p : badpatterns) { + if (it->key().find(p) == 0) { + it = dst.erase(it); found = true; break; } } if (!found) { - it = dst->exifData().erase(it); - } else { ++it; } - } - - Exiv2::ExifThumb thumb(dst->exifData()); - thumb.erase(); + } } @@ -320,15 +321,6 @@ void Exiv2Metadata::saveToXmp(const Glib::ustring &path) const } } - class Error: public Exiv2::AnyError { - public: - Error(const std::string &msg): msg_(msg) {} - const char *what() const throw() { return msg_.c_str(); } - int code() const throw() { return 0; } - - private: - std::string msg_; - }; if (err) { throw Error("error saving XMP sidecar " + path); } diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 57904d4a4..7439d6b36 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -65,7 +65,7 @@ private: void do_merge_xmp(Exiv2::Image* dst) const; void import_exif_pairs(Exiv2::ExifData& out) const; void import_iptc_pairs(Exiv2::IptcData& out) const; - void remove_unwanted(Exiv2::Image* dst) const; + void remove_unwanted(Exiv2::ExifData& dst) const; Glib::ustring src_; bool merge_xmp_; From 9735ba5768f8961e525551695c0ad78b18808382 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 5 Apr 2020 07:13:33 -0700 Subject: [PATCH 095/326] metadata: preserve standard exif tags (accidentally broken by 7310eb64978bb1138edbdf02fa58fb64a9326e17) (cherry picked from commit 75a49b8cb9db957dfe13e6911dcf6c83bb92045d) --- rtengine/metadata.cc | 86 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index dbc1e178a..e2bc4dc42 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include "metadata.h" #include "settings.h" @@ -243,22 +244,87 @@ void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const Exiv2::ExifThumb thumb(dst); thumb.erase(); + static const std::set badtags = { + "Exif.Image.Orientation", + "Exif.Image2.JPEGInterchangeFormat", + "Exif.Image2.JPEGInterchangeFormatLength", + "Exif.Image.NewSubfileType", + "Exif.Image.SubfileType", + "Exif.Image.ImageWidth", + "Exif.Image.ImageLength", + "Exif.Image.BitsPerSample", + "Exif.Image.Compression", + "Exif.Image.PhotometricInterpretation", + "Exif.Image.Thresholding", + "Exif.Image.CellWidth", + "Exif.Image.CellLength", + "Exif.Image.FillOrder", + "Exif.Image.StripOffsets", + "Exif.Image.Orientation", + "Exif.Image.SamplesPerPixel", + "Exif.Image.RowsPerStrip", + "Exif.Image.StripByteCounts", + "Exif.Image.XResolution", + "Exif.Image.YResolution", + "Exif.Image.PlanarConfiguration", + "Exif.Image.GrayResponseUnit", + "Exif.Image.GrayResponseCurve", + "Exif.Image.T4Options", + "Exif.Image.T6Options", + "Exif.Image.ResolutionUnit", + "Exif.Image.PageNumber", + "Exif.Image.Predictor", + "Exif.Image.TileWidth", + "Exif.Image.TileLength", + "Exif.Image.TileOffsets", + "Exif.Image.TileByteCounts", + "Exif.Image.SubIFDs", + "Exif.Image.ExtraSamples", + "Exif.Image.SampleFormat", + "Exif.Image.SMinSampleValue", + "Exif.Image.SMaxSampleValue", + "Exif.Image.Indexed", + "Exif.Image.JPEGTables", + "Exif.Image.OPIProxy", + "Exif.Image.JPEGProc", + "Exif.Image.JPEGInterchangeFormat", + "Exif.Image.JPEGInterchangeFormatLength", + "Exif.Image.JPEGRestartInterval", + "Exif.Image.JPEGLosslessPredictors", + "Exif.Image.JPEGPointTransforms", + "Exif.Image.JPEGQTables", + "Exif.Image.JPEGDCTables", + "Exif.Image.JPEGACTables", + "Exif.Image.TIFFEPStandardID", + "Exif.Image.DNGVersion", + "Exif.Image.DNGBackwardVersion", + "Exif.Image.DNGPrivateData", + "Exif.Image.OriginalRawFileData", + "Exif.Image.SubTileBlockSize", + "Exif.Image.RowInterleaveFactor", + "Exif.Photo.ComponentsConfiguration", + "Exif.Photo.CompressedBitsPerPixel" + }; + static const std::vector badpatterns = { - "Exif.Image.", "Exif.SubImage" }; for (auto it = dst.begin(); it != dst.end(); ) { - bool found = false; - for (auto &p : badpatterns) { - if (it->key().find(p) == 0) { - it = dst.erase(it); - found = true; - break; + if (badtags.find(it->key()) != badtags.end()) { + it = dst.erase(it); + } else { + bool found = false; + for (auto &p : badpatterns) { + if (it->key().find(p) == 0) { + it = dst.erase(it); + found = true; + break; + } + } + if (!found) { + ++it; } - } - if (!found) { - ++it; } } } From f62f6807a7c03d33a7d4c4969604806e62cb8b0f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 7 Apr 2020 09:48:14 -0700 Subject: [PATCH 096/326] exifpanel: sort the list of exif tags (cherry picked from commit 88e5ec5dc6a47d3a9cc751d2902aadc540ce0826) --- rtgui/exifpanel.cc | 17 ++++++++++++----- rtgui/exifpanel.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 5cc4af341..5b93f25c8 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -174,7 +174,7 @@ void ExifPanel::setImageData (const FramesMetaData* id) idata = id; } -Gtk::TreeModel::Children ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited) +void ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited) { // TODO Re-fix #5923 if necessary @@ -184,7 +184,7 @@ Gtk::TreeModel::Children ExifPanel::addTag(const std::string &key, const Glib::u auto root = exifTreeModel->children(); - Gtk::TreeModel::Row row = * (exifTreeModel->append (root)); + Gtk::TreeModel::Row row = *(exifTreeModel->append(root)); row[exifColumns.editable] = editable; row[exifColumns.edited] = edited; row[exifColumns.key] = key; @@ -200,8 +200,6 @@ Gtk::TreeModel::Children ExifPanel::addTag(const std::string &key, const Glib::u } else if (editable) { row[exifColumns.icon] = keepicon; } - - return row.children(); } void ExifPanel::refreshTags() @@ -244,6 +242,7 @@ void ExifPanel::refreshTags() addTag(pos->key(), pos->tagLabel(), pos->print(&exif), true, edited); } } + std::map keymap; for (const auto& tag : exif) { const bool editable = ed.find(tag.key()) != ed.end(); if ( @@ -255,9 +254,17 @@ void ExifPanel::refreshTags() || tag.size() < 256 ) ) { - addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); + std::string lbl = tag.tagLabel(); + for (auto &c : lbl) { + c = std::tolower(c); + } + keymap[lbl] = tag.key(); } } + for (auto &p : keymap) { + auto &tag = *(exif.findKey(Exiv2::ExifKey(p.second))); + addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); + } } catch (const std::exception& exc) { return; } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 47ad33c83..cfcf77e4d 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -82,7 +82,7 @@ private: const std::vector> editableTags; - Gtk::TreeModel::Children addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); + void addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); void refreshTags(); void resetIt(const Gtk::TreeModel::const_iterator& iter); void resetPressed(); From 5fdff8dab4650903c162e673e349f072202f7ce9 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 7 Apr 2020 09:48:43 -0700 Subject: [PATCH 097/326] file browser: pick up star ratings from the image metadata if available (cherry picked from commit 98f0675b2e419d18bd88259997b81bcbcc4e5c96) --- rtengine/imagedata.cc | 5 +++++ rtengine/procparams.cc | 42 ++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index a810bc925..42286cd40 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -325,6 +325,11 @@ FramesData::FramesData(const Glib::ustring &fname) : if (find_exif_tag("Exif.Image.Rating")) { rating = pos->toLong(); + } else { + auto it = meta.xmpData().findKey(Exiv2::XmpKey("Xmp.xmp.Rating")); + if (it != meta.xmpData().end() && it->size()) { + rating = it->toLong(); + } } // ----------------------- diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 8794fe0e8..f3068c18e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1363,7 +1363,7 @@ bool WBParams::isPanningRelatedChange(const WBParams& other) const enabled == other.enabled && ( ( - method == "Camera" + method == "Camera" && other.method == "Camera" ) || ( @@ -2327,25 +2327,25 @@ WaveletParams::WaveletParams() : }, blcurve{ static_cast(FCT_MinMaxCPoints), - 0.0, - 0.0, - 0.0, - 0.35, - 0.5, - 0., + 0.0, + 0.0, + 0.0, + 0.35, + 0.5, + 0., 0.35, 0.35, 1.0, 0.0, 0.35, 0.35 -/* +/* 0.0, - 0.35, - 0.35, - 1.0, - 0.0, - 0.35, + 0.35, + 0.35, + 1.0, + 0.0, + 0.35, 0.35 */ }, @@ -5418,7 +5418,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo keyFile.set_string("Version", "AppVersion", RTVERSION); keyFile.set_integer("Version", "Version", PPVERSION); - saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", rank, keyFile); + if (rank >= 0) { + saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", rank, keyFile); + } saveToKeyfile(!pedited || pedited->general.colorlabel, "General", "ColorLabel", colorlabel, keyFile); saveToKeyfile(!pedited || pedited->general.intrash, "General", "InTrash", inTrash, keyFile); @@ -5710,9 +5712,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Dehaze saveToKeyfile(!pedited || pedited->dehaze.enabled, "Dehaze", "Enabled", dehaze.enabled, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); - saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); + saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Saturation", dehaze.saturation, keyFile); // Directional pyramid denoising @@ -6834,7 +6836,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->filmNegative.refInput, "Film Negative", "GreenBase", filmNegative.refInput.g, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.refInput, "Film Negative", "BlueBase", filmNegative.refInput.b, keyFile); } - + saveToKeyfile(!pedited || pedited->filmNegative.colorSpace, "Film Negative", "ColorSpace", toUnderlying(filmNegative.colorSpace), keyFile); saveToKeyfile(!pedited || pedited->filmNegative.refInput, "Film Negative", "RefInput", filmNegative.refInput, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.refOutput, "Film Negative", "RefOutput", filmNegative.refOutput, keyFile); @@ -7352,7 +7354,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->colorappearance.complexmethod = true; } } - + if (keyFile.has_key("Color appearance", "ModelCat")) { assignFromKeyfile(keyFile, "Color appearance", "ModelCat", pedited, colorappearance.modelmethod, pedited->colorappearance.modelmethod); } else if (colorappearance.enabled) { @@ -7362,7 +7364,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "Color appearance", "CatCat", pedited, 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); From abb052e51bc4a9001d5af9403707d18c69ba57db Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 8 Apr 2020 11:48:36 -0700 Subject: [PATCH 098/326] metadata: allow to select which metadata tags to include in the output image (cherry picked from commit ed64206cb8b4455870815e2c51aecbd5c09e4054) --- rtdata/images/svg/add.svg | 14 +-- rtdata/images/svg/box.svg | 110 ++++++++++++++++++++ rtdata/images/svg/tick.svg | 12 +-- rtengine/metadata.cc | 12 +++ rtengine/metadata.h | 5 + rtengine/procparams.cc | 31 +++++- rtengine/procparams.h | 1 + rtengine/simpleprocess.cc | 3 + rtgui/exifpanel.cc | 202 +++++++++++++++++++++++++++---------- rtgui/exifpanel.h | 17 ++++ rtgui/paramsedited.cc | 6 ++ rtgui/paramsedited.h | 1 + 12 files changed, 347 insertions(+), 67 deletions(-) create mode 100644 rtdata/images/svg/box.svg diff --git a/rtdata/images/svg/add.svg b/rtdata/images/svg/add.svg index c45f9f584..41fa7cc39 100644 --- a/rtdata/images/svg/add.svg +++ b/rtdata/images/svg/add.svg @@ -17,7 +17,7 @@ inkscape:export-filename="/tmp/template.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" - inkscape:version="0.92.2 2405546, 2018-03-11" + inkscape:version="0.91 r13725" sodipodi:docname="add.svg"> image/svg+xml - + Maciej Dworak @@ -120,8 +120,8 @@ style="opacity:0.7;fill:none;fill-opacity:0.53333285;fill-rule:nonzero;stroke:#2a7fff;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/images/svg/box.svg b/rtdata/images/svg/box.svg new file mode 100644 index 000000000..2ebee4b8c --- /dev/null +++ b/rtdata/images/svg/box.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + image/svg+xml + + + + + Maciej Dworak + + + + + + + + RawTherapee icon. + + + + + + + + + + + + + + + + diff --git a/rtdata/images/svg/tick.svg b/rtdata/images/svg/tick.svg index 8ab7a2e27..dd4ab4bdd 100644 --- a/rtdata/images/svg/tick.svg +++ b/rtdata/images/svg/tick.svg @@ -17,8 +17,8 @@ inkscape:export-filename="/tmp/template.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" - inkscape:version="0.92.2 2405546, 2018-03-11" - sodipodi:docname="tick-large.svg"> + inkscape:version="0.91 r13725" + sodipodi:docname="tick.svg"> image/svg+xml - + Maciej Dworak @@ -103,7 +103,7 @@ sodipodi:nodetypes="ccccccc" inkscape:connector-curvature="0" id="path2996-6" - d="M 4.6666624,10.166665 8.3333305,13.833335 19.333336,2.833329 23.000006,6.4999972 8.3333305,21.166671 0.99999442,13.833335 Z" + d="M 6.0000005,10.299997 9.0000007,13.533332 18.000004,3.833329 21.000006,7.066663 9.0000007,20 3,13.533332 Z" style="opacity:0.7;fill:#2a7fff;fill-opacity:1;stroke:none;stroke-width:2.30911016" /> diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index e2bc4dc42..af2a7ef8a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -313,6 +313,8 @@ void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const for (auto it = dst.begin(); it != dst.end(); ) { if (badtags.find(it->key()) != badtags.end()) { it = dst.erase(it); + } else if (exif_keys_ && exif_keys_->find(it->key()) == exif_keys_->end()) { + it = dst.erase(it); } else { bool found = false; for (auto &p : badpatterns) { @@ -393,6 +395,16 @@ void Exiv2Metadata::saveToXmp(const Glib::ustring &path) const } +void Exiv2Metadata::setExifKeys(const std::vector *keys) +{ + exif_keys_.reset(); + if (keys) { + exif_keys_ = std::make_shared>(); + exif_keys_->insert(keys->begin(), keys->end()); + } +} + + Glib::ustring Exiv2Metadata::xmpSidecarPath(const Glib::ustring &path) { Glib::ustring fn = path; diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 7439d6b36..57484d234 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "procparams.h" #include "cache.h" @@ -55,6 +56,8 @@ public: void saveToImage(const Glib::ustring& path) const; void saveToXmp(const Glib::ustring& path) const; + void setExifKeys(const std::vector *keys); + static Glib::ustring xmpSidecarPath(const Glib::ustring& path); static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path); @@ -76,6 +79,8 @@ private: Exiv2::IptcData iptc_data_; Exiv2::XmpData xmp_data_; + std::shared_ptr> exif_keys_; + typedef std::pair, Glib::TimeVal> CacheVal; typedef Cache ImageCache; static std::unique_ptr cache_; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f3068c18e..5076e147f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -178,6 +178,17 @@ void getFromKeyfile( } } +void getFromKeyfile( + const Glib::KeyFile& keyfile, + const Glib::ustring& group_name, + const Glib::ustring& key, + std::vector& value +) +{ + auto tmpval = keyfile.get_string_list(group_name, key); + value.assign(tmpval.begin(), tmpval.end()); +} + template bool assignFromKeyfile( const Glib::KeyFile& keyfile, @@ -306,6 +317,17 @@ void putToKeyfile( keyfile.set_double_list(group_name, key, list); } +void putToKeyfile( + const Glib::ustring& group_name, + const Glib::ustring& key, + const std::vector& value, + Glib::KeyFile& keyfile +) +{ + const Glib::ArrayHandle list = value; + keyfile.set_string_list(group_name, key, list); +} + void putToKeyfile( const Glib::ustring& group_name, const Glib::ustring& key, @@ -5226,13 +5248,15 @@ Glib::ustring RAWParams::getFlatFieldBlurTypeString(FlatFieldBlurType type) MetaDataParams::MetaDataParams(): - mode(MetaDataParams::TUNNEL) + mode(MetaDataParams::TUNNEL), + exifKeys{"ALL"} { } bool MetaDataParams::operator==(const MetaDataParams &other) const { - return mode == other.mode; + return mode == other.mode + && exifKeys == other.exifKeys; } bool MetaDataParams::operator!=(const MetaDataParams &other) const @@ -6823,6 +6847,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // MetaData saveToKeyfile(!pedited || pedited->metadata.mode, "MetaData", "Mode", metadata.mode, keyFile); + saveToKeyfile(!pedited || pedited->metadata.exifKeys, "MetaData", "ExifKeys", metadata.exifKeys, keyFile); // Film negative saveToKeyfile(!pedited || pedited->filmNegative.enabled, "Film Negative", "Enabled", filmNegative.enabled, keyFile); @@ -9350,6 +9375,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) { metadata.mode = static_cast(mode); } + + assignFromKeyfile(keyFile, "MetaData", "ExifKeys", pedited, metadata.exifKeys, pedited->metadata.exifKeys); } if (keyFile.has_group("Exif")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4a1eb47e3..dd6872630 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1728,6 +1728,7 @@ struct MetaDataParams { STRIP }; Mode mode; + std::vector exifKeys; MetaDataParams(); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 0b6406b62..c8ee5e147 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1739,6 +1739,9 @@ private: case MetaDataParams::EDIT: info.setExif(params.exif); info.setIptc(params.iptc); + if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "ALL")) { + info.setExifKeys(&(params.metadata.exifKeys)); + } readyImg->setMetadata(std::move(info)); break; default: // case MetaDataParams::STRIP diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 5b93f25c8..f63541e5f 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -51,16 +51,17 @@ ExifPanel::ExifPanel() : exifTree->set_rules_hint (false); exifTree->set_reorderable (false); exifTree->set_enable_search (false); - exifTree->get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); - scrolledWindow->set_shadow_type (Gtk::SHADOW_NONE); - scrolledWindow->set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); + exifTree->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); + scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); scrolledWindow->property_window_placement().set_value (Gtk::CORNER_TOP_LEFT); - scrolledWindow->add (*exifTree); + scrolledWindow->add(*exifTree); - exifTreeModel = Gtk::TreeStore::create (exifColumns); - exifTree->set_model (exifTreeModel); - exifTree->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_NONE); + exifTreeModel = Gtk::TreeStore::create(exifColumns); + exifTree->set_model(exifTreeModel); + exifTree->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE); exifTree->set_show_expanders(false); + exifTree->set_tooltip_column(0); keepicon = RTImage::createPixbufFromFile ("tick-small.png"); editicon = RTImage::createPixbufFromFile("add-small.png"); @@ -69,25 +70,32 @@ ExifPanel::ExifPanel() : Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ()); Gtk::CellRendererText *render_txt = Gtk::manage (new Gtk::CellRendererText()); render_txt->property_ellipsize() = Pango::ELLIPSIZE_END; - viewcol->pack_start (*render_pb, false); - viewcol->pack_start (*render_txt, true); - viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon); - viewcol->add_attribute (*render_txt, "markup", exifColumns.label); - viewcol->set_expand (true); - viewcol->set_resizable (true); - viewcol->set_fixed_width (35); - viewcol->set_min_width (35); - viewcol->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE); + viewcol->pack_start(*render_pb, false); + viewcol->pack_start(*render_txt, true); + viewcol->add_attribute(*render_pb, "pixbuf", exifColumns.icon); + viewcol->add_attribute(*render_txt, "markup", exifColumns.label); + viewcol->set_expand(true); + viewcol->set_resizable(true); + viewcol->set_fixed_width(35); + viewcol->set_min_width(35); + viewcol->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE); render_pb->property_ypad() = 0; render_txt->property_ypad() = 0; render_pb->property_yalign() = 0; render_txt->property_yalign() = 0; - exifTree->append_column (*viewcol); + exif_active_renderer_.property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + exif_active_renderer_.signal_toggled().connect(sigc::mem_fun(this, &ExifPanel::onKeyActiveToggled)); + exif_active_column_.pack_start(exif_active_renderer_); + exif_active_column_.set_cell_data_func(exif_active_renderer_, sigc::mem_fun(this, &ExifPanel::setKeyActive)); - Gtk::TreeView::Column *viewcolv = Gtk::manage (new Gtk::TreeView::Column ("Value")); - Gtk::CellRendererText *render_txtv = Gtk::manage (new Gtk::CellRendererText()); + exifTree->append_column(exif_active_column_); + + exifTree->append_column(*viewcol); + + Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); + Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); render_txtv->property_ellipsize() = Pango::ELLIPSIZE_END; viewcolv->pack_start (*render_txtv, true); viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); @@ -108,26 +116,23 @@ ExifPanel::ExifPanel() : buttons1->set_column_homogeneous (true); setExpandAlignProperties (buttons1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - add = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_ADDEDIT") - add->set_image (*Gtk::manage (new RTImage(editicon))); - add->set_tooltip_text (M ("EXIFPANEL_ADDEDITHINT")); - add->get_style_context()->add_class ("Right"); - setExpandAlignProperties (add, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to (*add, Gtk::POS_RIGHT, 1, 1); + const auto addbtn = + [&](const Glib::ustring &tip, const Glib::ustring &icon1, const Glib::ustring &icon2=Glib::ustring()) -> Gtk::Button * + { + Gtk::Button *b = Gtk::manage(new Gtk::Button()); + b->set_image(*Gtk::manage(new RTImage(icon1, icon2))); + b->set_tooltip_text(M(tip)); + b->get_style_context()->add_class("Right"); + setExpandAlignProperties(b, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons1->attach_next_to(*b, Gtk::POS_RIGHT, 1, 1); + return b; + }; - reset = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESET") - reset->set_image (*Gtk::manage (new RTImage("undo.png", "redo.png"))); - reset->set_tooltip_text (M ("EXIFPANEL_RESETHINT")); - reset->get_style_context()->add_class ("MiddleH"); - setExpandAlignProperties (reset, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->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_tooltip_text (M ("EXIFPANEL_RESETALLHINT")); - resetAll->get_style_context()->add_class ("Right"); - setExpandAlignProperties (resetAll, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to (*resetAll, Gtk::POS_RIGHT, 1, 1); + activate_all_ = addbtn("EXIFPANEL_ACTIVATE_ALL_HINT", "tick.png"); + activate_none_ = addbtn("EXIFPANEL_ACTIVATE_NONE_HINT", "box.png"); + add = addbtn("EXIFPANEL_ADDEDIT", "add.png"); + reset = addbtn("EXIFPANEL_RESETHINT", "undo.png", "redo.png"); + resetAll = addbtn("EXIFPANEL_RESETALLHINT", "undo-all.png", "redo-all.png"); pack_end (*buttons1, Gtk::PACK_SHRINK); @@ -137,6 +142,8 @@ ExifPanel::ExifPanel() : reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) ); resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) ); add->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::addPressed) ); + activate_all_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateAllPressed)); + activate_none_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateNonePressed)); show_all (); } @@ -147,24 +154,56 @@ ExifPanel::~ExifPanel () void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); + disableListener(); *changeList = pp->exif; - setImageData (idata); + initial_active_keys_.clear(); + initial_active_keys_.insert(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end()); + cur_active_keys_ = initial_active_keys_; + setImageData(idata); refreshTags(); - enableListener (); + enableListener(); } void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) { pp->exif = *changeList; + + std::unordered_set prev; + bool all_active = (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "ALL"); + + if (!all_active) { + prev = cur_active_keys_; + } + + pp->metadata.exifKeys.clear(); + + bool none_active = true; + + auto root = exifTreeModel->children(); + for (auto &entry : root->children()) { + Glib::ustring key = entry[exifColumns.key]; + prev.erase(key); + if (entry[exifColumns.active]) { + pp->metadata.exifKeys.push_back(key); + none_active = false; + } else { + all_active = false; + } + } + + if (all_active) { + pp->metadata.exifKeys = { "ALL" }; + } else if (!none_active) { + pp->metadata.exifKeys.insert(pp->metadata.exifKeys.end(), prev.begin(), prev.end()); + } + std::sort(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end()); } void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { - *defChangeList = defParams->exif; } @@ -195,6 +234,9 @@ void ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const row[exifColumns.label] = escapeHtmlChars(label); row[exifColumns.value] = escapeHtmlChars(value); + bool active = (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "ALL") || cur_active_keys_.find(key) != cur_active_keys_.end(); + row[exifColumns.active] = active; + if (edited) { row[exifColumns.icon] = editicon; } else if (editable) { @@ -223,6 +265,17 @@ void ExifPanel::refreshTags() ed.insert(p.first); } + const auto to_label = + [](const Exiv2::Exifdatum &tag) -> Glib::ustring + { + auto s = tag.key(); + auto pos = s.find('.'); + if (pos != std::string::npos) { + s = s.substr(pos+1); + } + return s; + }; + try { rtengine::Exiv2Metadata meta(fn); meta.load(); @@ -239,10 +292,10 @@ void ExifPanel::refreshTags() const auto pos = exif.findKey(Exiv2::ExifKey(p.first)); if (pos != exif.end() && pos->size()) { const bool edited = changeList->find(pos->key()) != changeList->end(); - addTag(pos->key(), pos->tagLabel(), pos->print(&exif), true, edited); + addTag(pos->key(), to_label(*pos), pos->print(&exif), true, edited); } } - std::map keymap; + std::multimap keymap; for (const auto& tag : exif) { const bool editable = ed.find(tag.key()) != ed.end(); if ( @@ -254,16 +307,16 @@ void ExifPanel::refreshTags() || tag.size() < 256 ) ) { - std::string lbl = tag.tagLabel(); + std::string lbl = to_label(tag); for (auto &c : lbl) { c = std::tolower(c); } - keymap[lbl] = tag.key(); + keymap.insert(std::make_pair(lbl, tag.key())); } } for (auto &p : keymap) { auto &tag = *(exif.findKey(Exiv2::ExifKey(p.second))); - addTag(tag.key(), tag.tagLabel(), tag.print(&exif), false, false); + addTag(tag.key(), to_label(tag), tag.print(&exif), false, false); } } catch (const std::exception& exc) { return; @@ -303,7 +356,7 @@ void ExifPanel::resetIt(const Gtk::TreeModel::const_iterator& iter) changeList->erase(key); } -void ExifPanel::resetPressed () +void ExifPanel::resetPressed() { std::vector sel = exifTree->get_selection()->get_selected_rows(); @@ -320,8 +373,9 @@ void ExifPanel::resetAllPressed () { setImageData(idata); *changeList = *defChangeList; + cur_active_keys_ = initial_active_keys_; refreshTags(); - notifyListener (); + notifyListener(); } void ExifPanel::addPressed () @@ -391,8 +445,9 @@ void ExifPanel::addPressed () auto key = editableTags[tcombo->get_active_row_number()].first; const auto value = ventry->get_text(); (*changeList)[key] = value; + cur_active_keys_.insert(key); refreshTags(); - notifyListener (); + notifyListener(); } delete dialog; @@ -404,9 +459,52 @@ void ExifPanel::addPressed () delete hb2; } -void ExifPanel::notifyListener () +void ExifPanel::activateAllPressed() +{ + disableListener(); + auto root = exifTreeModel->children(); + for (auto &row : root->children()) { + row[exifColumns.active] = true; + } + enableListener(); + notifyListener(); +} + + +void ExifPanel::activateNonePressed() +{ + disableListener(); + auto root = exifTreeModel->children(); + for (auto &row : root->children()) { + row[exifColumns.active] = false; + } + enableListener(); + notifyListener(); +} + + +void ExifPanel::notifyListener() { if (listener) { - listener->panelChanged (EvExif, M ("HISTORY_CHANGED")); + listener->panelChanged(EvExif, M("HISTORY_CHANGED")); } } + + +void ExifPanel::onKeyActiveToggled(const Glib::ustring &path) +{ + auto it = exifTreeModel->get_iter(path); + if (it) { + auto row = *it; + row[exifColumns.active] = !row[exifColumns.active]; + notifyListener(); + } +} + + +void ExifPanel::setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it) +{ + auto row = *it; + static_cast(renderer)->set_active(row[exifColumns.active]); +} + diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index cfcf77e4d..1f9378fa3 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -21,6 +21,7 @@ #include #include +#include #include "toolpanel.h" @@ -56,6 +57,7 @@ private: Gtk::TreeModelColumn value_nopango; Gtk::TreeModelColumn editable; Gtk::TreeModelColumn edited; + Gtk::TreeModelColumn active; ExifColumns() { @@ -66,6 +68,7 @@ private: add(edited); add(value_nopango); add(editable); + add(active); } }; Glib::RefPtr keepicon; @@ -79,15 +82,29 @@ private: Gtk::Button* add; Gtk::Button* reset; Gtk::Button* resetAll; + Gtk::Button *activate_all_; + Gtk::Button *activate_none_; + + Gtk::CellRendererToggle exif_active_renderer_; + Gtk::TreeView::Column exif_active_column_; const std::vector> editableTags; + std::unordered_set initial_active_keys_; + std::unordered_set cur_active_keys_; + void addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); void refreshTags(); void resetIt(const Gtk::TreeModel::const_iterator& iter); void resetPressed(); void resetAllPressed(); void addPressed(); + void activateAllPressed(); + void activateNonePressed(); + + void setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it); + void onKeyActiveToggled(const Glib::ustring &path); + public: ExifPanel (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 1fdefc0a3..8459d4013 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -675,6 +675,7 @@ void ParamsEdited::set(bool v) dehaze.depth = v; dehaze.saturation = v; metadata.mode = v; + metadata.exifKeys = v; filmNegative.enabled = v; filmNegative.redRatio = v; filmNegative.greenExp = v; @@ -1931,6 +1932,7 @@ void ParamsEdited::initFrom(const std::vector& dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; dehaze.saturation = dehaze.saturation && p.dehaze.saturation == other.dehaze.saturation; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; + metadata.exifKeys = metadata.exifKeys && p.metadata.exifKeys == other.metadata.exifKeys; filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; @@ -6569,6 +6571,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.metadata.mode = mods.metadata.mode; } + if (metadata.exifKeys) { + toEdit.metadata.exifKeys = mods.metadata.exifKeys; + } + if (filmNegative.enabled) { toEdit.filmNegative.enabled = mods.filmNegative.enabled; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 95fc76407..a7306ba68 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1361,6 +1361,7 @@ struct RAWParamsEdited { struct MetaDataParamsEdited { bool mode; + bool exifKeys; }; struct FilmNegativeParamsEdited { From a26e6272821b3235741a482e60f18085a8e94e4a Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 9 Apr 2020 10:06:00 -0700 Subject: [PATCH 099/326] Add EXIF panel activate buttons hints Original commit message: updated French and Brazilian translations (cherry picked from commit 63db950a767737181b25e1888534cfac1cc40899) --- rtdata/languages/default | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3f51e1d90..4c0087cd3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -62,6 +62,8 @@ EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Lens EXIFFILTER_METADATAFILTER;Enable metadata filters EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags +EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags EXIFPANEL_ADDEDIT;Add/Edit EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value From 8a5aa6c1194b3de93608bba43632e2c5267aa1c3 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 9 Apr 2020 08:33:18 -0700 Subject: [PATCH 100/326] exif panel: further tweaks to the metadata selection (cherry picked from commit 207e51b64726367f2d932c000060f00b2697523f) --- rtgui/exifpanel.cc | 150 +++++++++++++++++++++++++++++++-------------- rtgui/exifpanel.h | 6 +- 2 files changed, 109 insertions(+), 47 deletions(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index f63541e5f..ba612f615 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -39,11 +39,11 @@ ExifPanel::ExifPanel() : {"Exif.Photo.UserComment", "User Comment"}, {"Exif.Image.Artist", "Artist"}, {"Exif.Image.Copyright", "Copyright"}, - {"Exif.Image.ImageDescription", "Image Description"} + {"Exif.Image.ImageDescription", "Image Description"}, + { "Exif.Photo.LensModel", "Lens Model" } } { set_orientation(Gtk::ORIENTATION_VERTICAL); - exifTree = Gtk::manage (new Gtk::TreeView()); scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); @@ -54,13 +54,13 @@ ExifPanel::ExifPanel() : exifTree->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - scrolledWindow->property_window_placement().set_value (Gtk::CORNER_TOP_LEFT); + scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); scrolledWindow->add(*exifTree); exifTreeModel = Gtk::TreeStore::create(exifColumns); exifTree->set_model(exifTreeModel); exifTree->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE); - exifTree->set_show_expanders(false); + //exifTree->set_show_expanders(false); exifTree->set_tooltip_column(0); keepicon = RTImage::createPixbufFromFile ("tick-small.png"); @@ -93,6 +93,7 @@ ExifPanel::ExifPanel() : exifTree->append_column(exif_active_column_); exifTree->append_column(*viewcol); + exifTree->set_expander_column(*viewcol); Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); @@ -107,7 +108,7 @@ ExifPanel::ExifPanel() : render_txtv->property_ypad() = 0; - exifTree->append_column (*viewcolv); + exifTree->append_column(*viewcolv); pack_start (*scrolledWindow); @@ -183,14 +184,26 @@ void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) bool none_active = true; auto root = exifTreeModel->children(); - for (auto &entry : root->children()) { - Glib::ustring key = entry[exifColumns.key]; - prev.erase(key); - if (entry[exifColumns.active]) { - pp->metadata.exifKeys.push_back(key); - none_active = false; - } else { - all_active = false; + // for (auto &entry : root->children()) { + // Glib::ustring key = entry[exifColumns.key]; + // prev.erase(key); + // if (entry[exifColumns.active]) { + // pp->metadata.exifKeys.push_back(key); + // none_active = false; + // } else { + // all_active = false; + // } + // } + for (auto &group : root->children()) { + for (auto &entry : group.children()) { + std::string key = entry[exifColumns.key]; + prev.erase(key); + if (entry[exifColumns.active]) { + pp->metadata.exifKeys.push_back(key); + none_active = false; + } else { + all_active = false; + } } } @@ -209,11 +222,10 @@ void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pe void ExifPanel::setImageData (const FramesMetaData* id) { - idata = id; } -void ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited) +void ExifPanel::addTag(const std::string &key, const std::pair &label, const Glib::ustring &value, bool editable, bool edited) { // TODO Re-fix #5923 if necessary @@ -221,18 +233,47 @@ void ExifPanel::addTag(const std::string &key, const Glib::ustring &label, const // value = "???"; //} - auto root = exifTreeModel->children(); +// auto root = exifTreeModel->children(); + + const auto getgroup = + [&]() -> Gtk::TreeNodeChildren + { + auto root = exifTreeModel->children(); + + for (auto it = root.rbegin(), end = root.rend(); it != end; ++it) { + auto row = *it; + std::string key = row[exifColumns.key]; + if (row[exifColumns.is_group] && key == label.first) { + return it->children(); + } + } + auto it = exifTreeModel->append(root); + auto row = *it; + + row[exifColumns.editable] = false; + row[exifColumns.edited] = false; + row[exifColumns.key] = label.first; + row[exifColumns.label] = "" + label.first + ""; + row[exifColumns.value_nopango] = ""; + row[exifColumns.value] = ""; + row[exifColumns.is_group] = true; + + return it->children(); + }; + + auto root = getgroup(); Gtk::TreeModel::Row row = *(exifTreeModel->append(root)); row[exifColumns.editable] = editable; row[exifColumns.edited] = edited; row[exifColumns.key] = key; - row[exifColumns.label] = label; + row[exifColumns.is_group] = false; + //row[exifColumns.label] = label.second; row[exifColumns.value_nopango] = value; - row[exifColumns.value] = value; + //row[exifColumns.value] = value; - row[exifColumns.label] = escapeHtmlChars(label); - row[exifColumns.value] = escapeHtmlChars(value); + row[exifColumns.label] = escapeHtmlChars(label.second); + row[exifColumns.value] = value;//escapeHtmlChars(value); bool active = (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "ALL") || cur_active_keys_.find(key) != cur_active_keys_.end(); row[exifColumns.active] = active; @@ -266,14 +307,20 @@ void ExifPanel::refreshTags() } const auto to_label = - [](const Exiv2::Exifdatum &tag) -> Glib::ustring + [](const Exiv2::Exifdatum &tag) -> std::pair { auto s = tag.key(); auto pos = s.find('.'); if (pos != std::string::npos) { s = s.substr(pos+1); } - return s; + Glib::ustring g = ""; + pos = s.find('.'); + if (pos != std::string::npos) { + g = s.substr(0, pos); + s = s.substr(pos+1); + } + return std::make_pair(g, Glib::ustring(s)); }; try { @@ -281,6 +328,17 @@ void ExifPanel::refreshTags() meta.load(); auto& exif = meta.exifData(); + const auto to_value = + [&](Exiv2::Exifdatum &tag) -> Glib::ustring + { + if (!tag.tagLabel().empty() && tag.typeId() != Exiv2::undefined && + (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { + return escapeHtmlChars(tag.print(&exif)); + } + return "(Not shown)"; + }; + + for (const auto& p : *changeList) { try { exif[p.first] = p.second; @@ -295,28 +353,16 @@ void ExifPanel::refreshTags() addTag(pos->key(), to_label(*pos), pos->print(&exif), true, edited); } } - std::multimap keymap; + std::set keyset; for (const auto& tag : exif) { const bool editable = ed.find(tag.key()) != ed.end(); - if ( - !editable - && !tag.tagLabel().empty() - && tag.typeId() != Exiv2::undefined - && ( - tag.typeId() == Exiv2::asciiString - || tag.size() < 256 - ) - ) { - std::string lbl = to_label(tag); - for (auto &c : lbl) { - c = std::tolower(c); - } - keymap.insert(std::make_pair(lbl, tag.key())); + if (!editable) { + keyset.insert(tag.key()); } } - for (auto &p : keymap) { - auto &tag = *(exif.findKey(Exiv2::ExifKey(p.second))); - addTag(tag.key(), to_label(tag), tag.print(&exif), false, false); + for (auto &k : keyset) { + auto &tag = *(exif.findKey(Exiv2::ExifKey(k))); + addTag(tag.key(), to_label(tag), to_value(tag), false, false); } } catch (const std::exception& exc) { return; @@ -325,6 +371,8 @@ void ExifPanel::refreshTags() for (const auto& p : sel) { exifTree->get_selection()->select(p); } + + exifTree->expand_all(); } void ExifPanel::exifSelectionChanged () @@ -463,8 +511,11 @@ void ExifPanel::activateAllPressed() { disableListener(); auto root = exifTreeModel->children(); - for (auto &row : root->children()) { - row[exifColumns.active] = true; + for (auto &group : root->children()) { + group[exifColumns.active] = true; + for (auto &row : group.children()) { + row[exifColumns.active] = true; + } } enableListener(); notifyListener(); @@ -475,8 +526,11 @@ void ExifPanel::activateNonePressed() { disableListener(); auto root = exifTreeModel->children(); - for (auto &row : root->children()) { - row[exifColumns.active] = false; + for (auto &group : root->children()) { + group[exifColumns.active] = false; + for (auto &row : group.children()) { + row[exifColumns.active] = false; + } } enableListener(); notifyListener(); @@ -496,7 +550,13 @@ void ExifPanel::onKeyActiveToggled(const Glib::ustring &path) auto it = exifTreeModel->get_iter(path); if (it) { auto row = *it; - row[exifColumns.active] = !row[exifColumns.active]; + bool b = !row[exifColumns.active]; + row[exifColumns.active] = b; + if (row[exifColumns.is_group]) { + for (auto &c : row.children()) { + c[exifColumns.active] = b; + } + } notifyListener(); } } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 1f9378fa3..32ce10dc7 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -51,13 +51,14 @@ private: { public: Gtk::TreeModelColumn > icon; - Gtk::TreeModelColumn key; + Gtk::TreeModelColumn key; Gtk::TreeModelColumn label; Gtk::TreeModelColumn value; Gtk::TreeModelColumn value_nopango; Gtk::TreeModelColumn editable; Gtk::TreeModelColumn edited; Gtk::TreeModelColumn active; + Gtk::TreeModelColumn is_group; ExifColumns() { @@ -69,6 +70,7 @@ private: add(value_nopango); add(editable); add(active); + add(is_group); } }; Glib::RefPtr keepicon; @@ -93,7 +95,7 @@ private: std::unordered_set initial_active_keys_; std::unordered_set cur_active_keys_; - void addTag(const std::string &key, const Glib::ustring &label, const Glib::ustring &value, bool editable, bool edited); + void addTag(const std::string &key, const std::pair &label, const Glib::ustring &value, bool editable, bool edited); void refreshTags(); void resetIt(const Gtk::TreeModel::const_iterator& iter); void resetPressed(); From b92e77fb961fa84b4d3e09c37e3ccdd0c340ea0d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 10 Apr 2020 05:54:40 -0700 Subject: [PATCH 101/326] improved support for metadata editing (cherry picked from commit 85da0b51ecf7ece768c0267aead71dd94404d4dc) --- rtdata/images/svg/edit-small.svg | 128 +++++++++++++++++ rtdata/images/svg/edit.svg | 136 ++++++++++++++++++ rtdata/languages/default | 5 +- rtengine/imagedata.cc | 33 +++++ rtengine/imagedata.h | 3 + rtengine/metadata.cc | 11 ++ rtengine/procparams.cc | 154 +++++++++++++-------- rtengine/procparams.h | 46 ++++--- rtengine/simpleprocess.cc | 6 +- rtgui/exifpanel.cc | 227 ++++++++++++++++++++----------- rtgui/exifpanel.h | 19 ++- rtgui/iptcpanel.cc | 8 +- rtgui/paramsedited.cc | 8 +- rtgui/thumbnail.cc | 6 +- rtgui/toolpanelcoord.cc | 8 +- 15 files changed, 615 insertions(+), 183 deletions(-) create mode 100644 rtdata/images/svg/edit-small.svg create mode 100644 rtdata/images/svg/edit.svg diff --git a/rtdata/images/svg/edit-small.svg b/rtdata/images/svg/edit-small.svg new file mode 100644 index 000000000..6306f06df --- /dev/null +++ b/rtdata/images/svg/edit-small.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + image/svg+xml + + + + + Maciej Dworak + + + + + + + + RawTherapee icon. + + + + + + + + + + + + + + + + + + + diff --git a/rtdata/images/svg/edit.svg b/rtdata/images/svg/edit.svg new file mode 100644 index 000000000..71f3d0b06 --- /dev/null +++ b/rtdata/images/svg/edit.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + image/svg+xml + + + + + Maciej Dworak + + + + + + + + RawTherapee icon. + + + + + + + + + + + + + + + + + + + + + diff --git a/rtdata/languages/default b/rtdata/languages/default index 4c0087cd3..a5ce4fa54 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -77,8 +77,7 @@ EXIFPANEL_RESET;Reset EXIFPANEL_RESETALL;Reset All EXIFPANEL_RESETALLHINT;Reset all tags to their original values. EXIFPANEL_RESETHINT;Reset the selected tags to their original values. -EXIFPANEL_SHOWALL;Show all -EXIFPANEL_SUBDIRECTORY;Subdirectory +EXIFPANEL_BASIC_GROUP;Basic EXPORT_BYPASS;Processing steps to bypass EXPORT_BYPASS_ALL;Select / Unselect All EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -1548,7 +1547,7 @@ 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_EXPOSURE;Exposure diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 42286cd40..52a9fa297 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -699,3 +699,36 @@ double FramesMetaData::apertureFromString(std::string s) return std::atof(s.c_str()); } + + +namespace { + +template +void set_exif(Exiv2::ExifData &exif, const std::string &key, T val) +{ + try { + exif[key] = val; + } catch (std::exception &exc) {} +} + +} // namespace + +void FramesData::fillBasicTags(Exiv2::ExifData &exif) const +{ + if (!hasExif()) { + return; + } + set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed()); + set_exif(exif, "Exif.Photo.FNumber", Exiv2::DoubleValue(getFNumber())); + //set_exif(exif, "Exif.Photo.ExposureTime", Exiv2::DoubleValue(getShutterSpeed())); + set_exif(exif, "Exif.Photo.ExposureTime", shutterToString(getShutterSpeed())); + set_exif(exif, "Exif.Photo.FocalLength", Exiv2::DoubleValue(getFocalLen())); + set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(getExpComp())); + set_exif(exif, "Exif.Image.Make", getMake()); + set_exif(exif, "Exif.Image.Model", getModel()); + set_exif(exif, "Exif.Photo.LensModel", getLens()); + char buf[256]; + auto t = getDateTime(); + strftime(buf, 256, "%Y:%m:%d %H:%M:%S", &t); + set_exif(exif, "Exif.Photo.DateTimeOriginal", buf); +} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 306c3b6f9..3a915c15d 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -23,6 +23,7 @@ #include #include "imageio.h" +#include "metadata.h" namespace Glib { @@ -83,6 +84,8 @@ public: std::string getOrientation() const override; Glib::ustring getFileName() const override; int getRating() const override; + + void fillBasicTags(Exiv2::ExifData &exif) const; }; } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index af2a7ef8a..d04b979fe 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -26,6 +26,7 @@ #include "metadata.h" #include "settings.h" +#include "imagedata.h" #include "../rtgui/version.h" #include "../rtgui/pathutils.h" @@ -309,6 +310,16 @@ void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const static const std::vector badpatterns = { "Exif.SubImage" }; + + if (exif_keys_ && !src_.empty()) { + try { + FramesData fd(src_); + fd.fillBasicTags(dst); + } catch (std::exception &exc) { + std::cout << "Error reading metadata from " << src_ + << std::endl; + } + } for (auto it = dst.begin(); it != dst.end(); ) { if (badtags.find(it->key()) != badtags.end()) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 5076e147f..06ea2be6a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -379,33 +379,6 @@ bool saveToKeyfile( return false; } -const std::map exif_keys = { - {"Copyright", "Exif.Image.Copyright"}, - {"Artist", "Exif.Image.Artist"}, - {"ImageDescription", "Exif.Image.ImageDescription"}, - {"Exif.UserComment", "Exif.Photo.UserComment"} -}; - -const std::map iptc_keys = { - {"Title", "Iptc.Application2.ObjectName"}, - {"Category", "Iptc.Application2.Category"}, - {"SupplementalCategories", "Iptc.Application2.SuppCategory"}, - {"Keywords", "Iptc.Application2.Keywords"}, - {"Instructions", "Iptc.Application2.SpecialInstructions"}, - {"DateCreated", "Iptc.Application2.DateCreated"}, - {"Creator", "Iptc.Application2.Byline"}, - {"CreatorJobTitle", "Iptc.Application2.BylineTitle"}, - {"City", "Iptc.Application2.City"}, - {"Province", "Iptc.Application2.ProvinceState"}, - {"Country", "Iptc.Application2.CountryName"}, - {"TransReference", "Iptc.Application2.TransmissionReference"}, - {"Headline", "Iptc.Application2.Headline"}, - {"Credit", "Iptc.Application2.Credit"}, - {"Source", "Iptc.Application2.Source"}, - {"Copyright", "Iptc.Application2.Copyright"}, - {"Caption", "Iptc.Application2.Caption"}, - {"CaptionWriter", "Iptc.Application2.Writer"} -}; } // namespace @@ -5247,23 +5220,6 @@ Glib::ustring RAWParams::getFlatFieldBlurTypeString(FlatFieldBlurType type) } -MetaDataParams::MetaDataParams(): - mode(MetaDataParams::TUNNEL), - exifKeys{"ALL"} -{ -} - -bool MetaDataParams::operator==(const MetaDataParams &other) const -{ - return mode == other.mode - && exifKeys == other.exifKeys; -} - -bool MetaDataParams::operator!=(const MetaDataParams &other) const -{ - return !(*this == other); -} - FilmNegativeParams::FilmNegativeParams() : enabled(false), redRatio(1.36), @@ -5316,6 +5272,90 @@ bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const return !(*this == other); } + +namespace { + +const std::map exif_keys = { + {"Copyright", "Exif.Image.Copyright"}, + {"Artist", "Exif.Image.Artist"}, + {"ImageDescription", "Exif.Image.ImageDescription"}, + {"Exif.UserComment", "Exif.Photo.UserComment"}, + {"ISOSpeed", "Exif.Photo.ISOSpeedRatings"}, + {"FNumber", "Exif.Photo.FNumber"}, + {"ShutterSpeed", "Exif.Photo.ExposureTime"}, + {"FocalLength", "Exif.Photo.FocalLength"}, + {"ExpComp", "Exif.Photo.ExposureBiasValue"}, + {"Flash", "Exif.Photo.Flash"}, + {"Make", "Exif.Image.Make"}, + {"Model", "Exif.Image.Model"}, + {"Lens", "Exif.Photo.LensModel"}, + {"DateTime", "Exif.Photo.DateTimeOriginal"} +}; + +const std::map iptc_keys = { + {"Title", "Iptc.Application2.ObjectName"}, + {"Category", "Iptc.Application2.Category"}, + {"SupplementalCategories", "Iptc.Application2.SuppCategory"}, + {"Keywords", "Iptc.Application2.Keywords"}, + {"Instructions", "Iptc.Application2.SpecialInstructions"}, + {"DateCreated", "Iptc.Application2.DateCreated"}, + {"Creator", "Iptc.Application2.Byline"}, + {"CreatorJobTitle", "Iptc.Application2.BylineTitle"}, + {"City", "Iptc.Application2.City"}, + {"Province", "Iptc.Application2.ProvinceState"}, + {"Country", "Iptc.Application2.CountryName"}, + {"TransReference", "Iptc.Application2.TransmissionReference"}, + {"Headline", "Iptc.Application2.Headline"}, + {"Credit", "Iptc.Application2.Credit"}, + {"Source", "Iptc.Application2.Source"}, + {"Copyright", "Iptc.Application2.Copyright"}, + {"Caption", "Iptc.Application2.Caption"}, + {"CaptionWriter", "Iptc.Application2.Writer"} +}; + +} // namespace + + +std::vector MetaDataParams::basicExifKeys = { + "Exif.Image.Copyright", + "Exif.Image.Artist", + "Exif.Image.ImageDescription", + "Exif.Photo.UserComment", + "Exif.Image.Make", + "Exif.Image.Model", + "Exif.Photo.LensModel", + "Exif.Photo.FNumber", + "Exif.Photo.ExposureTime", + "Exif.Photo.FocalLength", + "Exif.Photo.ISOSpeedRatings", + "Exif.Photo.ExposureBiasValue", + "Exif.Photo.Flash", + "Exif.Photo.DateTimeOriginal" +}; + + +MetaDataParams::MetaDataParams(): + mode(MetaDataParams::TUNNEL), + exifKeys{"*"}, + exif{}, + iptc{} +{ +} + +bool MetaDataParams::operator==(const MetaDataParams &other) const +{ + return mode == other.mode + && exifKeys == other.exifKeys + && exif == other.exif + && iptc == other.iptc; +} + +bool MetaDataParams::operator!=(const MetaDataParams &other) const +{ + return !(*this == other); +} + + ProcParams::ProcParams() { setDefaults(); @@ -5414,8 +5454,8 @@ void ProcParams::setDefaults() raw = {}; metadata = {}; - exif.clear(); - iptc.clear(); + //exif.clear(); + //iptc.clear(); // -1 means that there's no pp3 data with rank yet. In this case, the // embedded Rating metadata should take precedence. -1 should never be @@ -6876,10 +6916,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo for (auto &p : exif_keys) { m[p.second] = p.first; } - for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { - auto it = m.find(i->first); + for (auto &p : metadata.exif) { + auto it = m.find(p.first); if (it != m.end()) { - keyFile.set_string("Exif", it->second, i->second); + keyFile.set_string("Exif", it->second, p.second); } } } @@ -6890,10 +6930,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo for (auto &p : iptc_keys) { m[p.second] = p.first; } - for (IPTCPairs::const_iterator i = iptc.begin(); i != iptc.end(); ++i) { - auto it = m.find(i->first); + for (auto &p : metadata.iptc) { + auto it = m.find(p.first); if (it != m.end()) { - Glib::ArrayHandle values = i->second; + Glib::ArrayHandle values = p.second; keyFile.set_string_list("IPTC", it->second, values); } } @@ -9383,7 +9423,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) for (const auto& key : keyFile.get_keys("Exif")) { auto it = exif_keys.find(key); if (it != exif_keys.end()) { - exif[it->second] = keyFile.get_string("Exif", key); + metadata.exif[it->second] = keyFile.get_string("Exif", key); if (pedited) { pedited->exif = true; @@ -9413,16 +9453,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } auto kk = it->second; - const IPTCPairs::iterator element = iptc.find(kk); + const IPTCPairs::iterator element = metadata.iptc.find(kk); - if (element != iptc.end()) { + if (element != metadata.iptc.end()) { // it already exist so we cleanup the values element->second.clear(); } // TODO: look out if merging Keywords and SupplementalCategories from the procparams chain would be interesting for (const auto& currLoadedTagValue : keyFile.get_string_list("IPTC", key)) { - iptc[kk].push_back(currLoadedTagValue); + metadata.iptc[kk].push_back(currLoadedTagValue); } if (pedited) { @@ -9500,8 +9540,6 @@ bool ProcParams::operator ==(const ProcParams& other) const && rgbCurves == other.rgbCurves && colorToning == other.colorToning && metadata == other.metadata - && exif == other.exif - && iptc == other.iptc && dehaze == other.dehaze && filmNegative == other.filmNegative; } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index dd6872630..d874a9b13 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1718,25 +1718,6 @@ struct ColorManagementParams { bool operator !=(const ColorManagementParams& other) const; }; -/** - * Parameters for metadata handling - */ -struct MetaDataParams { - enum Mode { - TUNNEL, - EDIT, - STRIP - }; - Mode mode; - std::vector exifKeys; - - MetaDataParams(); - - bool operator ==(const MetaDataParams &other) const; - bool operator !=(const MetaDataParams &other) const; -}; - - /** * Minimal wrapper allowing forward declaration for representing a key/value for the exif metadata information */ @@ -1841,6 +1822,29 @@ private: std::map> pairs; }; +/** + * Parameters for metadata handling + */ +struct MetaDataParams { + enum Mode { + TUNNEL, + EDIT, + STRIP + }; + Mode mode; + std::vector exifKeys; + ExifPairs exif; + IPTCPairs iptc; + + MetaDataParams(); + + bool operator ==(const MetaDataParams &other) const; + bool operator !=(const MetaDataParams &other) const; + + static std::vector basicExifKeys; +}; + + struct WaveletParams { std::vector ccwcurve; std::vector wavdenoise; @@ -2355,8 +2359,8 @@ public: int ppVersion; ///< Version of the PP file from which the parameters have been read MetaDataParams metadata; ///< Metadata parameters - ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image - IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image + // ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image + // IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image /** * The constructor only sets the hand-wired defaults. diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index c8ee5e147..ef5592074 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1737,9 +1737,9 @@ private: readyImg->setMetadata(std::move(info)); break; case MetaDataParams::EDIT: - info.setExif(params.exif); - info.setIptc(params.iptc); - if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "ALL")) { + 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)); diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index ba612f615..a130a09b8 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -34,15 +34,12 @@ using namespace rtengine::procparams; ExifPanel::ExifPanel() : idata(nullptr), changeList(new rtengine::procparams::ExifPairs), - defChangeList(new rtengine::procparams::ExifPairs), - editableTags{ - {"Exif.Photo.UserComment", "User Comment"}, - {"Exif.Image.Artist", "Artist"}, - {"Exif.Image.Copyright", "Copyright"}, - {"Exif.Image.ImageDescription", "Image Description"}, - { "Exif.Photo.LensModel", "Lens Model" } - } + defChangeList(new rtengine::procparams::ExifPairs) { + for (auto &k : MetaDataParams::basicExifKeys) { + editableTags.push_back(std::make_pair(k, "")); + } + set_orientation(Gtk::ORIENTATION_VERTICAL); exifTree = Gtk::manage (new Gtk::TreeView()); scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); @@ -60,11 +57,29 @@ ExifPanel::ExifPanel() : exifTreeModel = Gtk::TreeStore::create(exifColumns); exifTree->set_model(exifTreeModel); exifTree->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE); - //exifTree->set_show_expanders(false); + exifTree->set_show_expanders(false); exifTree->set_tooltip_column(0); + exifTree->set_enable_search(false); - keepicon = RTImage::createPixbufFromFile ("tick-small.png"); - editicon = RTImage::createPixbufFromFile("add-small.png"); + //keepicon = RTImage::createPixbufFromFile("tick-small.png"); + editicon = RTImage::createPixbufFromFile("edit-small.png"); + open_icon_ = RTImage::createPixbufFromFile("expander-open-small.png"); + closed_icon_ = RTImage::createPixbufFromFile("expander-closed-small.png"); + + exif_active_renderer_.property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + exif_active_renderer_.signal_toggled().connect(sigc::mem_fun(this, &ExifPanel::onKeyActiveToggled)); + exif_active_column_.pack_start(exif_active_renderer_); + exif_active_column_.set_cell_data_func(exif_active_renderer_, sigc::mem_fun(this, &ExifPanel::setKeyActive)); + + exifTree->append_column(exif_active_column_); + + // { + // Gtk::TreeView::Column *c = Gtk::manage(new Gtk::TreeView::Column("")); + // Gtk::CellRendererPixbuf *pb = Gtk::manage(new Gtk::CellRendererPixbuf()); + // c->pack_start(*pb, false); + // c->add_attribute(*pb, "pixbuf", exifColumns.expander_icon); + // exifTree->append_column(*c); + // } Gtk::TreeView::Column *viewcol = Gtk::manage (new Gtk::TreeView::Column ("Field Name")); Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ()); @@ -85,15 +100,8 @@ ExifPanel::ExifPanel() : render_pb->property_yalign() = 0; render_txt->property_yalign() = 0; - exif_active_renderer_.property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; - exif_active_renderer_.signal_toggled().connect(sigc::mem_fun(this, &ExifPanel::onKeyActiveToggled)); - exif_active_column_.pack_start(exif_active_renderer_); - exif_active_column_.set_cell_data_func(exif_active_renderer_, sigc::mem_fun(this, &ExifPanel::setKeyActive)); - - exifTree->append_column(exif_active_column_); - exifTree->append_column(*viewcol); - exifTree->set_expander_column(*viewcol); + //exifTree->set_expander_column(*viewcol); Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); @@ -131,14 +139,14 @@ ExifPanel::ExifPanel() : activate_all_ = addbtn("EXIFPANEL_ACTIVATE_ALL_HINT", "tick.png"); activate_none_ = addbtn("EXIFPANEL_ACTIVATE_NONE_HINT", "box.png"); - add = addbtn("EXIFPANEL_ADDEDIT", "add.png"); + add = addbtn("EXIFPANEL_ADDEDIT", "edit.png"); reset = addbtn("EXIFPANEL_RESETHINT", "undo.png", "redo.png"); resetAll = addbtn("EXIFPANEL_RESETALLHINT", "undo-all.png", "redo-all.png"); pack_end (*buttons1, Gtk::PACK_SHRINK); exifTree->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ExifPanel::exifSelectionChanged)); - // exifTree->signal_row_activated().connect (sigc::mem_fun (*this, &ExifPanel::row_activated)); + exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowActivated)); reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) ); resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) ); @@ -146,6 +154,10 @@ ExifPanel::ExifPanel() : activate_all_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateAllPressed)); activate_none_->signal_clicked().connect(sigc::mem_fun(*this, &ExifPanel::activateNonePressed)); + exifTree->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &ExifPanel::onExifTreeClick)); + exifTree->signal_row_expanded().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowExpanded)); + exifTree->signal_row_collapsed().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowCollapsed)); + show_all (); } @@ -157,7 +169,7 @@ void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { disableListener(); - *changeList = pp->exif; + *changeList = pp->metadata.exif; initial_active_keys_.clear(); initial_active_keys_.insert(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end()); cur_active_keys_ = initial_active_keys_; @@ -170,54 +182,15 @@ void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) { - pp->exif = *changeList; - - std::unordered_set prev; - bool all_active = (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "ALL"); - - if (!all_active) { - prev = cur_active_keys_; - } - - pp->metadata.exifKeys.clear(); - - bool none_active = true; - - auto root = exifTreeModel->children(); - // for (auto &entry : root->children()) { - // Glib::ustring key = entry[exifColumns.key]; - // prev.erase(key); - // if (entry[exifColumns.active]) { - // pp->metadata.exifKeys.push_back(key); - // none_active = false; - // } else { - // all_active = false; - // } - // } - for (auto &group : root->children()) { - for (auto &entry : group.children()) { - std::string key = entry[exifColumns.key]; - prev.erase(key); - if (entry[exifColumns.active]) { - pp->metadata.exifKeys.push_back(key); - none_active = false; - } else { - all_active = false; - } - } - } - - if (all_active) { - pp->metadata.exifKeys = { "ALL" }; - } else if (!none_active) { - pp->metadata.exifKeys.insert(pp->metadata.exifKeys.end(), prev.begin(), prev.end()); - } + pp->metadata.exif = *changeList; + cur_active_keys_ = get_active_keys(); + pp->metadata.exifKeys.assign(cur_active_keys_.begin(), cur_active_keys_.end()); std::sort(pp->metadata.exifKeys.begin(), pp->metadata.exifKeys.end()); } void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { - *defChangeList = defParams->exif; + *defChangeList = defParams->metadata.exif; } void ExifPanel::setImageData (const FramesMetaData* id) @@ -240,11 +213,13 @@ void ExifPanel::addTag(const std::string &key, const std::pairchildren(); - for (auto it = root.rbegin(), end = root.rend(); it != end; ++it) { - auto row = *it; + // for (auto it = root.rbegin(), end = root.rend(); it != end; ++it) { + // auto row = *it; + for (auto &row : root) { + // auto row = *it; std::string key = row[exifColumns.key]; if (row[exifColumns.is_group] && key == label.first) { - return it->children(); + return row./*it->*/children(); } } auto it = exifTreeModel->append(root); @@ -253,7 +228,7 @@ void ExifPanel::addTag(const std::string &key, const std::pair"; + row[exifColumns.label] = "" + label.first + ""; row[exifColumns.value_nopango] = ""; row[exifColumns.value] = ""; row[exifColumns.is_group] = true; @@ -275,13 +250,13 @@ void ExifPanel::addTag(const std::string &key, const std::pair Glib::ustring @@ -338,6 +314,9 @@ void ExifPanel::refreshTags() return "(Not shown)"; }; + if (const rtengine::FramesData *fd = dynamic_cast(idata)) { + fd->fillBasicTags(exif); + } for (const auto& p : *changeList) { try { @@ -346,12 +325,18 @@ void ExifPanel::refreshTags() } } - for (const auto& p : editableTags) { - const auto pos = exif.findKey(Exiv2::ExifKey(p.first)); + for (auto& p : editableTags) { + Exiv2::ExifKey k(p.first); + const auto pos = exif.findKey(k); + bool edited = false; + Glib::ustring value = ""; + auto lbl = std::make_pair(M("EXIFPANEL_BASIC_GROUP"), k.tagLabel()); + p.second = k.tagLabel(); if (pos != exif.end() && pos->size()) { - const bool edited = changeList->find(pos->key()) != changeList->end(); - addTag(pos->key(), to_label(*pos), pos->print(&exif), true, edited); + edited = changeList->find(pos->key()) != changeList->end(); + value = pos->print(&exif); } + addTag(p.first, lbl, value, true, edited); } std::set keyset; for (const auto& tag : exif) { @@ -406,6 +391,7 @@ void ExifPanel::resetIt(const Gtk::TreeModel::const_iterator& iter) void ExifPanel::resetPressed() { + cur_active_keys_ = get_active_keys(); std::vector sel = exifTree->get_selection()->get_selected_rows(); @@ -490,10 +476,13 @@ void ExifPanel::addPressed () hb2->show (); if (dialog->run () == Gtk::RESPONSE_OK) { + cur_active_keys_ = get_active_keys(); auto key = editableTags[tcombo->get_active_row_number()].first; const auto value = ventry->get_text(); (*changeList)[key] = value; - cur_active_keys_.insert(key); + if (!all_keys_active()) { + cur_active_keys_.insert(key); + } refreshTags(); notifyListener(); } @@ -556,6 +545,11 @@ void ExifPanel::onKeyActiveToggled(const Glib::ustring &path) for (auto &c : row.children()) { c[exifColumns.active] = b; } + } else if (!b) { + it = row.parent(); + if (it) { + (*it)[exifColumns.active] = b; + } } notifyListener(); } @@ -568,3 +562,78 @@ void ExifPanel::setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel:: static_cast(renderer)->set_active(row[exifColumns.active]); } + +bool ExifPanel::all_keys_active() const +{ + return (cur_active_keys_.size() == 1 && *(cur_active_keys_.begin()) == "*"); +} + + +std::unordered_set ExifPanel::get_active_keys() const +{ + bool all_active = true; + std::unordered_set ret; + auto root = exifTreeModel->children(); + for (auto &group : root->children()) { + for (auto &entry : group.children()) { + std::string key = entry[exifColumns.key]; + if (entry[exifColumns.active]) { + ret.insert(key); + } else { + all_active = false; + } + } + } + if (all_active) { + ret.clear(); + ret.insert("*"); + } + return ret; +} + +void ExifPanel::onExifTreeClick(GdkEventButton *event) +{ + Gtk::TreeModel::Path pth; + Gtk::TreeViewColumn *col; + int cell_x; + int cell_y; + if (exifTree->get_path_at_pos(event->x, event->y, pth, col, cell_x, cell_y) && col == exifTree->get_column(1) && cell_x <= 22) { + auto it = exifTreeModel->get_iter(pth); + auto row = *it; + if (row[exifColumns.is_group]) { + if (exifTree->row_expanded(pth)) { + exifTree->collapse_row(pth); + } else { + exifTree->expand_row(pth, false); + } + } + } +} + + +void ExifPanel::onExifRowExpanded(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path) +{ + auto row = *it; + if (row[exifColumns.is_group]) { + row[exifColumns.icon] = open_icon_; + } +} + + +void ExifPanel::onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path) +{ + auto row = *it; + if (row[exifColumns.is_group]) { + row[exifColumns.icon] = closed_icon_; + } +} + + +void ExifPanel::onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) +{ + auto it = exifTreeModel->get_iter(path); + auto row = *it; + if (row[exifColumns.editable]) { + addPressed(); + } +} diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 32ce10dc7..da4cc1e37 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -50,7 +50,8 @@ private: class ExifColumns : public Gtk::TreeModelColumnRecord { public: - Gtk::TreeModelColumn > icon; + // Gtk::TreeModelColumn> expander_icon; + Gtk::TreeModelColumn> icon; Gtk::TreeModelColumn key; Gtk::TreeModelColumn label; Gtk::TreeModelColumn value; @@ -71,10 +72,13 @@ private: add(editable); add(active); add(is_group); + // add(expander_icon); } }; - Glib::RefPtr keepicon; + //Glib::RefPtr keepicon; Glib::RefPtr editicon; + Glib::RefPtr open_icon_; + Glib::RefPtr closed_icon_; ExifColumns exifColumns; Gtk::TreeView* exifTree; @@ -90,7 +94,7 @@ private: Gtk::CellRendererToggle exif_active_renderer_; Gtk::TreeView::Column exif_active_column_; - const std::vector> editableTags; + std::vector> editableTags; std::unordered_set initial_active_keys_; std::unordered_set cur_active_keys_; @@ -106,7 +110,14 @@ private: void setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it); void onKeyActiveToggled(const Glib::ustring &path); - + + bool all_keys_active() const; + std::unordered_set get_active_keys() const; + + void onExifTreeClick(GdkEventButton *event); + void onExifRowExpanded(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path); + void onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path); + void onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column); public: ExifPanel (); diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index f476e7513..bee7ec74a 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -467,8 +467,8 @@ void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) disableListener (); changeList->clear(); - if (!pp->iptc.empty()) { - *changeList = pp->iptc; + if (!pp->metadata.iptc.empty()) { + *changeList = pp->metadata.iptc; } else { *changeList = *embeddedData; } @@ -480,13 +480,13 @@ void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited) { - pp->iptc = *changeList; + pp->metadata.iptc = *changeList; } void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { - *defChangeList = defParams->iptc; + *defChangeList = defParams->metadata.iptc; } void IPTCPanel::setImageData (const FramesMetaData* id) diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 8459d4013..98abe2869 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -6612,15 +6612,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng // Exif changes are added to the existing ones if (exif) { - for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { - toEdit.exif[i->first] = i->second; + for (procparams::ExifPairs::const_iterator i = mods.metadata.exif.begin(); i != mods.metadata.exif.end(); ++i) { + toEdit.metadata.exif[i->first] = i->second; } } // IPTC changes are added to the existing ones if (iptc) { - for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); ++i) { - toEdit.iptc[i->first] = i->second; + for (procparams::IPTCPairs::const_iterator i = mods.metadata.iptc.begin(); i != mods.metadata.iptc.end(); ++i) { + toEdit.metadata.iptc[i->first] = i->second; } } } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index ce5138d28..dfc1bfeb7 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -1215,7 +1215,7 @@ void Thumbnail::saveMetadata() return; } - if (pparams->exif.empty() && pparams->iptc.empty()) { + if (pparams->metadata.exif.empty() && pparams->metadata.iptc.empty()) { return; } @@ -1224,8 +1224,8 @@ void Thumbnail::saveMetadata() auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname); rtengine::Exiv2Metadata meta; meta.xmpData() = std::move(xmp); - meta.setExif(pparams->exif); - meta.setIptc(pparams->iptc); + meta.setExif(pparams->metadata.exif); + meta.setIptc(pparams->metadata.iptc); meta.saveToXmp(fn); if (options.rtSettings.verbose) { std::cout << "saved edited metadata for " << fname << " to " diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 920585aed..fde949606 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -141,7 +141,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); @@ -187,7 +187,7 @@ 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++) { @@ -585,8 +585,8 @@ void ToolPanelCoordinator::profileChange( // Reset IPTC values when switching procparams from the History if (event == rtengine::EvHistoryBrowsed) { - mergedParams->iptc.clear(); - mergedParams->exif.clear(); + mergedParams->metadata.iptc.clear(); + mergedParams->metadata.exif.clear(); } // And apply the partial profile nparams to mergedParams From 1935f3d76d583d5ca082fc7e1580ed27b918189a Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 10 Apr 2020 06:47:13 -0700 Subject: [PATCH 102/326] exif panel: ensure that keys are not empty in the displayed tag tree (cherry picked from commit da45bf30bddf311b6c7d0d990d078b2a37d4b500) --- rtdata/languages/default | 1 + rtgui/exifpanel.cc | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a5ce4fa54..1b625bdac 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -78,6 +78,7 @@ EXIFPANEL_RESETALL;Reset All EXIFPANEL_RESETALLHINT;Reset all tags to their original values. EXIFPANEL_RESETHINT;Reset the selected tags to their original values. EXIFPANEL_BASIC_GROUP;Basic +EXIFPANEL_VALUE_NOT_SHOWN;Not shown EXPORT_BYPASS;Processing steps to bypass EXPORT_BYPASS_ALL;Select / Unselect All EXPORT_BYPASS_DEFRINGE;Bypass Defringe diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index a130a09b8..4957cc0b6 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -293,9 +293,12 @@ void ExifPanel::refreshTags() pos = s.find('.'); if (pos != std::string::npos) { g = s.substr(0, pos); - // s = s.substr(pos+1); + s = s.substr(pos+1); + } + auto l = tag.tagLabel(); + if (!l.empty()) { + s = l; } - s = tag.tagLabel(); return std::make_pair(g, Glib::ustring(s)); }; @@ -311,7 +314,7 @@ void ExifPanel::refreshTags() (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { return escapeHtmlChars(tag.print(&exif)); } - return "(Not shown)"; + return "(" + M("EXIFPANEL_VALUE_NOT_SHOWN") + ")"; }; if (const rtengine::FramesData *fd = dynamic_cast(idata)) { @@ -338,7 +341,24 @@ void ExifPanel::refreshTags() } addTag(p.first, lbl, value, true, edited); } - std::set keyset; + struct KeyLt { + bool operator()(const std::string &a, const std::string &b) const + { + auto p1 = a.find_last_of('.'); + auto p2 = b.find_last_of('.'); + const char *sa = a.c_str(); + const char *sb = b.c_str(); + if (p1 != std::string::npos && p2 != std::string::npos) { + bool hex_a = strncmp(sa+p1+1, "0x", 2) == 0; + bool hex_b = strncmp(sb+p2+1, "0x", 2) == 0; + if (hex_a != hex_b) { + return !hex_a; + } + } + return strcmp(sa, sb) < 0; + } + }; + std::set keyset; for (const auto& tag : exif) { const bool editable = ed.find(tag.key()) != ed.end(); if (!editable) { From e9705620551aae8edd66d3172273b8f51a61301b Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 11 Apr 2020 00:31:55 +0200 Subject: [PATCH 103/326] metadata: check for "Exif.Photo.ExposureBiasValue" in addition to "Exif.Image.ExposureBiasValue" for exposure compensation Fixes #49 (cherry picked from commit a7cb9add3453c581347e738110461f0af15cb1cb) --- rtengine/imagedata.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 52a9fa297..fac34ba76 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -321,6 +321,8 @@ FramesData::FramesData(const Glib::ustring &fname) : if (find_exif_tag("Exif.Image.ExposureBiasValue")) { expcomp = pos->toFloat(); + } else if (find_exif_tag("Exif.Photo.ExposureBiasValue")) { + expcomp = pos->toFloat(); } if (find_exif_tag("Exif.Image.Rating")) { From a9aa17f153cf8a64c2f89af773098ef255fa9050 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 11 Apr 2020 00:45:49 +0200 Subject: [PATCH 104/326] metadata: small tweaks to expcomp and fnumber default values in "apply changes" mode (cherry picked from commit af20ad37cceb3b4bf0a01e46b5cec023d4170300) --- rtengine/imagedata.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index fac34ba76..d8cec7604 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -721,11 +721,10 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const return; } set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed()); - set_exif(exif, "Exif.Photo.FNumber", Exiv2::DoubleValue(getFNumber())); - //set_exif(exif, "Exif.Photo.ExposureTime", Exiv2::DoubleValue(getShutterSpeed())); + set_exif(exif, "Exif.Photo.FNumber", apertureToString(getFNumber())); set_exif(exif, "Exif.Photo.ExposureTime", shutterToString(getShutterSpeed())); set_exif(exif, "Exif.Photo.FocalLength", Exiv2::DoubleValue(getFocalLen())); - set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(getExpComp())); + set_exif(exif, "Exif.Photo.ExposureBiasValue", expcompToString(getExpComp(), false)); set_exif(exif, "Exif.Image.Make", getMake()); set_exif(exif, "Exif.Image.Model", getModel()); set_exif(exif, "Exif.Photo.LensModel", getLens()); From 1de9516ef0ec43f1c49359bc8f648ba7b34e9a22 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 11 Apr 2020 02:50:49 -0700 Subject: [PATCH 105/326] metadata: better defaults and presentation of the exif tag tree (cherry picked from commit 9edc783c1b6ba3b49c933560a73e2de126e04dc1) --- rtengine/procparams.cc | 8 ++++-- rtgui/exifpanel.cc | 63 ++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 06ea2be6a..d5cc7b45b 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -5335,13 +5335,15 @@ std::vector MetaDataParams::basicExifKeys = { MetaDataParams::MetaDataParams(): - mode(MetaDataParams::TUNNEL), - exifKeys{"*"}, + mode(MetaDataParams::EDIT), + exifKeys{}, exif{}, iptc{} { + exifKeys = basicExifKeys; } + bool MetaDataParams::operator==(const MetaDataParams &other) const { return mode == other.mode @@ -9409,7 +9411,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("MetaData")) { - int mode = int(MetaDataParams::TUNNEL); + int mode = int(MetaDataParams::EDIT); assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) { diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 4957cc0b6..05d69f6e3 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -73,14 +73,6 @@ ExifPanel::ExifPanel() : exifTree->append_column(exif_active_column_); - // { - // Gtk::TreeView::Column *c = Gtk::manage(new Gtk::TreeView::Column("")); - // Gtk::CellRendererPixbuf *pb = Gtk::manage(new Gtk::CellRendererPixbuf()); - // c->pack_start(*pb, false); - // c->add_attribute(*pb, "pixbuf", exifColumns.expander_icon); - // exifTree->append_column(*c); - // } - Gtk::TreeView::Column *viewcol = Gtk::manage (new Gtk::TreeView::Column ("Field Name")); Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ()); Gtk::CellRendererText *render_txt = Gtk::manage (new Gtk::CellRendererText()); @@ -310,7 +302,7 @@ void ExifPanel::refreshTags() const auto to_value = [&](Exiv2::Exifdatum &tag) -> Glib::ustring { - if (!tag.tagLabel().empty() && tag.typeId() != Exiv2::undefined && + if (!tag.tagLabel().empty() && //tag.typeId() != Exiv2::undefined && (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { return escapeHtmlChars(tag.print(&exif)); } @@ -342,6 +334,13 @@ void ExifPanel::refreshTags() addTag(p.first, lbl, value, true, edited); } struct KeyLt { + KeyLt(): + order_{ + {"Exif.GPSInfo", 0}, + {"Exif.Photo", 1}, + {"Exif.Image", 2} + } + {} bool operator()(const std::string &a, const std::string &b) const { auto p1 = a.find_last_of('.'); @@ -355,8 +354,28 @@ void ExifPanel::refreshTags() return !hex_a; } } + if (p1 != p2 || strncmp(sa, sb, p1) != 0) { + std::string ga(sa, sa+p1); + std::string gb(sb, sb+p2); + int ia = getorder(ga); + int ib = getorder(gb); + if (ia != ib) { + return ia < ib; + } + } return strcmp(sa, sb) < 0; } + + int getorder(const std::string &key) const + { + auto it = order_.find(key); + if (it == order_.end()) { + return 1000; + } + return it->second; + } + + std::unordered_map order_; }; std::set keyset; for (const auto& tag : exif) { @@ -565,11 +584,6 @@ void ExifPanel::onKeyActiveToggled(const Glib::ustring &path) for (auto &c : row.children()) { c[exifColumns.active] = b; } - } else if (!b) { - it = row.parent(); - if (it) { - (*it)[exifColumns.active] = b; - } } notifyListener(); } @@ -579,7 +593,26 @@ void ExifPanel::onKeyActiveToggled(const Glib::ustring &path) void ExifPanel::setKeyActive(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it) { auto row = *it; - static_cast(renderer)->set_active(row[exifColumns.active]); + Gtk::CellRendererToggle *toggle = static_cast(renderer); + if (row[exifColumns.is_group]) { + bool all_true = true, all_false = true; + for (auto &c : row.children()) { + if (c[exifColumns.active]) { + all_false = false; + } else { + all_true = false; + } + } + if (!all_true && !all_false) { + toggle->property_inconsistent() = true; + } else { + toggle->property_inconsistent() = false; + toggle->set_active(all_true); + } + } else { + toggle->property_inconsistent() = false; + toggle->set_active(row[exifColumns.active]); + } } From 3f0556454893610812b059b291bba5a268ed2173 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 14 Apr 2020 00:05:30 -0700 Subject: [PATCH 106/326] exifpanel: fixed missing markup escaping when adding tag values Fixes #54 (cherry picked from commit 383619d6260fa10b8f112e3dc55e0323f5e99b43) --- rtgui/exifpanel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 05d69f6e3..bcc95bfd0 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -329,7 +329,7 @@ void ExifPanel::refreshTags() p.second = k.tagLabel(); if (pos != exif.end() && pos->size()) { edited = changeList->find(pos->key()) != changeList->end(); - value = pos->print(&exif); + value = escapeHtmlChars(pos->print(&exif)); } addTag(p.first, lbl, value, true, edited); } From 7c9726ddbe1ae91fb07b40c768c84883c2148998 Mon Sep 17 00:00:00 2001 From: David Hunt Date: Tue, 14 Apr 2020 00:11:03 -0700 Subject: [PATCH 107/326] metadata: use std::unique_ptr instead of Exiv2::Image::AutoPtr Fixes #55 (cherry picked from commit 9466fc133f1af465a784a7384cf0369d7c35b901) --- rtengine/metadata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index d04b979fe..884c8a9a1 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -52,7 +52,7 @@ private: constexpr size_t IMAGE_CACHE_SIZE = 200; -Exiv2::Image::AutoPtr open_exiv2(const Glib::ustring& fname) +std::unique_ptr open_exiv2(const Glib::ustring& fname) { #ifdef EXV_UNICODE_PATH glong ws_size = 0; From 38eb9f9f187aad17c37d43e3d6a469b1cd14b487 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 14 Apr 2020 05:36:40 -0700 Subject: [PATCH 108/326] exifpanel: improved ui for editing tags (cherry picked from commit f6f4ddf54c25e6e577bf4960ea51fc23e8434559) --- rtgui/exifpanel.cc | 144 +++++++++++++++------------------------------ rtgui/exifpanel.h | 4 +- 2 files changed, 51 insertions(+), 97 deletions(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index bcc95bfd0..c44a4f8d2 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -48,7 +48,7 @@ ExifPanel::ExifPanel() : exifTree->set_rules_hint (false); exifTree->set_reorderable (false); exifTree->set_enable_search (false); - exifTree->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + exifTree->get_selection()->set_mode(Gtk::SELECTION_SINGLE); scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); @@ -99,7 +99,7 @@ ExifPanel::ExifPanel() : Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); render_txtv->property_ellipsize() = Pango::ELLIPSIZE_END; viewcolv->pack_start (*render_txtv, true); - viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); + // viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); viewcolv->set_expand (true); viewcolv->set_resizable (true); viewcol->set_fixed_width (35); @@ -107,6 +107,8 @@ ExifPanel::ExifPanel() : viewcolv->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE); render_txtv->property_ypad() = 0; + viewcolv->set_cell_data_func(*render_txtv, sigc::mem_fun(this, &ExifPanel::setExifTagValue)); + render_txtv->signal_edited().connect(sigc::mem_fun(this, &ExifPanel::onEditExifTagValue)); exifTree->append_column(*viewcolv); @@ -138,7 +140,6 @@ ExifPanel::ExifPanel() : pack_end (*buttons1, Gtk::PACK_SHRINK); exifTree->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ExifPanel::exifSelectionChanged)); - exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::onExifRowActivated)); reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) ); resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) ); @@ -401,20 +402,18 @@ void ExifPanel::refreshTags() void ExifPanel::exifSelectionChanged () { - Glib::RefPtr selection = exifTree->get_selection(); std::vector sel = selection->get_selected_rows(); - if (sel.size() > 1) { - reset->set_sensitive (1); - } else if (sel.size() == 1) { + if (sel.size() >= 1) { Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (sel[0]); - - if (iter->get_value(exifColumns.icon) == editicon) { - reset->set_sensitive (1); + if (iter->get_value(exifColumns.editable)) { + reset->set_sensitive(true); + add->set_sensitive(true); } } else { - reset->set_sensitive (0); + reset->set_sensitive(false); + add->set_sensitive(false); } } @@ -432,107 +431,43 @@ void ExifPanel::resetPressed() { cur_active_keys_ = get_active_keys(); - std::vector sel = exifTree->get_selection()->get_selected_rows(); - + auto sel = exifTree->get_selection()->get_selected_rows(); for (size_t i = 0; i < sel.size(); i++) { resetIt(exifTreeModel->get_iter(sel[i])); } refreshTags(); + + if (!sel.empty()) { + exifTree->get_selection()->select(sel[0]); + } + notifyListener(); } -void ExifPanel::resetAllPressed () +void ExifPanel::resetAllPressed() { + auto sel = exifTree->get_selection()->get_selected_rows(); setImageData(idata); *changeList = *defChangeList; cur_active_keys_ = initial_active_keys_; refreshTags(); + if (!sel.empty()) { + exifTree->get_selection()->select(sel[0]); + } notifyListener(); } -void ExifPanel::addPressed () +void ExifPanel::addPressed() { + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn *col; - Gtk::Dialog* dialog = new Gtk::Dialog (M ("EXIFPANEL_ADDTAGDLG_TITLE"), * ((Gtk::Window*)get_toplevel()), true); - dialog->add_button ("_OK", Gtk::RESPONSE_OK); - dialog->add_button ("_Cancel", Gtk::RESPONSE_CANCEL); - - Gtk::Box* hb1 = new Gtk::Box (); - Gtk::Box* hb2 = new Gtk::Box (); - - Gtk::Label* tlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_SELECTTAG") + ":"); - MyComboBoxText* tcombo = new MyComboBoxText (); - - for (const auto& p : editableTags) { - tcombo->append(p.second); + exifTree->get_cursor(path, col); + const auto it = exifTreeModel->get_iter(path); + if (it && it->get_value(exifColumns.editable)) { + exifTree->set_cursor(path, *col, true); } - - hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4); - hb1->pack_start (*tcombo); - - Gtk::Label* vlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_ENTERVALUE") + ":"); - Gtk::Entry* ventry = new Gtk::Entry (); - hb2->pack_start (*vlabel, Gtk::PACK_SHRINK, 4); - hb2->pack_start (*ventry); - - Glib::ustring sel; - Glib::ustring val; - { - const Glib::RefPtr selection = exifTree->get_selection(); - const std::vector rows = selection->get_selected_rows(); - - if (rows.size() == 1) { - const Gtk::TreeModel::iterator iter = exifTreeModel->get_iter(rows[0]); - if (iter->get_value(exifColumns.editable)) { - sel = iter->get_value(exifColumns.key); - val = iter->get_value(exifColumns.value_nopango); - } - } - } - - if (sel.empty()) { - tcombo->set_active(0); - } else { - for (size_t i = 0; i < editableTags.size(); ++i) { - if (editableTags[i].first == sel) { - tcombo->set_active(i); - break; - } - } - } - - ventry->set_text(val); - ventry->set_activates_default (true); - dialog->set_default_response (Gtk::RESPONSE_OK); - dialog->get_content_area()->pack_start (*hb1, Gtk::PACK_SHRINK); - dialog->get_content_area()->pack_start (*hb2, Gtk::PACK_SHRINK, 4); - tlabel->show (); - tcombo->show (); - vlabel->show (); - ventry->show (); - hb1->show (); - hb2->show (); - - if (dialog->run () == Gtk::RESPONSE_OK) { - cur_active_keys_ = get_active_keys(); - auto key = editableTags[tcombo->get_active_row_number()].first; - const auto value = ventry->get_text(); - (*changeList)[key] = value; - if (!all_keys_active()) { - cur_active_keys_.insert(key); - } - refreshTags(); - notifyListener(); - } - - delete dialog; - delete tlabel; - delete tcombo; - delete vlabel; - delete ventry; - delete hb1; - delete hb2; } void ExifPanel::activateAllPressed() @@ -682,11 +617,28 @@ void ExifPanel::onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk } -void ExifPanel::onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) +void ExifPanel::setExifTagValue(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it) +{ + auto row = *it; + Gtk::CellRendererText *txt = static_cast(renderer); + txt->property_editable() = row[exifColumns.editable]; + txt->property_markup() = row[exifColumns.value]; +} + + +void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustring &value) { auto it = exifTreeModel->get_iter(path); auto row = *it; - if (row[exifColumns.editable]) { - addPressed(); + std::string key = row[exifColumns.key]; + + changeList[key] = value; + if (!all_keys_active()) { + cur_active_keys_.insert(key); } + refreshTags(); + + it = exifTreeModel->get_iter(path); + exifTree->get_selection()->select(it); + notifyListener(); } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index da4cc1e37..261561ea0 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -117,8 +117,10 @@ private: void onExifTreeClick(GdkEventButton *event); void onExifRowExpanded(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path); void onExifRowCollapsed(const Gtk::TreeModel::iterator &it, const Gtk::TreeModel::Path &path); - void onExifRowActivated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column); + void setExifTagValue(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &it); + void onEditExifTagValue(const Glib::ustring &path, const Glib::ustring &value); + public: ExifPanel (); ~ExifPanel() override; From 30e77ee96fa83c0a593568cdcacbdedc2e6746b6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 20 Apr 2020 07:32:55 -0700 Subject: [PATCH 109/326] fixed compilation error with Apple Clang 7.0.0 (cherry picked from commit dd5b10d9dc8eb7447e37ac30ddd7545897c878b0) --- rtengine/metadata.cc | 3 ++- rtgui/exifpanel.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 884c8a9a1..732133785 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -76,7 +76,8 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname) #endif throw Exiv2::Error(error_code, "exiv2: invalid image"); } - return image; + std::unique_ptr ret(image.release()); + return ret; } } // namespace diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index c44a4f8d2..44c70bc12 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -632,7 +632,7 @@ void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustrin auto row = *it; std::string key = row[exifColumns.key]; - changeList[key] = value; + (*changeList)[key] = value; if (!all_keys_active()) { cur_active_keys_.insert(key); } From 41834c7007a2d821e61ada4eef0a2e10eea14565 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 24 Apr 2020 05:00:50 -0700 Subject: [PATCH 110/326] cmake: fix build issue on opensuse (exiv2 library not found) Fixes #64 (cherry picked from commit 33ced3e42605fcc4f69a0be03aa4df3691fa66f9) --- CMakeLists.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3630eecb..aa118e15b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ endif() # Warning for GCC 10, which causes problems #5749: if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "10.1") - 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() @@ -482,10 +482,17 @@ set(EXIV2_LIBRARIES "") foreach(l ${_exiv2_libs}) set(_el "_el-NOTFOUND") if(EXIV2_LIBRARY_DIRS) + message(STATUS "searching for library ${l} in ${EXIV2_LIBRARY_DIRS}") find_library(_el ${l} PATHS ${EXIV2_LIBRARY_DIRS} NO_DEFAULT_PATH) + if(NOT _el) + message(STATUS " NOT FOUND, searching again in default path") + find_library(_el ${l}) + endif() else() - find_library(_el ${l} PATHS ${EXIV2_LIBRARY_DIRS}) + message(STATUS "searching for library ${l}") + find_library(_el ${l})# PATHS ${EXIV2_LIBRARY_DIRS}) endif() + message(STATUS " result: ${_el}") set(EXIV2_LIBRARIES ${EXIV2_LIBRARIES} ${_el}) endforeach() @@ -709,7 +716,7 @@ elseif(APPLE) -DSYSTEM:STRING=Apple -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} - -DCOMPILER_INFO:STRING=${COMPILER_INFO}) + -DCOMPILER_INFO:STRING=${COMPILER_INFO}) else() list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Linux -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} @@ -771,14 +778,17 @@ foreach(l ${LENSFUN_LIBRARIES}) # want, and not the system's one (e.g. if we have a custom version # installed in a non-standard location) set(_l "_l-NOTFOUND") + message(STATUS "searching for library ${l} in ${LENSFUN_LIBRARY_DIRS}") find_library(_l ${l} PATHS ${LENSFUN_LIBRARY_DIRS} NO_DEFAULT_PATH) else() # LENSFUN_LIBRARY_DIRS can be empty if lensfun is installed in the # default path. In this case, adding NO_DEFAULT_PATH would make # find_library fail... set(_l "_l-NOTFOUND") + message(STATUS "searching for library ${l}") find_library(_l ${l}) endif() + message(STATUS " result: ${_l}") set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_l}) endforeach() check_cxx_source_compiles( From 62249218435ddea570322ba5353a502770a5c8a8 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 7 May 2020 09:26:13 +0200 Subject: [PATCH 111/326] metadata: workaround for misbehaviour of exiv2 on ubuntu 20.04 (cherry picked from commit 26b8860d4bb803cff0277c7b2353b58b5e02fbc6) --- rtengine/metadata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 732133785..6e2b53ed8 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -68,7 +68,7 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname) auto image = Exiv2::ImageFactory::open(Glib::filename_from_utf8(fname)); #endif image->readMetadata(); - if (!image->good()) { + if (!image->good() || image->exifData().empty()) { #if EXIV2_TEST_VERSION(0,27,0) auto error_code = Exiv2::kerErrorMessage; #else From 700eeccb393cf283076cc0617585f35d93b8bd2d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 8 May 2020 02:11:08 -0700 Subject: [PATCH 112/326] metadata: don't raise error if exif is empty when opening an image for saving Fixes #79 (regression introduced by 26b8860d4bb803cff0277c7b2353b58b5e02fbc6) (cherry picked from commit 62ae8e15b8ca07cbe545ed42c323e986448c3213) --- rtengine/metadata.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 6e2b53ed8..4c347c86c 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -52,7 +52,8 @@ private: constexpr size_t IMAGE_CACHE_SIZE = 200; -std::unique_ptr open_exiv2(const Glib::ustring& fname) +std::unique_ptr open_exiv2(const Glib::ustring& fname, + bool check_exif) { #ifdef EXV_UNICODE_PATH glong ws_size = 0; @@ -68,7 +69,7 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname) auto image = Exiv2::ImageFactory::open(Glib::filename_from_utf8(fname)); #endif image->readMetadata(); - if (!image->good() || image->exifData().empty()) { + if (!image->good() || (check_exif && image->exifData().empty())) { #if EXIV2_TEST_VERSION(0,27,0) auto error_code = Exiv2::kerErrorMessage; #else @@ -121,7 +122,7 @@ void Exiv2Metadata::load() const if (cache_ && cache_->get(src_, val) && val.second >= finfo->modification_time()) { image_ = val.first; } else { - auto img = open_exiv2(src_); + auto img = open_exiv2(src_, true); image_.reset(img.release()); if (cache_) { cache_->set(src_, CacheVal(image_, finfo->modification_time())); @@ -218,7 +219,7 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const void Exiv2Metadata::saveToImage(const Glib::ustring &path) const { - auto dst = open_exiv2(path); + auto dst = open_exiv2(path, false); if (image_.get()) { dst->setIptcData(image_->iptcData()); dst->setXmpData(image_->xmpData()); @@ -432,7 +433,7 @@ Exiv2::XmpData Exiv2Metadata::getXmpSidecar(const Glib::ustring &path) Exiv2::XmpData ret; auto fname = xmpSidecarPath(path); if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { - auto image = open_exiv2(fname); + auto image = open_exiv2(fname, false); ret = image->xmpData(); } return ret; From 6cec8057742a964d069428a2511f8e65819a2e7e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 17 May 2020 18:28:06 +0200 Subject: [PATCH 113/326] metadata: try to be more robust when saving Tentative fix for #89 (cherry picked from commit a8b53fef753c7a1146013feeb66be87c688b8631) --- rtengine/imageio.cc | 2 +- rtengine/metadata.cc | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index af945949f..4d8f93d55 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1399,7 +1399,7 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const // dst->writeMetadata(); } catch (const std::exception& exc) { std::cout << "EXIF ERROR: " << exc.what() << std::endl; - return false; + //return false; } } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 4c347c86c..0205e3134 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -238,7 +238,35 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; import_exif_pairs(dst->exifData()); import_iptc_pairs(dst->iptcData()); - dst->writeMetadata(); + bool xmp_tried = false; + bool iptc_tried = false; + for (int i = 0; i < 3; ++i) { + try { + dst->writeMetadata(); + return; + } catch (Exiv2::Error &exc) { + if (exc.code() == 37) { + std::string msg = exc.what(); + if (msg.find("XMP") != std::string::npos && + !dst->xmpData().empty()) { + dst->xmpData().clear(); + if (!xmp_tried && merge_xmp_) { + do_merge_xmp(dst.get()); + xmp_tried = true; + } + } else if (msg.find("IPTC") != std::string::npos && + !dst->iptcData().empty()) { + dst->iptcData().clear(); + if (!iptc_tried) { + import_iptc_pairs(dst->iptcData()); + iptc_tried = true; + } + } + } else { + throw exc; + } + } + } } From 0415d556fc66e528374b2fa9d194197d8ddc16d0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 20 May 2020 16:31:33 +0200 Subject: [PATCH 114/326] exifpanel: ignore errors when printing tags in human-readable form (cherry picked from commit 47fa34e7365d618f250826eb412c72fe0ab8cfed) --- rtgui/exifpanel.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 44c70bc12..136e97b6e 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -303,10 +303,12 @@ void ExifPanel::refreshTags() const auto to_value = [&](Exiv2::Exifdatum &tag) -> Glib::ustring { - if (!tag.tagLabel().empty() && //tag.typeId() != Exiv2::undefined && - (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { - return escapeHtmlChars(tag.print(&exif)); - } + try { + if (!tag.tagLabel().empty() && //tag.typeId() != Exiv2::undefined && + (tag.typeId() == Exiv2::asciiString || tag.size() < 256)) { + return escapeHtmlChars(tag.print(&exif)); + } + } catch (std::exception &) {} return "(" + M("EXIFPANEL_VALUE_NOT_SHOWN") + ")"; }; From 1e0cf4544528f224291aa504e47946c27c982e8f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 3 Jun 2020 02:47:17 -0700 Subject: [PATCH 115/326] metadata: use copyXmpTo* instead of moveXmpTo* (cherry picked from commit d3ac9618f8a3e2688f7a084419eeebbe24a76664) --- rtengine/metadata.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 0205e3134..8028e933f 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -196,8 +196,8 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const auto xmp = getXmpSidecar(src_); Exiv2::ExifData exif; Exiv2::IptcData iptc; - Exiv2::moveXmpToIptc(xmp, iptc); - Exiv2::moveXmpToExif(xmp, exif); + Exiv2::copyXmpToIptc(xmp, iptc); + Exiv2::copyXmpToExif(xmp, exif); for (auto &datum : exif) { dst->exifData()[datum.key()] = datum; From 393dbcf9f938a2554d081b8a7d0e71cc351f9901 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 4 Jun 2020 02:48:47 -0700 Subject: [PATCH 116/326] metadata: allow the user to specify XResolution/YResolution see https://discuss.pixls.us/t/note-to-the-dev-guys-about-72-ppi-output (cherry picked from commit ad237944699800368ba50151f6774ee203d61ed5) --- rtdata/languages/default | 3 ++- rtengine/procparams.cc | 8 ++++-- rtgui/editorpanel.cc | 4 ++- rtgui/exifpanel.cc | 55 ++++++++++++++++++++++++++++++++-------- rtgui/exifpanel.h | 3 +++ rtgui/metadatapanel.cc | 6 +++++ rtgui/metadatapanel.h | 2 ++ rtgui/toolpanelcoord.cc | 6 +++++ rtgui/toolpanelcoord.h | 2 ++ 9 files changed, 75 insertions(+), 14 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 1b625bdac..a0b25e0b6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -52,6 +52,7 @@ DYNPROFILEEDITOR_PROFILE;Processing Profile EDITWINDOW_TITLE;Image Edit EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 EXIFFILTER_APERTURE;Aperture EXIFFILTER_CAMERA;Camera EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) @@ -1556,7 +1557,7 @@ 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_INSPECT; Inspect MAIN_TAB_IPTC;IPTC MAIN_TAB_LOCALLAB;Local MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d5cc7b45b..f0300a011 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -5289,7 +5289,9 @@ const std::map exif_keys = { {"Make", "Exif.Image.Make"}, {"Model", "Exif.Image.Model"}, {"Lens", "Exif.Photo.LensModel"}, - {"DateTime", "Exif.Photo.DateTimeOriginal"} + {"DateTime", "Exif.Photo.DateTimeOriginal"}, + {"XResolution", "Exif.Image.XResolution"}, + {"YResolution", "Exif.Image.YResolution"} }; const std::map iptc_keys = { @@ -5330,7 +5332,9 @@ std::vector MetaDataParams::basicExifKeys = { "Exif.Photo.ISOSpeedRatings", "Exif.Photo.ExposureBiasValue", "Exif.Photo.Flash", - "Exif.Photo.DateTimeOriginal" + "Exif.Photo.DateTimeOriginal", + "Exif.Image.XResolution", + "Exif.Image.YResolution" }; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c2ad9241a..350538626 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -487,7 +487,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) firstProcessingDone = false; // construct toolpanelcoordinator - tpc = new ToolPanelCoordinator (); + tpc = new ToolPanelCoordinator(); + tpc->setProgressListener(this); // build GUI @@ -1227,6 +1228,7 @@ void EditorPanel::setProgressState(bool inProcessing) void EditorPanel::error(const Glib::ustring& descr) { + parent->error(descr); } void EditorPanel::error(const Glib::ustring& title, const Glib::ustring& descr) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 136e97b6e..719674151 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -34,7 +34,8 @@ using namespace rtengine::procparams; ExifPanel::ExifPanel() : idata(nullptr), changeList(new rtengine::procparams::ExifPairs), - defChangeList(new rtengine::procparams::ExifPairs) + defChangeList(new rtengine::procparams::ExifPairs), + pl_(nullptr) { for (auto &k : MetaDataParams::basicExifKeys) { editableTags.push_back(std::make_pair(k, "")); @@ -318,8 +319,16 @@ void ExifPanel::refreshTags() for (const auto& p : *changeList) { try { - exif[p.first] = p.second; + auto &datum = exif[p.first]; + if (datum.setValue(p.second) != 0) { + if (pl_) { + pl_->error(Glib::ustring::compose(M("ERROR_MSG_METADATA_VALUE"), p.first, p.second)); + } + } } catch (const std::exception& exc) { + if (pl_) { + pl_->error(Glib::ustring::compose(M("ERROR_MSG_METADATA_VALUE"), p.first, p.second)); + } } } @@ -628,19 +637,45 @@ void ExifPanel::setExifTagValue(Gtk::CellRenderer *renderer, const Gtk::TreeMode } -void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustring &value) +void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustring &val) { auto it = exifTreeModel->get_iter(path); auto row = *it; std::string key = row[exifColumns.key]; + auto value = val; - (*changeList)[key] = value; - if (!all_keys_active()) { - cur_active_keys_.insert(key); + bool good = true; + try { + Exiv2::ExifData data; + auto &datum = data[key]; + if (datum.setValue(value) != 0) { + if ((datum.typeId() == Exiv2::signedRational || datum.typeId() == Exiv2::unsignedRational) && datum.setValue(value + "/1") == 0) { + value += "/1"; + } else { + good = false; + } + } + } catch (std::exception &exc) { + good = false; } - refreshTags(); - it = exifTreeModel->get_iter(path); - exifTree->get_selection()->select(it); - notifyListener(); + if (good) { + (*changeList)[key] = value; + if (!all_keys_active()) { + cur_active_keys_.insert(key); + } + refreshTags(); + + it = exifTreeModel->get_iter(path); + exifTree->get_selection()->select(it); + notifyListener(); + } else if (pl_) { + pl_->error(Glib::ustring::compose(M("ERROR_MSG_METADATA_VALUE"), key, value)); + } +} + + +void ExifPanel::setProgressListener(rtengine::ProgressListener *pl) +{ + pl_ = pl; } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 261561ea0..bc8d6229f 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -99,6 +99,8 @@ private: std::unordered_set initial_active_keys_; std::unordered_set cur_active_keys_; + rtengine::ProgressListener *pl_; + void addTag(const std::string &key, const std::pair &label, const Glib::ustring &value, bool editable, bool edited); void refreshTags(); void resetIt(const Gtk::TreeModel::const_iterator& iter); @@ -136,4 +138,5 @@ public: void notifyListener(); + void setProgressListener(rtengine::ProgressListener *pl); }; diff --git a/rtgui/metadatapanel.cc b/rtgui/metadatapanel.cc index e26444ccc..4e6252da4 100644 --- a/rtgui/metadatapanel.cc +++ b/rtgui/metadatapanel.cc @@ -127,3 +127,9 @@ void MetaDataPanel::metaDataModeChanged() listener->panelChanged(EvMetaDataMode, M("HISTORY_CHANGED")); } } + + +void MetaDataPanel::setProgressListener(rtengine::ProgressListener *pl) +{ + exifpanel->setProgressListener(pl); +} diff --git a/rtgui/metadatapanel.h b/rtgui/metadatapanel.h index bc74ac484..aacbb9fe1 100644 --- a/rtgui/metadatapanel.h +++ b/rtgui/metadatapanel.h @@ -45,5 +45,7 @@ public: void setImageData(const rtengine::FramesMetaData* id); void setListener(ToolPanelListener *tpl) override; + + void setProgressListener(rtengine::ProgressListener *pl); }; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index fde949606..defe64065 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -1271,3 +1271,9 @@ bool ToolPanelCoordinator::getFilmNegativeSpot(rtengine::Coord spot, int spotSiz { return ipc && ipc->getFilmNegativeSpot(spot.x, spot.y, spotSize, refInput, refOutput); } + + +void ToolPanelCoordinator::setProgressListener(rtengine::ProgressListener *pl) +{ + metadata->setProgressListener(pl); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 675b77de7..4c46a39ec 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -348,6 +348,8 @@ public: void setEditProvider(EditDataProvider *provider); + void setProgressListener(rtengine::ProgressListener *pl); + private: IdleRegister idle_register; }; From 322e709bcb29cdb49db1b49a42ff3877e9c349d0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 17 Sep 2020 23:17:45 -0700 Subject: [PATCH 117/326] metadata: do not accidentally remove exif tags when embedding the arp sidecar in XMP Fixes #127 (cherry picked from commit 49cbe9bd19db558a4be36221472cbb5e78aa95a2) --- rtengine/imageio.cc | 2 +- rtengine/metadata.cc | 6 ++++-- rtengine/metadata.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 4d8f93d55..b38fc745c 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1370,7 +1370,7 @@ bool ImageIO::saveMetadata(const Glib::ustring &fname) const if (has_meta) { try { - metadataInfo.saveToImage(fname); + metadataInfo.saveToImage(fname, false); // auto src = open_exiv2(metadataInfo.filename()); // auto dst = open_exiv2(fname); // src->readMetadata(); diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 8028e933f..049233cc6 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -217,7 +217,7 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const } -void Exiv2Metadata::saveToImage(const Glib::ustring &path) const +void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tags) const { auto dst = open_exiv2(path, false); if (image_.get()) { @@ -227,7 +227,9 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path) const do_merge_xmp(dst.get()); } auto srcexif = image_->exifData(); - remove_unwanted(srcexif); + if (!preserve_all_tags) { + remove_unwanted(srcexif); + } dst->setExifData(srcexif); } else { dst->setExifData(exif_data_); diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 57484d234..0f9f7919d 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -53,7 +53,7 @@ public: void setExif(const rtengine::procparams::ExifPairs& exif); void setIptc(const rtengine::procparams::IPTCPairs& iptc); - void saveToImage(const Glib::ustring& path) const; + void saveToImage(const Glib::ustring& path, bool preserve_all_tags) const; void saveToXmp(const Glib::ustring& path) const; void setExifKeys(const std::vector *keys); From fca1b5c5f5bbac9dd11717299740176d92d3785e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 1 Oct 2020 08:46:38 +0200 Subject: [PATCH 118/326] added support for easier editing of some common metadata tags (cherry picked from commit 0e3f760b520a5cbaa4e63d0f8a5ca5574093f411) --- rtgui/exifpanel.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 719674151..0664132f6 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -28,6 +28,8 @@ #include "../rtengine/metadata.h" #include "../rtengine/procparams.h" +#include + using namespace rtengine; using namespace rtengine::procparams; @@ -637,6 +639,74 @@ void ExifPanel::setExifTagValue(Gtk::CellRenderer *renderer, const Gtk::TreeMode } +namespace { + + +Glib::ustring to_fraction(const Glib::ustring &s) +{ + auto i = s.find("."); + if (i != Glib::ustring::npos) { + return s.substr(0, i) + s.substr(i+1) + "/1" + Glib::ustring(s.size() - i - 1, '0'); + } + return s; +} + +typedef Glib::ustring (*validator_func)(const Glib::ustring &); + +Glib::ustring get_fnumber(const Glib::ustring &val) +{ + Glib::MatchInfo m; + auto re = Glib::Regex::create("f? *([0-9.]+) *", Glib::REGEX_CASELESS); + if (re->match(val, m)) { + auto s = m.fetch(1); + return to_fraction(s); + } + return val; +} + +Glib::ustring get_shutterspeed(const Glib::ustring &val) +{ + Glib::MatchInfo m; + auto re = Glib::Regex::create(" *([0-9/]+) *s? *", Glib::REGEX_CASELESS); + if (re->match(val, m)) { + auto s = m.fetch(1); + return s; + } + return val; +} + +Glib::ustring get_focallen(const Glib::ustring &val) +{ + Glib::MatchInfo m; + auto re = Glib::Regex::create(" *([0-9.]+) *(mm)? *", Glib::REGEX_CASELESS); + if (re->match(val, m)) { + auto s = m.fetch(1); + return to_fraction(s); + } + return val; +} + +Glib::ustring get_expcomp(const Glib::ustring &val) +{ + Glib::MatchInfo m; + auto re = Glib::Regex::create(" *(-?[0-9.]+) *(EV)? *", Glib::REGEX_CASELESS); + if (re->match(val, m)) { + auto s = m.fetch(1); + return to_fraction(s); + } + return val; +} + +std::unordered_map validators = { + {"Exif.Photo.FNumber", get_fnumber}, + {"Exif.Photo.ExposureTime", get_shutterspeed}, + {"Exif.Photo.FocalLength", get_focallen}, + {"Exif.Photo.ExposureBiasValue", get_expcomp} +}; + +} // namespace + + void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustring &val) { auto it = exifTreeModel->get_iter(path); @@ -648,6 +718,13 @@ void ExifPanel::onEditExifTagValue(const Glib::ustring &path, const Glib::ustrin try { Exiv2::ExifData data; auto &datum = data[key]; + auto it = validators.find(key); + if (it != validators.end()) { + auto v = it->second(value); + if (datum.setValue(v) == 0) { + value = v; + } + } if (datum.setValue(value) != 0) { if ((datum.typeId() == Exiv2::signedRational || datum.typeId() == Exiv2::unsignedRational) && datum.setValue(value + "/1") == 0) { value += "/1"; From 0102fca563cd4f3121428122b1c46787aabb0691 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 25 Nov 2020 23:32:55 -0800 Subject: [PATCH 119/326] improved metadata extraction from ancient Kodak DCS4xx cameras (cherry picked from commit a2cc73f5f4769ad9ad2daaea9b5adbe7b158ad9e) --- rtengine/imagedata.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index d8cec7604..da0c136fc 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "imagedata.h" #include "imagesource.h" @@ -311,6 +313,8 @@ FramesData::FramesData(const Glib::ustring &fname) : } else if (find_exif_tag("Exif.Photo.DateTimeDigitized")) { datetime_taken = pos->print(&exif); + } else if (find_exif_tag("Exif.Image.DateTime")) { + datetime_taken = validateUft8(pos->print(&exif)); } if (sscanf(datetime_taken.c_str(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { time.tm_year -= 1900; @@ -334,6 +338,42 @@ FramesData::FramesData(const Glib::ustring &fname) : } } + // try getting some metadata from ImageDescription + if (!make.compare(0, 5, "KODAK") && !getISOSpeed() && !getFNumber() && !getFocalLen() && !getShutterSpeed() && + find_exif_tag("Exif.Image.ImageDescription")) { + std::string s = pos->toString(); + std::string line; + std::smatch m; + const auto d = + [&m]() -> double { + std::string s = m[1]; + return atof(s.c_str()); + }; + while (true) { + auto p = s.find('\r'); + if (p == std::string::npos) { + break; + } + auto line = s.substr(0, p); + s = s.substr(p+1); + + if (std::regex_match(line, m, std::regex("ISO: +([0-9]+) *"))) { + iso_speed = d(); + } else if (std::regex_match(line, m, std::regex("Aperture: +F([0-9.]+) *"))) { + aperture = d(); + } else if (std::regex_match(line, m, std::regex("Shutter: +([0-9.]+) *"))) { + shutter = d(); + if (shutter) { + shutter = 1.0/shutter; + } + } else if (std::regex_match(line, m, std::regex("Lens \\(mm\\): +([0-9.]+) *"))) { + focal_len = d(); + } else if (std::regex_match(line, m, std::regex("Exp Comp: +([0-9.]+) *"))) { + expcomp = d(); + } + } + } + // ----------------------- // Special file type detection (HDR, PixelShift) // ------------------------ From 92befa7e810bfec7b2a8cbeb8b7162c3b627b684 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 2 Dec 2020 02:03:00 -0800 Subject: [PATCH 120/326] refactored code for extracting image dimensions from metadata (cherry picked from commit 0ece9c5bfad09bc9052238d83fa696ef39effaaa) --- rtengine/imagedata.cc | 20 ++++++++++++- rtengine/imagedata.h | 5 ++++ rtengine/metadata.cc | 23 +++++++++++++++ rtengine/metadata.h | 2 ++ rtengine/rawimagesource.cc | 58 +++++++++++++++++++++++++++++++------- rtengine/rawimagesource.h | 4 ++- rtengine/rtengine.h | 5 ++-- rtengine/rtthumbnail.cc | 11 ++++++-- rtengine/rtthumbnail.h | 4 ++- rtgui/cacheimagedata.cc | 12 +++++++- rtgui/cacheimagedata.h | 8 ++++++ rtgui/editorpanel.cc | 9 ++++-- rtgui/thumbnail.cc | 6 ++++ 13 files changed, 146 insertions(+), 21 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index da0c136fc..469388b1c 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -81,7 +81,9 @@ FramesData::FramesData(const Glib::ustring &fname) : lens("Unknown"), sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), - isHDR(false) + isHDR(false), + w_(-1), + h_(-1) { make.clear(); model.clear(); @@ -374,6 +376,8 @@ FramesData::FramesData(const Glib::ustring &fname) : } } + meta.getDimensions(w_, h_); + // ----------------------- // Special file type detection (HDR, PixelShift) // ------------------------ @@ -773,3 +777,17 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const strftime(buf, 256, "%Y:%m:%d %H:%M:%S", &t); set_exif(exif, "Exif.Photo.DateTimeOriginal", buf); } + + +void FramesData::getDimensions(int &w, int &h) const +{ + w = w_; + h = h_; +} + + +void FramesData::setDimensions(int w, int h) +{ + w_ = w; + h_ = h; +} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 3a915c15d..88c0ec48d 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -57,6 +57,8 @@ private: IIOSampleFormat sampleFormat; bool isPixelShift; bool isHDR; + int w_; + int h_; public: explicit FramesData(const Glib::ustring& fname); @@ -84,8 +86,11 @@ public: std::string getOrientation() const override; Glib::ustring getFileName() const override; int getRating() const override; + void getDimensions(int &w, int &h) const override; void fillBasicTags(Exiv2::ExifData &exif) const; + + void setDimensions(int w, int h); }; } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 049233cc6..85fcf79ff 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -448,6 +448,29 @@ void Exiv2Metadata::setExifKeys(const std::vector *keys) } +void Exiv2Metadata::getDimensions(int &w, int &h) const +{ + if (image_) { + if (dynamic_cast(image_.get())) { + auto &exif = image_->exifData(); + auto itw = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth")); + auto ith = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageLength")); + if (itw != exif.end() && ith != exif.end()) { + w = itw->toLong(); + h = ith->toLong(); + } else { + w = h = -1; + } + } else { + w = image_->pixelWidth(); + h = image_->pixelHeight(); + } + } else { + w = h = -1; + } +} + + Glib::ustring Exiv2Metadata::xmpSidecarPath(const Glib::ustring &path) { Glib::ustring fn = path; diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 0f9f7919d..d9b195ed5 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -58,6 +58,8 @@ public: void setExifKeys(const std::vector *keys); + void getDimensions(int &w, int &h) const; + static Glib::ustring xmpSidecarPath(const Glib::ustring& path); static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 8f8a71553..e583a27a5 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -690,7 +690,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima { MyMutex::MyLock lock(getImageMutex); - tran = defTransform (tran); + tran = defTransform(ri, tran); // compute channel multipliers double r, g, b; @@ -1009,8 +1009,41 @@ void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementP void RawImageSource::getFullSize (int& w, int& h, int tr) { + computeFullSize(ri, tr, w, h); - tr = defTransform (tr); + // tr = defTransform(ri, tr); + + // if (fuji) { + // w = ri->get_FujiWidth() * 2 + 1; + // h = (H - ri->get_FujiWidth()) * 2 + 1; + // } else if (d1x) { + // w = W; + // h = 2 * H; + // } else { + // w = W; + // h = H; + // } + + // if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { + // int tmp = w; + // w = h; + // h = tmp; + // } + + // w -= 2 * border; + // h -= 2 * border; +} + + +void RawImageSource::computeFullSize(const RawImage *ri, int tr, int &w, int &h) +{ + tr = defTransform(ri, tr); + + const int W = ri->get_width(); + const int H = ri->get_height(); + const bool fuji = ri->get_FujiWidth() != 0; + const bool d1x = !ri->get_model().compare("D1X"); + const int border = (ri->getSensorType() == ST_BAYER ? 4 : (ri->getSensorType() == ST_FUJI_XTRANS ? 7 : 0)); if (fuji) { w = ri->get_FujiWidth() * 2 + 1; @@ -1253,6 +1286,11 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) // Load complete Exif information idata = new FramesData(fname); // TODO: std::unique_ptr<> idata->setDCRawFrameCount (numFrames); + { + int ww, hh; + getFullSize(ww, hh); + idata->setDimensions(ww, hh); + } green(W, H); red(W, H); @@ -2718,7 +2756,7 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::defTransform (int tran) +int RawImageSource::defTransform(const RawImage *ri, int tran) { int deg = ri->get_rotateDegree(); @@ -4466,7 +4504,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double Probably (sure) there are improvement to do... I have create a table temperature with temp and white point with 118 values between 2000K and 12000K we can obviously change these values, more...with different steps - I have create a table for tint (green)with 134 values between 0.4 to 4. + I have create a table for tint (green)with 134 values between 0.4 to 4. I have create or recuparate and transformed 201 spectral colors from Colorchecker24, others color and my 468 colors target, or from web flowers, etc. with a step of 5nm, I think it is large enough. I think this value of 201 is now complete: I tested correlation with 60, 90, 100, 120, 155...better student increase with number of color, but now it seems stabilized Of course we can increase this number :) @@ -4519,7 +4557,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double itcwb_precis : 5 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file */ // BENCHFUN - + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix("sRGB"); const float wp[3][3] = { {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, @@ -5064,7 +5102,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } estimchrom /= sizcu4; - if (settings->verbose) { + if (settings->verbose) { printf("estimchrom=%f\n", estimchrom); } if (settings->itcwb_sort) { //sort in ascending with chroma values @@ -5366,7 +5404,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int if (settings->itcwb_precis == 5) { precision = 5; } else if (settings->itcwb_precis < 5) { - precision = 3; + precision = 3; } else if (settings->itcwb_precis > 5) { precision = 9; } @@ -5628,11 +5666,11 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref if (settings->itcwb_precis == 5) { precision = 5; } else if (settings->itcwb_precis < 5) { - precision = 3; + precision = 3; } else if (settings->itcwb_precis > 5) { precision = 9; } - + 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); WBauto(tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, studgood, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw); @@ -6093,7 +6131,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vectorinit(); + + RawImageSource::computeFullSize(ri, TR_NONE, tpp->full_width, tpp->full_height); + delete ri; return tpp; } @@ -1025,7 +1028,9 @@ Thumbnail::Thumbnail () : gammaCorrected (false), colorMatrix{}, scaleGain (1.0), - isRaw (true) + isRaw (true), + full_width(-1), + full_height(-1) { } @@ -1236,7 +1241,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.dehaze(baseImg, params.dehaze); ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0); - + // perform transform int origFW; int origFH; @@ -2125,7 +2130,7 @@ bool Thumbnail::readData (const Glib::ustring& fname) colorMatrix[i][j] = cm[ix++]; } } - + if (keyFile.has_key ("LiveThumbData", "ScaleGain")) { scaleGain = keyFile.get_double ("LiveThumbData", "ScaleGain"); } diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 33bfec21c..455f4fadb 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -82,6 +82,8 @@ class Thumbnail public: bool isRaw; + int full_width; + int full_height; ~Thumbnail (); Thumbnail (); @@ -94,7 +96,7 @@ public: void getDimensions (int& w, int& h, double& scaleFac); static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false); - static Thumbnail* loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false); + static Thumbnail* loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching=false); static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); void getCamWB (double& temp, double& green); diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 97007751c..365b8f1b7 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -56,7 +56,9 @@ CacheImageData::CacheImageData() : greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), - thumbImgType(0) + thumbImgType(0), + width(-1), + height(-1) { } @@ -208,6 +210,12 @@ int CacheImageData::load (const Glib::ustring& fname) if (keyFile.has_key ("FileInfo", "SampleFormat")) { sampleFormat = (rtengine::IIO_Sample_Format)keyFile.get_integer ("FileInfo", "SampleFormat"); } + if (keyFile.has_key("FileInfo", "Width")) { + width = keyFile.get_integer("FileInfo", "Width"); + } + if (keyFile.has_key("FileInfo", "Height")) { + height = keyFile.get_integer("FileInfo", "Height"); + } } if (format == FT_Raw && keyFile.has_group ("ExtraRawInfo")) { @@ -298,6 +306,8 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_string ("FileInfo", "Filetype", filetype); keyFile.set_integer ("FileInfo", "FrameCount", frameCount); keyFile.set_integer ("FileInfo", "SampleFormat", sampleFormat); + keyFile.set_integer("FileInfo", "Width", width); + keyFile.set_integer("FileInfo", "Height", height); if (format == FT_Raw) { keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 2b4d5f471..cb02b9169 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -80,6 +80,9 @@ public: QUICK_THUMBNAIL = 1 // was the thumbnail generated from embedded jpeg }; + int width; + int height; + CacheImageData (); int load (const Glib::ustring& fname); @@ -110,4 +113,9 @@ 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; } + void getDimensions(int &w, int &h) const override + { + w = width; + h = height; + } }; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 350538626..62556fb68 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1357,8 +1357,13 @@ void EditorPanel::info_toggled () escapeHtmlChars (Glib::path_get_dirname (openThm->getFileName())) + G_DIR_SEPARATOR_S, escapeHtmlChars (Glib::path_get_basename (openThm->getFileName())) ); - int ww = ipc->getFullWidth(); - int hh = ipc->getFullHeight(); + int ww = -1, hh = -1; + idata->getDimensions(ww, hh); + if (ww <= 0) { + ww = ipc->getFullWidth(); + hh = ipc->getFullHeight(); + } + //megapixels infoString = Glib::ustring::compose ("%1\n%2 MP (%3x%4)", infoString, diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index dfc1bfeb7..2ee17ba27 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -241,6 +241,10 @@ void Thumbnail::_generateThumbnailImage () 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; + } } } @@ -893,6 +897,8 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname) cfs.filetype = ""; } + idata->getDimensions(cfs.width, cfs.height); + delete idata; return deg; } From d16bc6f6ea84f842473453bb1032a87b13be245c Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sat, 12 Dec 2020 17:10:45 +0100 Subject: [PATCH 121/326] metadata: do not copy Exif tags with 0 count Tentative fix for #147 (cherry picked from commit 12f699df10c1c0854c0e882db151560a1f4f3a26) --- rtengine/metadata.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 85fcf79ff..f5f2d972c 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -230,7 +230,12 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag if (!preserve_all_tags) { remove_unwanted(srcexif); } - dst->setExifData(srcexif); + //dst->setExifData(srcexif); + for (auto &tag : srcexif) { + if (tag.count() > 0) { + dst->exifData()[tag.key()] = tag; + } + } } else { dst->setExifData(exif_data_); dst->setIptcData(iptc_data_); From 3d209e687d29e9c88245e90a218f01291df2ab06 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 12 Jan 2021 00:21:58 -0800 Subject: [PATCH 122/326] metadata: filter out unwanted tags when syncing with xmp sidecars (cherry picked from commit 239f3f59b931efb15482134fffd5f6065616e574) --- rtengine/metadata.cc | 14 +++++++++----- rtengine/metadata.h | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index f5f2d972c..236d402da 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -130,7 +130,7 @@ void Exiv2Metadata::load() const } if (merge_xmp_) { - do_merge_xmp(image_.get()); + do_merge_xmp(image_.get(), false); } } } @@ -190,15 +190,19 @@ void Exiv2Metadata::setIptc(const rtengine::procparams::IPTCPairs &iptc) *iptc_ = iptc; } -void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst) const +void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst, bool keep_all) const { try { auto xmp = getXmpSidecar(src_); Exiv2::ExifData exif; Exiv2::IptcData iptc; Exiv2::copyXmpToIptc(xmp, iptc); - Exiv2::copyXmpToExif(xmp, exif); + Exiv2::moveXmpToExif(xmp, exif); + if (!keep_all) { + remove_unwanted(exif); + } + for (auto &datum : exif) { dst->exifData()[datum.key()] = datum; } @@ -224,7 +228,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag dst->setIptcData(image_->iptcData()); dst->setXmpData(image_->xmpData()); if (merge_xmp_) { - do_merge_xmp(dst.get()); + do_merge_xmp(dst.get(), preserve_all_tags); } auto srcexif = image_->exifData(); if (!preserve_all_tags) { @@ -258,7 +262,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag !dst->xmpData().empty()) { dst->xmpData().clear(); if (!xmp_tried && merge_xmp_) { - do_merge_xmp(dst.get()); + do_merge_xmp(dst.get(), preserve_all_tags); xmp_tried = true; } } else if (msg.find("IPTC") != std::string::npos && diff --git a/rtengine/metadata.h b/rtengine/metadata.h index d9b195ed5..9de285111 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -67,7 +67,7 @@ public: static void cleanup(); private: - void do_merge_xmp(Exiv2::Image* dst) const; + void do_merge_xmp(Exiv2::Image* dst, bool keep_all) const; void import_exif_pairs(Exiv2::ExifData& out) const; void import_iptc_pairs(Exiv2::IptcData& out) const; void remove_unwanted(Exiv2::ExifData& dst) const; From 7d5b9e9d65d50fd1e892db9b473a891dd639ce6f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 20 Jan 2021 18:22:43 +0100 Subject: [PATCH 123/326] metadata: fixed bug in transferring basic tags (cherry picked from commit 89afbd90e154ddd5e6071c44990b68aa62227739) --- rtengine/imagedata.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 469388b1c..b4058e56e 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -754,7 +754,8 @@ void set_exif(Exiv2::ExifData &exif, const std::string &key, T val) { try { exif[key] = val; - } catch (std::exception &exc) {} + } catch (std::exception &exc) { + } } } // namespace @@ -765,10 +766,10 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const return; } set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed()); - set_exif(exif, "Exif.Photo.FNumber", apertureToString(getFNumber())); - set_exif(exif, "Exif.Photo.ExposureTime", shutterToString(getShutterSpeed())); + set_exif(exif, "Exif.Photo.FNumber", Exiv2::DoubleValue(getFNumber())); + set_exif(exif, "Exif.Photo.ExposureTime", Exiv2::DoubleValue(getShutterSpeed())); set_exif(exif, "Exif.Photo.FocalLength", Exiv2::DoubleValue(getFocalLen())); - set_exif(exif, "Exif.Photo.ExposureBiasValue", expcompToString(getExpComp(), false)); + set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(getExpComp())); set_exif(exif, "Exif.Image.Make", getMake()); set_exif(exif, "Exif.Image.Model", getModel()); set_exif(exif, "Exif.Photo.LensModel", getLens()); From ba79d8b7f06e85f9b908bb0fa5f9ee3d7ea71f11 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 20 Jan 2021 20:59:08 +0100 Subject: [PATCH 124/326] (hopefully) better metadata formatting (cherry picked from commit 89be8ee8e71b1d56f5c6ce7ce4068ab330e19d68) --- rtengine/imagedata.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index b4058e56e..d6b643bcd 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -766,10 +766,14 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const return; } set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed()); - set_exif(exif, "Exif.Photo.FNumber", Exiv2::DoubleValue(getFNumber())); - set_exif(exif, "Exif.Photo.ExposureTime", Exiv2::DoubleValue(getShutterSpeed())); - set_exif(exif, "Exif.Photo.FocalLength", Exiv2::DoubleValue(getFocalLen())); - set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(getExpComp())); + set_exif(exif, "Exif.Photo.FNumber", Exiv2::URationalValue(Exiv2::URational(round(getFNumber() * 10), 10))); + auto s = shutterToString(getShutterSpeed()); + if (s.find('/') == std::string::npos) { + s += "/1"; + } + set_exif(exif, "Exif.Photo.ExposureTime", s); + set_exif(exif, "Exif.Photo.FocalLength", Exiv2::URationalValue(Exiv2::URational(getFocalLen() * 10, 10))); + set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(round(getExpComp() * 100) / 100.0)); set_exif(exif, "Exif.Image.Make", getMake()); set_exif(exif, "Exif.Image.Model", getModel()); set_exif(exif, "Exif.Photo.LensModel", getLens()); From 939315f67b83441ba214678fc60f491f22beda22 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 26 Jan 2021 08:15:36 +0100 Subject: [PATCH 125/326] metadata: do not exclude tags that were explicitly selected by the user (cherry picked from commit 60d862fa72046ecf8f44c2a1677f72237e86e838) --- rtengine/metadata.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 236d402da..c0bdcfa29 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -363,9 +363,10 @@ void Exiv2Metadata::remove_unwanted(Exiv2::ExifData &dst) const } for (auto it = dst.begin(); it != dst.end(); ) { - if (badtags.find(it->key()) != badtags.end()) { + int relevant = exif_keys_ ? (exif_keys_->find(it->key()) != exif_keys_->end() ? 1 : 0) : -1; + if (badtags.find(it->key()) != badtags.end() && relevant != 1) { it = dst.erase(it); - } else if (exif_keys_ && exif_keys_->find(it->key()) == exif_keys_->end()) { + } else if (relevant == 0) { it = dst.erase(it); } else { bool found = false; From 522f6f44730606ce19e7f5b9d886cab18f767fb3 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 27 Jan 2021 10:06:25 -0800 Subject: [PATCH 126/326] metadata: make sure to include XResolution and YResolution when writing TIFFs This is mandatory (according to http://dpfmanager.org), and in fact needed for Photoshop compatibility (cherry picked from commit 5d281810cc7a7f7dc563dde030cf90c78dbf55d0) --- rtengine/imageio.cc | 26 ++++++++++++++++++++++++++ rtengine/metadata.cc | 40 ++++++++++++++++++++++++++++++++++++++-- rtengine/metadata.h | 2 ++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index b38fc745c..67b856092 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1098,6 +1098,7 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con return IMIO_SUCCESS; } + int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool uncompressed) const { if (getWidth() < 1 || getHeight() < 1) { @@ -1168,6 +1169,31 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u } }();*/ + // somehow Exiv2 (tested with 0.27.3) doesn't seem to be able to update + // XResolution and YResolution, so we do it ourselves here.... + constexpr float default_resolution = 300.f; + float x_res = default_resolution; + float y_res = default_resolution; + int res_unit = RESUNIT_INCH; + if (!metadataInfo.filename().empty()) { + auto exif = metadataInfo.getOutputExifData(); + auto it = exif.findKey(Exiv2::ExifKey("Exif.Image.XResolution")); + if (it != exif.end()) { + x_res = it->toFloat(); + } + it = exif.findKey(Exiv2::ExifKey("Exif.Image.YResolution")); + if (it != exif.end()) { + y_res = it->toFloat(); + } + it = exif.findKey(Exiv2::ExifKey("Exif.Image.ResolutionUnit")); + if (it != exif.end()) { + res_unit = it->toLong(); + } + } + TIFFSetField(out, TIFFTAG_XRESOLUTION, x_res); + TIFFSetField(out, TIFFTAG_YRESOLUTION, y_res); + TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, res_unit); + if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, (bps == 16 || bps == 32) && isFloat ? PREDICTOR_FLOATINGPOINT : PREDICTOR_HORIZONTAL); } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index c0bdcfa29..b6476f92a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -390,7 +390,12 @@ void Exiv2Metadata::import_exif_pairs(Exiv2::ExifData &out) const for (auto &p : *exif_) { try { out[p.first] = p.second; - } catch (std::exception &exc) {} + } catch (std::exception &exc) { + if (settings->verbose) { + std::cout << "Error setting " << p.first << " to " << p.second + << ": " << exc.what() << std::endl; + } + } } } @@ -408,7 +413,12 @@ void Exiv2Metadata::import_iptc_pairs(Exiv2::IptcData &out) const out.add(d); } } - } catch (std::exception &exc) {} + } catch (std::exception &exc) { + if (settings->verbose) { + std::cout << "Error setting " << p.first + << ": " << exc.what() << std::endl; + } + } } } @@ -515,4 +525,30 @@ void Exiv2Metadata::cleanup() Exiv2::XmpParser::terminate(); } + +Exiv2::ExifData Exiv2Metadata::getOutputExifData() const +{ + Exiv2::ExifData exif = exifData(); + try { + auto xmp = getXmpSidecar(src_); + Exiv2::moveXmpToExif(xmp, exif); + } catch (std::exception &exc) { + if (settings->verbose) { + std::cerr << "Error loading metadata from XMP sidecar: " + << exc.what() << std::endl; + } + } + remove_unwanted(exif); + import_exif_pairs(exif); + for (auto it = exif.begin(); it != exif.end(); ) { + if (it->count() > 0) { + ++it; + } else { + it = exif.erase(it); + } + } + return exif; +} + + } // namespace rtengine diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 9de285111..cd27aada5 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -60,6 +60,8 @@ public: void getDimensions(int &w, int &h) const; + Exiv2::ExifData getOutputExifData() const; + static Glib::ustring xmpSidecarPath(const Glib::ustring& path); static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path); From c75296b910a264dc9f224b10b03cc526ac5f26d7 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 4 Apr 2021 21:15:09 +0200 Subject: [PATCH 127/326] metadata: properly set the value of Exif.Photo.ExposureBiasValue (cherry picked from commit b0bdd1fda6759b8041a0cbf5ce977e947ea10cff) --- rtengine/imagedata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index d6b643bcd..b61bb8cfd 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -773,7 +773,7 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const } set_exif(exif, "Exif.Photo.ExposureTime", s); set_exif(exif, "Exif.Photo.FocalLength", Exiv2::URationalValue(Exiv2::URational(getFocalLen() * 10, 10))); - set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::DoubleValue(round(getExpComp() * 100) / 100.0)); + set_exif(exif, "Exif.Photo.ExposureBiasValue", Exiv2::RationalValue(Exiv2::Rational(round(getExpComp() * 100), 100))); set_exif(exif, "Exif.Image.Make", getMake()); set_exif(exif, "Exif.Image.Model", getModel()); set_exif(exif, "Exif.Photo.LensModel", getLens()); From 77d1bc2cb1137e392f8422b3600976a7750f1352 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 7 Apr 2021 02:18:33 -0700 Subject: [PATCH 128/326] metadata: use exiv2 to handle BMFF files (e.g. CR3) if supported (cherry picked from commit 1469a0a8225cb44fe7f130f375879aef23496a8b) --- rtengine/metadata.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index b6476f92a..555f9e7b2 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -517,6 +517,9 @@ void Exiv2Metadata::init() { cache_.reset(new ImageCache(IMAGE_CACHE_SIZE)); Exiv2::XmpParser::initialize(); +#ifdef EXV_ENABLE_BMFF + Exiv2::enableBMFF(true); +#endif } From a73e74f9cc31bb09100201756879ff0b415b62a8 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 22 Jun 2021 23:59:47 -0700 Subject: [PATCH 129/326] metadata: fixed bug in setting shutter speed in output jpgs (cherry picked from commit b6a1a15a76c2091f6f940ae7d16d45caa93dbb99) --- rtengine/imagedata.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index b61bb8cfd..4772b2230 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -695,11 +695,12 @@ std::string FramesMetaData::apertureToString(double aperture) std::string FramesMetaData::shutterToString(double shutter) { - char buffer[256]; if (shutter > 0.0 && shutter <= 0.5) { snprintf(buffer, sizeof(buffer), "1/%0.0f", 1.0 / shutter); + } else if (int(shutter) == shutter) { + snprintf(buffer, sizeof(buffer), "%d", int(shutter)); } else { snprintf(buffer, sizeof(buffer), "%0.1f", shutter); } @@ -755,6 +756,9 @@ void set_exif(Exiv2::ExifData &exif, const std::string &key, T val) try { exif[key] = val; } catch (std::exception &exc) { + if (settings->verbose) { + std::cout << "Exif -- error setting " << key << " to " << val << ": " << exc.what() << std::endl; + } } } @@ -768,7 +772,11 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const set_exif(exif, "Exif.Photo.ISOSpeedRatings", getISOSpeed()); set_exif(exif, "Exif.Photo.FNumber", Exiv2::URationalValue(Exiv2::URational(round(getFNumber() * 10), 10))); auto s = shutterToString(getShutterSpeed()); - if (s.find('/') == std::string::npos) { + auto p = s.find('.'); + if (p != std::string::npos) { + assert(p == s.length()-2); + s = s.substr(0, p) + s.substr(p+1) + "/10"; + } else if (s.find('/') == std::string::npos) { s += "/1"; } set_exif(exif, "Exif.Photo.ExposureTime", s); From f2248dce9dd71e03c379fd59bbb96a43f0e3329e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 2 Nov 2021 22:05:47 +0100 Subject: [PATCH 130/326] metadata: detect pixelshift files from sony and fujifilm (cherry picked from commit 6554778f7bc6ce50c3bb8a98ca1907cb945c2e34) --- rtengine/imagedata.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4772b2230..a1db3c8d3 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -424,6 +424,30 @@ FramesData::FramesData(const Glib::ustring &fname) : } } + if (make == "SONY") { + if (find_exif_tag("Exif.SubImage1.BitsPerSample") && pos->toLong() == 14) { + if (find_exif_tag("Exif.SubImage1.SamplesPerPixel") && pos->toLong() == 4 && + find_exif_tag("Exif.SubImage1.PhotometricInterpretation") && pos->toLong() == 32892 && + find_exif_tag("Exif.SubImage1.Compression") && pos->toLong() == 1) { + isPixelShift = true; + } + } else if (bps != exif.end() && bps->toLong() == 14 && + spp != exif.end() && spp->toLong() == 4 && + c != exif.end() && c->toLong() == 1 && + find_exif_tag("Exif.Image.Software") && + pos->toString() == "make_arq") { + isPixelShift = true; + } + } else if (make == "FUJIFILM") { + if (bps != exif.end() && bps->toLong() == 16 && + spp != exif.end() && spp->toLong() == 4 && + c != exif.end() && c->toLong() == 1 && + find_exif_tag("Exif.Image.Software") && + pos->toString() == "make_arq") { + isPixelShift = true; + } + } + sampleFormat = IIOSF_UNKNOWN; if (sf == exif.end()) From 2ce81cccc56f40677697ff00ac91decf6d28f3c3 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 16 Nov 2021 23:21:40 -0800 Subject: [PATCH 131/326] metadata: fixed glitches in importing IPTC tags (cherry picked from commit 3d03f654e22ca01f058492eab2c8fcbc564dc1b9) --- rtengine/metadata.cc | 13 +- rtgui/iptcpanel.cc | 706 ++++++++++++++++++++++--------------------- 2 files changed, 373 insertions(+), 346 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 555f9e7b2..d372119d9 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -198,6 +198,7 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst, bool keep_all) const Exiv2::IptcData iptc; Exiv2::copyXmpToIptc(xmp, iptc); Exiv2::moveXmpToExif(xmp, exif); + std::unordered_set seen; if (!keep_all) { remove_unwanted(exif); @@ -207,10 +208,18 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst, bool keep_all) const dst->exifData()[datum.key()] = datum; } for (auto &datum : iptc) { - dst->iptcData()[datum.key()] = datum; + if (seen.insert(datum.key()).second) { + dst->iptcData()[datum.key()] = datum; + } else { + dst->iptcData().add(datum); + } } for (auto &datum : xmp) { - dst->xmpData()[datum.key()] = datum; + if (seen.insert(datum.key()).second) { + dst->xmpData()[datum.key()] = datum; + } else { + dst->xmpData().add(datum); + } } } catch (std::exception &exc) { if (settings->verbose) { diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index bee7ec74a..f103433c3 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -81,390 +81,390 @@ IPTCPanel::IPTCPanel(): { set_orientation(Gtk::ORIENTATION_VERTICAL); - set_spacing (4); + set_spacing(4); - Gtk::Grid* iptc = Gtk::manage( new Gtk::Grid () ); + Gtk::Grid* iptc = Gtk::manage(new Gtk::Grid()); setExpandAlignProperties(iptc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); iptc->set_row_spacing(3); int row = 0; - Gtk::Label* capl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_DESCRIPTION") + ":") ); + Gtk::Label* capl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DESCRIPTION") + ":")); setExpandAlignProperties(capl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - captionText = Gtk::TextBuffer::create (); - captionView = Gtk::manage( new Gtk::TextView (captionText) ); + captionText = Gtk::TextBuffer::create(); + captionView = Gtk::manage(new Gtk::TextView(captionText)); setExpandAlignProperties(captionView, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - Gtk::ScrolledWindow* scrolledWindowc = Gtk::manage( new Gtk::ScrolledWindow() ); + Gtk::ScrolledWindow* scrolledWindowc = Gtk::manage(new Gtk::ScrolledWindow()); setExpandAlignProperties(scrolledWindowc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - scrolledWindowc->set_min_content_height (100); + scrolledWindowc->set_min_content_height(100); scrolledWindowc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); scrolledWindowc->add(*captionView); - capl->set_tooltip_text (M("IPTCPANEL_DESCRIPTIONHINT")); - captionView->set_tooltip_text (M("IPTCPANEL_DESCRIPTIONHINT")); + capl->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONHINT")); + captionView->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONHINT")); captionView->set_size_request(35, 95); - iptc->attach (*capl, 0, row++, 1, 1); - iptc->attach (*scrolledWindowc, 0, row++, 1, 1); + iptc->attach(*capl, 0, row++, 1, 1); + iptc->attach(*scrolledWindowc, 0, row++, 1, 1); // -------------------------- - Gtk::Label* capwl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_DESCRIPTIONWRITER") + ":") ); + Gtk::Label* capwl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DESCRIPTIONWRITER") + ":")); setExpandAlignProperties(capwl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - captionWriter = Gtk::manage( new Gtk::Entry () ); + captionWriter = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(captionWriter, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - capwl->set_tooltip_text (M("IPTCPANEL_DESCRIPTIONWRITERHINT")); - captionWriter->set_tooltip_text (M("IPTCPANEL_DESCRIPTIONWRITERHINT")); - iptc->attach (*capwl, 0, row++, 1, 1); - iptc->attach (*captionWriter, 0, row++, 1, 1); + capwl->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONWRITERHINT")); + captionWriter->set_tooltip_text(M("IPTCPANEL_DESCRIPTIONWRITERHINT")); + iptc->attach(*capwl, 0, row++, 1, 1); + iptc->attach(*captionWriter, 0, row++, 1, 1); // -------------------------- - Gtk::Label* headl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_HEADLINE") + ":") ); + Gtk::Label* headl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_HEADLINE") + ":")); setExpandAlignProperties(headl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - headline = Gtk::manage( new Gtk::Entry () ); + headline = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(headline, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE); - headl->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); - headline->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); - iptc->attach (*headl, 0, row++, 1, 1); - iptc->attach (*headline, 0, row++, 1, 1); + headl->set_tooltip_text(M("IPTCPANEL_HEADLINEHINT")); + headline->set_tooltip_text(M("IPTCPANEL_HEADLINEHINT")); + iptc->attach(*headl, 0, row++, 1, 1); + iptc->attach(*headline, 0, row++, 1, 1); // -------------------------- - Gtk::Label* instl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_INSTRUCTIONS") + ":") ); + Gtk::Label* instl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_INSTRUCTIONS") + ":")); setExpandAlignProperties(instl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - instructions = Gtk::manage( new Gtk::Entry () ); + instructions = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(instructions, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - instl->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); - instructions->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); - iptc->attach (*instl, 0, row++, 1, 1); - iptc->attach (*instructions, 0, row++, 1, 1); + instl->set_tooltip_text(M("IPTCPANEL_INSTRUCTIONSHINT")); + instructions->set_tooltip_text(M("IPTCPANEL_INSTRUCTIONSHINT")); + iptc->attach(*instl, 0, row++, 1, 1); + iptc->attach(*instructions, 0, row++, 1, 1); // -------------------------- - Gtk::Separator* hsep1 = Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL) ); + Gtk::Separator* hsep1 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); setExpandAlignProperties(hsep1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - iptc->attach (*hsep1, 0, row++, 2, 1); + iptc->attach(*hsep1, 0, row++, 2, 1); // -------------------------- - Gtk::Label* keyl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_KEYWORDS") + ":")); + Gtk::Label* keyl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_KEYWORDS") + ":")); setExpandAlignProperties(keyl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - keyl->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); - keywords = Gtk::manage( new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE) ); + keyl->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT")); + keywords = Gtk::manage(new Gtk::ListViewText(1, false, Gtk::SELECTION_MULTIPLE)); setExpandAlignProperties(keywords, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - keywords->set_headers_visible (false); - keywords->set_size_request (50, 95); - Gtk::ScrolledWindow* scrolledWindowkw = Gtk::manage( new Gtk::ScrolledWindow() ); + keywords->set_headers_visible(false); + keywords->set_size_request(50, 95); + Gtk::ScrolledWindow* scrolledWindowkw = Gtk::manage(new Gtk::ScrolledWindow()); setExpandAlignProperties(scrolledWindowkw, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - scrolledWindowkw->set_min_content_height (100); + scrolledWindowkw->set_min_content_height(100); scrolledWindowkw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); scrolledWindowkw->add(*keywords); - keyword = Gtk::manage(new MyComboBoxText (true)); + keyword = Gtk::manage(new MyComboBoxText(true)); setExpandAlignProperties(keyword, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); keyword->set_size_request(75); - keywords->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); - keyword->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); - addKW = Gtk::manage( new Gtk::Button () ); + keywords->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT")); + keyword->set_tooltip_text(M("IPTCPANEL_KEYWORDSHINT")); + addKW = Gtk::manage(new Gtk::Button()); setExpandAlignProperties(addKW, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - delKW = Gtk::manage( new Gtk::Button () ); + 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* addKWImg = Gtk::manage(new RTImage("add-small.png")); setExpandAlignProperties(addKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Image* delKWImg = Gtk::manage( new RTImage ("remove-small.png") ); + Gtk::Image* delKWImg = Gtk::manage(new RTImage("remove-small.png")); setExpandAlignProperties(delKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - addKW->add (*addKWImg); - delKW->add (*delKWImg); - Gtk::Grid* kwgrid = Gtk::manage( new Gtk::Grid () ); + addKW->add(*addKWImg); + delKW->add(*delKWImg); + Gtk::Grid* kwgrid = Gtk::manage(new Gtk::Grid()); setExpandAlignProperties(kwgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - kwgrid->attach (*keyword, 0, 0, 1, 1); - kwgrid->attach (*addKW, 1, 0, 1, 1); - kwgrid->attach (*delKW, 2, 0, 1, 1); - iptc->attach (*keyl, 0, row++, 1, 1); - iptc->attach (*kwgrid, 0, row++, 1, 1); + kwgrid->attach(*keyword, 0, 0, 1, 1); + kwgrid->attach(*addKW, 1, 0, 1, 1); + kwgrid->attach(*delKW, 2, 0, 1, 1); + iptc->attach(*keyl, 0, row++, 1, 1); + iptc->attach(*kwgrid, 0, row++, 1, 1); // -------------------------- - iptc->attach (*scrolledWindowkw, 0, row++, 2, 1); + iptc->attach(*scrolledWindowkw, 0, row++, 2, 1); // -------------------------- - Gtk::Separator* hsep2 = Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL) ); + Gtk::Separator* hsep2 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); setExpandAlignProperties(hsep2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - iptc->attach (*hsep2, 0, row++, 2, 1); + iptc->attach(*hsep2, 0, row++, 2, 1); // -------------------------- - Gtk::Label* catl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CATEGORY") + ":") ); + Gtk::Label* catl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CATEGORY") + ":")); setExpandAlignProperties(catl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - category = Gtk::manage(new MyComboBoxText (true)); + category = Gtk::manage(new MyComboBoxText(true)); category->set_size_request(75); setExpandAlignProperties(category, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - catl->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); - category->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); - Gtk::Label* scl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_SUPPCATEGORIES") + ":") ); + catl->set_tooltip_text(M("IPTCPANEL_CATEGORYHINT")); + category->set_tooltip_text(M("IPTCPANEL_CATEGORYHINT")); + Gtk::Label* scl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_SUPPCATEGORIES") + ":")); setExpandAlignProperties(scl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - suppCategories = Gtk::manage( new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE) ); + suppCategories = Gtk::manage(new Gtk::ListViewText(1, false, Gtk::SELECTION_MULTIPLE)); setExpandAlignProperties(suppCategories, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - suppCategories->set_headers_visible (false); + suppCategories->set_headers_visible(false); suppCategories->set_size_request(50, 95); - Gtk::ScrolledWindow* scrolledWindowsc = Gtk::manage( new Gtk::ScrolledWindow() ); + Gtk::ScrolledWindow* scrolledWindowsc = Gtk::manage(new Gtk::ScrolledWindow()); setExpandAlignProperties(scrolledWindowsc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - scrolledWindowsc->set_min_content_height (100); + scrolledWindowsc->set_min_content_height(100); scrolledWindowsc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); scrolledWindowsc->add(*suppCategories); - suppCategory = Gtk::manage(new MyComboBoxText (true)); + suppCategory = Gtk::manage(new MyComboBoxText(true)); suppCategory->set_size_request(75); setExpandAlignProperties(suppCategory, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - scl->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); - suppCategories->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); - suppCategory->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); - addSC = Gtk::manage( new Gtk::Button () ); + scl->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategories->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategory->set_tooltip_text(M("IPTCPANEL_SUPPCATEGORIESHINT")); + addSC = Gtk::manage(new Gtk::Button()); setExpandAlignProperties(addSC, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - delSC = Gtk::manage( new Gtk::Button () ); + 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* addSCImg = Gtk::manage(new RTImage("add-small.png")); setExpandAlignProperties(addSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Image* delSCImg = Gtk::manage( new RTImage ("remove-small.png") ); + Gtk::Image* delSCImg = Gtk::manage(new RTImage("remove-small.png")); setExpandAlignProperties(delSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - addSC->add (*addSCImg); - delSC->add (*delSCImg); - Gtk::Grid* scgrid = Gtk::manage( new Gtk::Grid () ); + addSC->add(*addSCImg); + delSC->add(*delSCImg); + Gtk::Grid* scgrid = Gtk::manage(new Gtk::Grid()); setExpandAlignProperties(scgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - scgrid->attach (*suppCategory, 0, 0, 1, 1); - scgrid->attach (*addSC, 1, 0, 1, 1); - scgrid->attach (*delSC, 2, 0, 1, 1); - iptc->attach (*catl, 0, row++, 1, 1); - iptc->attach (*category, 0, row++, 1, 1); + scgrid->attach(*suppCategory, 0, 0, 1, 1); + scgrid->attach(*addSC, 1, 0, 1, 1); + scgrid->attach(*delSC, 2, 0, 1, 1); + iptc->attach(*catl, 0, row++, 1, 1); + iptc->attach(*category, 0, row++, 1, 1); // -------------------------- - iptc->attach (*scl, 0, row++, 1, 1); - iptc->attach (*scgrid, 0, row++, 1, 1); + iptc->attach(*scl, 0, row++, 1, 1); + iptc->attach(*scgrid, 0, row++, 1, 1); // -------------------------- - iptc->attach (*scrolledWindowsc, 0, row++, 2, 1); + iptc->attach(*scrolledWindowsc, 0, row++, 2, 1); // -------------------------- - Gtk::Separator* hsep3 = Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL) ); + Gtk::Separator* hsep3 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); setExpandAlignProperties(hsep3, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - iptc->attach (*hsep3, 0, row++, 2, 1); + iptc->attach(*hsep3, 0, row++, 2, 1); // -------------------------- - Gtk::Label* creatorLbl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CREATOR") + ":") ); + Gtk::Label* creatorLbl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREATOR") + ":")); setExpandAlignProperties(creatorLbl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - creator = Gtk::manage( new Gtk::Entry () ); + creator = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(creator, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - creatorLbl->set_tooltip_text (M("IPTCPANEL_CREATORHINT")); - creator->set_tooltip_text (M("IPTCPANEL_CREATORHINT")); - iptc->attach (*creatorLbl, 0, row++, 1, 1); - iptc->attach (*creator, 0, row++, 1, 1); + creatorLbl->set_tooltip_text(M("IPTCPANEL_CREATORHINT")); + creator->set_tooltip_text(M("IPTCPANEL_CREATORHINT")); + iptc->attach(*creatorLbl, 0, row++, 1, 1); + iptc->attach(*creator, 0, row++, 1, 1); // -------------------------- - Gtk::Label* creatorJobTitleLbl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CREATORJOBTITLE") + ":") ); + Gtk::Label* creatorJobTitleLbl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREATORJOBTITLE") + ":")); setExpandAlignProperties(creatorJobTitleLbl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - creatorJobTitle = Gtk::manage( new Gtk::Entry () ); + creatorJobTitle = Gtk::manage( new Gtk::Entry()); setExpandAlignProperties(creatorJobTitle, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - creatorJobTitleLbl->set_tooltip_text (M("IPTCPANEL_CREATORJOBTITLEHINT")); - creatorJobTitle->set_tooltip_text (M("IPTCPANEL_CREATORJOBTITLEHINT")); - iptc->attach (*creatorJobTitleLbl, 0, row++, 1, 1); - iptc->attach (*creatorJobTitle, 0, row++, 1, 1); + creatorJobTitleLbl->set_tooltip_text(M("IPTCPANEL_CREATORJOBTITLEHINT")); + creatorJobTitle->set_tooltip_text(M("IPTCPANEL_CREATORJOBTITLEHINT")); + iptc->attach(*creatorJobTitleLbl, 0, row++, 1, 1); + iptc->attach(*creatorJobTitle, 0, row++, 1, 1); // -------------------------- - Gtk::Label* credl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CREDIT") + ":") ); + Gtk::Label* credl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CREDIT") + ":")); setExpandAlignProperties(credl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - credit = Gtk::manage( new Gtk::Entry () ); + credit = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(credit, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - credl->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); - credit->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); - iptc->attach (*credl, 0, row++, 1, 1); - iptc->attach (*credit, 0, row++, 1, 1); + credl->set_tooltip_text(M("IPTCPANEL_CREDITHINT")); + credit->set_tooltip_text(M("IPTCPANEL_CREDITHINT")); + iptc->attach(*credl, 0, row++, 1, 1); + iptc->attach(*credit, 0, row++, 1, 1); // -------------------------- - Gtk::Label* sourl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_SOURCE") + ":") ); + Gtk::Label* sourl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_SOURCE") + ":")); setExpandAlignProperties(sourl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - source = Gtk::manage( new Gtk::Entry () ); + source = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(source, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - sourl->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); - source->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); - iptc->attach (*sourl, 0, row++, 1, 1); - iptc->attach (*source, 0, row++, 1, 1); + sourl->set_tooltip_text(M("IPTCPANEL_SOURCEHINT")); + source->set_tooltip_text(M("IPTCPANEL_SOURCEHINT")); + iptc->attach(*sourl, 0, row++, 1, 1); + iptc->attach(*source, 0, row++, 1, 1); // -------------------------- - Gtk::Label* cprl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_COPYRIGHT") + ":") ); + Gtk::Label* cprl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_COPYRIGHT") + ":")); setExpandAlignProperties(cprl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - copyright = Gtk::manage( new Gtk::Entry () ); + copyright = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(copyright, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - cprl->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); - copyright->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); - iptc->attach (*cprl, 0, row++, 1, 1); - iptc->attach (*copyright, 0, row++, 1, 1); + cprl->set_tooltip_text(M("IPTCPANEL_COPYRIGHTHINT")); + copyright->set_tooltip_text(M("IPTCPANEL_COPYRIGHTHINT")); + iptc->attach(*cprl, 0, row++, 1, 1); + iptc->attach(*copyright, 0, row++, 1, 1); // -------------------------- - Gtk::Separator* hsep4 = Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL) ); + Gtk::Separator* hsep4 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); setExpandAlignProperties(hsep4, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - iptc->attach (*hsep4, 0, row++, 2, 1); + iptc->attach(*hsep4, 0, row++, 2, 1); // -------------------------- - Gtk::Label* cityl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CITY") + ":") ); + Gtk::Label* cityl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_CITY") + ":")); setExpandAlignProperties(cityl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - city = Gtk::manage( new Gtk::Entry () ); + city = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(city, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - cityl->set_tooltip_text (M("IPTCPANEL_CITYHINT")); - city->set_tooltip_text (M("IPTCPANEL_CITYHINT")); - iptc->attach (*cityl, 0, row++, 1, 1); - iptc->attach (*city, 0, row++, 1, 1); + cityl->set_tooltip_text(M("IPTCPANEL_CITYHINT")); + city->set_tooltip_text(M("IPTCPANEL_CITYHINT")); + iptc->attach(*cityl, 0, row++, 1, 1); + iptc->attach(*city, 0, row++, 1, 1); // -------------------------- - Gtk::Label* provl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_PROVINCE") + ":") ); + Gtk::Label* provl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_PROVINCE") + ":")); setExpandAlignProperties(provl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - province = Gtk::manage( new Gtk::Entry () ); + province = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(province, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - provl->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); - province->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); - iptc->attach (*provl, 0, row++, 1, 1); - iptc->attach (*province, 0, row++, 1, 1); + provl->set_tooltip_text(M("IPTCPANEL_PROVINCEHINT")); + province->set_tooltip_text(M("IPTCPANEL_PROVINCEHINT")); + iptc->attach(*provl, 0, row++, 1, 1); + iptc->attach(*province, 0, row++, 1, 1); // -------------------------- - Gtk::Label* ctrl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_COUNTRY") + ":") ); + Gtk::Label* ctrl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_COUNTRY") + ":")); setExpandAlignProperties(ctrl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - country = Gtk::manage( new Gtk::Entry () ); + country = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(country, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - ctrl->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); - country->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); - iptc->attach (*ctrl, 0, row++, 1, 1); - iptc->attach (*country, 0, row++, 1, 1); + ctrl->set_tooltip_text(M("IPTCPANEL_COUNTRYHINT")); + country->set_tooltip_text(M("IPTCPANEL_COUNTRYHINT")); + iptc->attach(*ctrl, 0, row++, 1, 1); + iptc->attach(*country, 0, row++, 1, 1); // -------------------------- - Gtk::Label* titll = Gtk::manage( new Gtk::Label (M("IPTCPANEL_TITLE") + ":") ); + Gtk::Label* titll = Gtk::manage(new Gtk::Label(M("IPTCPANEL_TITLE") + ":")); setExpandAlignProperties(titll, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - title = Gtk::manage( new Gtk::Entry () ); + title = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(title, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - titll->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); - title->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); - iptc->attach (*titll, 0, row++, 1, 1); - iptc->attach (*title, 0, row++, 1, 1); + titll->set_tooltip_text(M("IPTCPANEL_TITLEHINT")); + title->set_tooltip_text(M("IPTCPANEL_TITLEHINT")); + iptc->attach(*titll, 0, row++, 1, 1); + iptc->attach(*title, 0, row++, 1, 1); // -------------------------- - Gtk::Label* dcl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_DATECREATED") + ":") ); + Gtk::Label* dcl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_DATECREATED") + ":")); setExpandAlignProperties(dcl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - dateCreated = Gtk::manage( new Gtk::Entry () ); + dateCreated = Gtk::manage( new Gtk::Entry()); setExpandAlignProperties(dateCreated, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - dcl->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); - dateCreated->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); - iptc->attach (*dcl, 0, row++, 1, 1); - iptc->attach (*dateCreated, 0, row++, 1, 1); + dcl->set_tooltip_text(M("IPTCPANEL_DATECREATEDHINT")); + dateCreated->set_tooltip_text(M("IPTCPANEL_DATECREATEDHINT")); + iptc->attach(*dcl, 0, row++, 1, 1); + iptc->attach(*dateCreated, 0, row++, 1, 1); // -------------------------- - Gtk::Label* trl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_TRANSREFERENCE") + ":") ); + Gtk::Label* trl = Gtk::manage(new Gtk::Label(M("IPTCPANEL_TRANSREFERENCE") + ":")); setExpandAlignProperties(trl, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - transReference = Gtk::manage( new Gtk::Entry () ); + transReference = Gtk::manage(new Gtk::Entry()); setExpandAlignProperties(transReference, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - trl->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); - transReference->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); - iptc->attach (*trl, 0, row++, 1, 1); - iptc->attach (*transReference, 0, row++, 1, 1); + trl->set_tooltip_text(M("IPTCPANEL_TRANSREFERENCEHINT")); + transReference->set_tooltip_text(M("IPTCPANEL_TRANSREFERENCEHINT")); + iptc->attach(*trl, 0, row++, 1, 1); + iptc->attach(*transReference, 0, row++, 1, 1); // -------------------------- - Gtk::ScrolledWindow* scrolledWindow = Gtk::manage( new Gtk::ScrolledWindow() ); + Gtk::ScrolledWindow* scrolledWindow = Gtk::manage(new Gtk::ScrolledWindow()); setExpandAlignProperties(scrolledWindow, false, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); scrolledWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_RIGHT); scrolledWindow->add(*iptc); - pack_start (*scrolledWindow); + pack_start(*scrolledWindow); - Gtk::Grid* bbox = Gtk::manage( new Gtk::Grid () ); + Gtk::Grid* bbox = Gtk::manage(new Gtk::Grid()); setExpandAlignProperties(bbox, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - reset = Gtk::manage( new Gtk::Button () ); // M("IPTCPANEL_RESET") + 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.png", "redo.png"))); setExpandAlignProperties(reset, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - bbox->attach_next_to (*reset, Gtk::POS_LEFT, 1, 1); + bbox->attach_next_to(*reset, Gtk::POS_LEFT, 1, 1); - file = Gtk::manage( new Gtk::Button () ); // M("IPTCPANEL_EMBEDDED") + 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.png"))); setExpandAlignProperties(file, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - bbox->attach_next_to (*file, Gtk::POS_RIGHT, 1, 1); + bbox->attach_next_to(*file, Gtk::POS_RIGHT, 1, 1); - copy = Gtk::manage( new Gtk::Button () ); + 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.png"))); setExpandAlignProperties(copy, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - bbox->attach_next_to (*copy, Gtk::POS_RIGHT, 1, 1); + bbox->attach_next_to(*copy, Gtk::POS_RIGHT, 1, 1); - paste = Gtk::manage( new Gtk::Button () ); + 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.png"))); setExpandAlignProperties(paste, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - bbox->attach_next_to (*paste, Gtk::POS_RIGHT, 1, 1); + bbox->attach_next_to(*paste, Gtk::POS_RIGHT, 1, 1); - pack_end (*bbox, Gtk::PACK_SHRINK, 2); + pack_end(*bbox, Gtk::PACK_SHRINK, 2); reset->set_tooltip_text(M("IPTCPANEL_RESETHINT")); file->set_tooltip_text(M("IPTCPANEL_EMBEDDEDHINT")); copy->set_tooltip_text(M("IPTCPANEL_COPYHINT")); paste->set_tooltip_text(M("IPTCPANEL_PASTEHINT")); - reset->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::resetClicked) ); - file->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::fileClicked) ); - copy->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::copyClicked) ); - paste->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::pasteClicked) ); + reset->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::resetClicked)); + file->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::fileClicked)); + copy->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::copyClicked)); + paste->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::pasteClicked)); - addKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); - delKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delKeyWord) ); - addSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); - delSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delSuppCategory) ); - keyword->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); - suppCategory->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); + addKW->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::addKeyWord)); + delKW->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::delKeyWord)); + addSC->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::addSuppCategory)); + delSC->signal_clicked().connect(sigc::mem_fun(*this, &IPTCPanel::delSuppCategory)); + keyword->get_entry()->signal_activate().connect(sigc::mem_fun(*this, &IPTCPanel::addKeyWord)); + suppCategory->get_entry()->signal_activate().connect(sigc::mem_fun(*this, &IPTCPanel::addSuppCategory)); - conns[0] = captionText->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[1] = captionWriter->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[2] = headline->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[3] = instructions->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[4] = category->get_entry()->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[5] = creator->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[6] = creatorJobTitle->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[7] = credit->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[8] = source->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[9] = copyright->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[10] = city->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[11] = province->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[12] = country->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[13] = title->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[14] = dateCreated->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); - conns[15] = transReference->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[0] = captionText->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[1] = captionWriter->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[2] = headline->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[3] = instructions->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[4] = category->get_entry()->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[5] = creator->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[6] = creatorJobTitle->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[7] = credit->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[8] = source->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[9] = copyright->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[10] = city->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[11] = province->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[12] = country->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[13] = title->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[14] = dateCreated->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); + conns[15] = transReference->signal_changed().connect(sigc::mem_fun(*this, &IPTCPanel::updateChangeList)); - category->get_entry()->set_max_length (3); - keyword->get_entry()->set_max_length (64); - captionWriter->set_max_length (32); - instructions->set_max_length (256); - creator->set_max_length (32); - creatorJobTitle->set_max_length (32); - credit->set_max_length (32); - source->set_max_length (32); - copyright->set_max_length (128); - city->set_max_length (32); - province->set_max_length (32); - country->set_max_length (64); - title->set_max_length (64); - dateCreated->set_max_length (8); - transReference->set_max_length (32); + category->get_entry()->set_max_length(3); + keyword->get_entry()->set_max_length(64); + captionWriter->set_max_length(32); + instructions->set_max_length(256); + creator->set_max_length(32); + creatorJobTitle->set_max_length(32); + credit->set_max_length(32); + source->set_max_length(32); + copyright->set_max_length(128); + city->set_max_length(32); + province->set_max_length(32); + country->set_max_length(64); + title->set_max_length(64); + dateCreated->set_max_length(10); + transReference->set_max_length(32); - show_all (); + show_all(); } void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); + disableListener(); changeList->clear(); if (!pp->metadata.iptc.empty()) { @@ -473,8 +473,8 @@ void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) *changeList = *embeddedData; } - applyChangeList (); - enableListener (); + applyChangeList(); + enableListener(); } void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited) @@ -489,7 +489,7 @@ void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pe *defChangeList = defParams->metadata.iptc; } -void IPTCPanel::setImageData (const FramesMetaData* id) +void IPTCPanel::setImageData(const FramesMetaData* id) { embeddedData->clear(); if (id) { @@ -507,267 +507,285 @@ void IPTCPanel::setImageData (const FramesMetaData* id) } } - file->set_sensitive (!embeddedData->empty()); + file->set_sensitive(!embeddedData->empty()); } -void IPTCPanel::notifyListener () +void IPTCPanel::notifyListener() { if (listener) { - listener->panelChanged (EvIPTC, M("HISTORY_CHANGED")); + listener->panelChanged(EvIPTC, M("HISTORY_CHANGED")); } } -void IPTCPanel::addKeyWord () + +void IPTCPanel::addKeyWord() { + keyword->get_entry()->select_region(0, keyword->get_entry()->get_text().size()); - keyword->get_entry()->select_region (0, keyword->get_entry()->get_text().size()); - - for (unsigned int i = 0; i < keywords->size(); i++) - if (keywords->get_text (i) == keyword->get_entry()->get_text()) { + for (unsigned int i = 0; i < keywords->size(); i++) { + if (keywords->get_text(i) == keyword->get_entry()->get_text()) { return; } + } - keywords->append (keyword->get_entry()->get_text()); - keyword->prepend (keyword->get_entry()->get_text()); + keywords->append(keyword->get_entry()->get_text()); + keyword->prepend(keyword->get_entry()->get_text()); std::vector items; for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i != keyword->get_model()->children().end(); ++i) { Glib::ustring s; - i->get_value (0, s); - items.push_back (s); + i->get_value(0, s); + items.push_back(s); } - keyword->remove_all (); + keyword->remove_all(); for (unsigned int i = 0; i < 10 && i < items.size(); i++) { - keyword->append (items[i]); + keyword->append(items[i]); } - keywords->scroll_to_row (keywords->get_model()->get_path(--keywords->get_model()->children().end())); + keywords->scroll_to_row(keywords->get_model()->get_path(--keywords->get_model()->children().end())); - updateChangeList (); + updateChangeList(); } -void IPTCPanel::delKeyWord () -{ - std::vector selection = keywords->get_selected (); +void IPTCPanel::delKeyWord() +{ + std::vector selection = keywords->get_selected(); if (!selection.empty()) { std::vector keep; for (unsigned int i = 0; i < keywords->size(); i++) - if (std::find (selection.begin(), selection.end(), i) == selection.end()) { - keep.push_back (keywords->get_text (i)); + if (std::find(selection.begin(), selection.end(), i) == selection.end()) { + keep.push_back(keywords->get_text(i)); } - keywords->clear_items (); + keywords->clear_items(); - for (unsigned int i = 0; i < keep.size(); i++) { - keywords->append (keep[i]); + for(unsigned int i = 0; i < keep.size(); i++) { + keywords->append(keep[i]); } } - updateChangeList (); + updateChangeList(); } -void IPTCPanel::addSuppCategory () +void IPTCPanel::addSuppCategory() { for (unsigned int i = 0; i < suppCategories->size(); i++) - if (suppCategories->get_text (i) == suppCategory->get_entry()->get_text()) { + if (suppCategories->get_text(i) == suppCategory->get_entry()->get_text()) { return; } - suppCategories->append (suppCategory->get_entry()->get_text()); - suppCategory->prepend (suppCategory->get_entry()->get_text()); + suppCategories->append(suppCategory->get_entry()->get_text()); + suppCategory->prepend(suppCategory->get_entry()->get_text()); std::vector items; for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i != suppCategory->get_model()->children().end(); ++i) { Glib::ustring s; - i->get_value (0, s); - items.push_back (s); + i->get_value(0, s); + items.push_back(s); } - suppCategory->remove_all (); + suppCategory->remove_all(); for (unsigned int i = 0; i < 10 && i < items.size(); i++) { - suppCategory->append (items[i]); + suppCategory->append(items[i]); } - suppCategories->scroll_to_row (suppCategories->get_model()->get_path(--suppCategories->get_model()->children().end())); - suppCategory->get_entry()->select_region (0, suppCategory->get_entry()->get_text().size()); + suppCategories->scroll_to_row(suppCategories->get_model()->get_path(--suppCategories->get_model()->children().end())); + suppCategory->get_entry()->select_region(0, suppCategory->get_entry()->get_text().size()); - updateChangeList (); + updateChangeList(); } -void IPTCPanel::delSuppCategory () +void IPTCPanel::delSuppCategory() { - std::vector selection = suppCategories->get_selected (); + std::vector selection = suppCategories->get_selected(); if (!selection.empty()) { std::vector keep; for (unsigned int i = 0; i < suppCategories->size(); i++) - if (std::find (selection.begin(), selection.end(), i) == selection.end()) { - keep.push_back (suppCategories->get_text (i)); + if (std::find(selection.begin(), selection.end(), i) == selection.end()) { + keep.push_back(suppCategories->get_text(i)); } - suppCategories->clear_items (); + suppCategories->clear_items(); for (unsigned int i = 0; i < keep.size(); i++) { - suppCategories->append (keep[i]); + suppCategories->append(keep[i]); } } - updateChangeList (); + updateChangeList(); } -void IPTCPanel::updateChangeList () +void IPTCPanel::updateChangeList() { - changeList->clear (); - (*changeList)[CAPTION].push_back (captionText->get_text ()); - (*changeList)[CAPTION_WRITER].push_back (captionWriter->get_text ()); - (*changeList)[HEADLINE].push_back (headline->get_text ()); - (*changeList)[INSTRUCTIONS].push_back (instructions->get_text ()); + changeList->clear(); + (*changeList)[CAPTION].push_back(captionText->get_text()); + (*changeList)[CAPTION_WRITER].push_back(captionWriter->get_text()); + (*changeList)[HEADLINE].push_back(headline->get_text()); + (*changeList)[INSTRUCTIONS].push_back(instructions->get_text()); + std::set sset; + sset.clear(); for (unsigned int i = 0; i < keywords->size(); i++) { - (*changeList)[KEYWORDS].push_back (keywords->get_text (i)); + sset.insert(keywords->get_text(i)); + } + for (auto &s : sset) { + (*changeList)[KEYWORDS].push_back(s); } - (*changeList)[CATEGORY].push_back (category->get_entry()->get_text ()); + (*changeList)[CATEGORY].push_back(category->get_entry()->get_text()); + sset.clear(); for (unsigned int i = 0; i < suppCategories->size(); i++) { - (*changeList)[SUPPLEMENTAL_CATEGORIES].push_back (suppCategories->get_text (i)); + sset.insert(suppCategories->get_text(i)); + } + for (auto &s : sset) { + (*changeList)[SUPPLEMENTAL_CATEGORIES].push_back(s); } - (*changeList)[CREATOR].push_back (creator->get_text ()); - (*changeList)[CREATOR_JOB_TITLE].push_back (creatorJobTitle->get_text ()); - (*changeList)[CREDIT].push_back (credit->get_text ()); - (*changeList)[SOURCE].push_back (source->get_text ()); - (*changeList)[COPYRIGHT].push_back (copyright->get_text ()); - (*changeList)[CITY].push_back (city->get_text ()); - (*changeList)[PROVINCE].push_back (province->get_text ()); - (*changeList)[COUNTRY].push_back (country->get_text ()); - (*changeList)[TITLE].push_back (title->get_text ()); - (*changeList)[DATE_CREATED].push_back (dateCreated->get_text ()); - (*changeList)[TRANS_REFERENCE].push_back (transReference->get_text ()); + (*changeList)[CREATOR].push_back(creator->get_text()); + (*changeList)[CREATOR_JOB_TITLE].push_back(creatorJobTitle->get_text()); + (*changeList)[CREDIT].push_back(credit->get_text()); + (*changeList)[SOURCE].push_back(source->get_text()); + (*changeList)[COPYRIGHT].push_back(copyright->get_text()); + (*changeList)[CITY].push_back(city->get_text()); + (*changeList)[PROVINCE].push_back(province->get_text()); + (*changeList)[COUNTRY].push_back(country->get_text()); + (*changeList)[TITLE].push_back(title->get_text()); + (*changeList)[DATE_CREATED].push_back(dateCreated->get_text()); + (*changeList)[TRANS_REFERENCE].push_back(transReference->get_text()); - notifyListener (); + notifyListener(); } -void IPTCPanel::applyChangeList () -{ +void IPTCPanel::applyChangeList() +{ for (int i = 0; i < 16; i++) { - conns[i].block (true); + conns[i].block(true); } - captionText->set_text (""); - captionWriter->set_text (""); - headline->set_text (""); - instructions->set_text (""); - keywords->clear_items (); - category->get_entry()->set_text (""); - suppCategories->clear_items (); - creator->set_text (""); - creatorJobTitle->set_text (""); - credit->set_text (""); - source->set_text (""); - copyright->set_text (""); - city->set_text (""); - province->set_text (""); - country->set_text (""); - title->set_text (""); - dateCreated->set_text (""); - transReference->set_text (""); - keyword->get_entry()->set_text (""); - suppCategory->get_entry()->set_text (""); + captionText->set_text(""); + captionWriter->set_text(""); + headline->set_text(""); + instructions->set_text(""); + keywords->clear_items(); + category->get_entry()->set_text(""); + suppCategories->clear_items(); + creator->set_text(""); + creatorJobTitle->set_text(""); + credit->set_text(""); + source->set_text(""); + copyright->set_text(""); + city->set_text(""); + province->set_text(""); + country->set_text(""); + title->set_text(""); + dateCreated->set_text(""); + transReference->set_text(""); + keyword->get_entry()->set_text(""); + suppCategory->get_entry()->set_text(""); for (rtengine::procparams::IPTCPairs::const_iterator i = changeList->begin(); i != changeList->end(); ++i) { if (i->first == CAPTION && !i->second.empty()) { - captionText->set_text (i->second.at(0)); + captionText->set_text(i->second.at(0)); } else if (i->first == CAPTION_WRITER && !i->second.empty()) { - captionWriter->set_text (i->second.at(0)); + captionWriter->set_text(i->second.at(0)); } else if (i->first == HEADLINE && !i->second.empty()) { - headline->set_text (i->second.at(0)); + headline->set_text(i->second.at(0)); } else if (i->first == INSTRUCTIONS && !i->second.empty()) { - instructions->set_text (i->second.at(0)); - } else if (i->first == KEYWORDS) + instructions->set_text(i->second.at(0)); + } else if (i->first == KEYWORDS) { + std::set sset; for (unsigned int j = 0; j < i->second.size(); j++) { - keywords->append (i->second.at(j)); + sset.insert(i->second[j]); } - else if (i->first == CATEGORY && !i->second.empty()) { - category->get_entry()->set_text (i->second.at(0)); - } else if (i->first == SUPPLEMENTAL_CATEGORIES) + for (auto &s : sset) { + keywords->append(s); + } + } else if (i->first == CATEGORY && !i->second.empty()) { + category->get_entry()->set_text(i->second.at(0)); + } else if (i->first == SUPPLEMENTAL_CATEGORIES) { + std::set sset; for (unsigned int j = 0; j < i->second.size(); j++) { - suppCategories->append (i->second.at(j)); + sset.insert(i->second[j]); } - else if (i->first == CREATOR && !i->second.empty()) { - creator->set_text (i->second.at(0)); + for (auto &s : sset) { + suppCategories->append(s); + } + } else if (i->first == CREATOR && !i->second.empty()) { + creator->set_text(i->second.at(0)); } else if (i->first == CREATOR_JOB_TITLE && !i->second.empty()) { - creatorJobTitle->set_text (i->second.at(0)); + creatorJobTitle->set_text(i->second.at(0)); } else if (i->first == CREDIT && !i->second.empty()) { - credit->set_text (i->second.at(0)); + credit->set_text(i->second.at(0)); } else if (i->first == SOURCE && !i->second.empty()) { - source->set_text (i->second.at(0)); + source->set_text(i->second.at(0)); } else if (i->first == COPYRIGHT && !i->second.empty()) { - copyright->set_text (i->second.at(0)); + copyright->set_text(i->second.at(0)); } else if (i->first == CITY && !i->second.empty()) { - city->set_text (i->second.at(0)); + city->set_text(i->second.at(0)); } else if (i->first == PROVINCE && !i->second.empty()) { - province->set_text (i->second.at(0)); + province->set_text(i->second.at(0)); } else if (i->first == COUNTRY && !i->second.empty()) { - country->set_text (i->second.at(0)); + country->set_text(i->second.at(0)); } else if (i->first == TITLE && !i->second.empty()) { - title->set_text (i->second.at(0)); + title->set_text(i->second.at(0)); } else if (i->first == DATE_CREATED && !i->second.empty()) { - dateCreated->set_text (i->second.at(0)); + dateCreated->set_text(i->second.at(0)); } else if (i->first == TRANS_REFERENCE && !i->second.empty()) { - transReference->set_text (i->second.at(0)); + transReference->set_text(i->second.at(0)); } } for (int i = 0; i < 16; i++) { - conns[i].block (false); + conns[i].block(false); } } -void IPTCPanel::resetClicked () +void IPTCPanel::resetClicked() { - disableListener (); + disableListener(); *changeList = *defChangeList; - applyChangeList (); - enableListener (); - notifyListener (); + applyChangeList(); + enableListener(); + notifyListener(); } -void IPTCPanel::fileClicked () +void IPTCPanel::fileClicked() { - disableListener (); + disableListener(); *changeList = *embeddedData; - applyChangeList (); - enableListener (); - notifyListener (); + applyChangeList(); + enableListener(); + notifyListener(); } -void IPTCPanel::copyClicked () +void IPTCPanel::copyClicked() { - clipboard.setIPTC (*changeList); + clipboard.setIPTC(*changeList); } -void IPTCPanel::pasteClicked () +void IPTCPanel::pasteClicked() { - disableListener (); - *changeList = clipboard.getIPTC (); - applyChangeList (); - enableListener (); - notifyListener (); + disableListener(); + *changeList = clipboard.getIPTC(); + applyChangeList(); + enableListener(); + notifyListener(); } From a0e9a5960688df8432afddd6b73b0a45b8ed0de6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 17 Nov 2021 05:22:00 -0800 Subject: [PATCH 132/326] do not save IPTC tags in the arp if they are unchanged (cherry picked from commit c4c642794868c2b03fd824acc0a7db962162c16f) --- rtgui/iptcpanel.cc | 21 ++++++++++++++------- rtgui/iptcpanel.h | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index f103433c3..a7aa38f88 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -461,34 +461,41 @@ IPTCPanel::IPTCPanel(): show_all(); } + void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { - disableListener(); changeList->clear(); if (!pp->metadata.iptc.empty()) { *changeList = pp->metadata.iptc; + changelist_valid_ = true; } else { *changeList = *embeddedData; + changelist_valid_ = false; } applyChangeList(); enableListener(); } + void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited) { - - pp->metadata.iptc = *changeList; + if (changelist_valid_) { + pp->metadata.iptc = *changeList; + } else { + pp->metadata.iptc.clear(); + } } + void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { - *defChangeList = defParams->metadata.iptc; } + void IPTCPanel::setImageData(const FramesMetaData* id) { embeddedData->clear(); @@ -510,9 +517,9 @@ void IPTCPanel::setImageData(const FramesMetaData* id) file->set_sensitive(!embeddedData->empty()); } + void IPTCPanel::notifyListener() { - if (listener) { listener->panelChanged(EvIPTC, M("HISTORY_CHANGED")); } @@ -628,7 +635,7 @@ void IPTCPanel::delSuppCategory() void IPTCPanel::updateChangeList() { - + changelist_valid_ = true; changeList->clear(); (*changeList)[CAPTION].push_back(captionText->get_text()); (*changeList)[CAPTION_WRITER].push_back(captionWriter->get_text()); @@ -756,9 +763,9 @@ void IPTCPanel::applyChangeList() void IPTCPanel::resetClicked() { - disableListener(); *changeList = *defChangeList; + changelist_valid_ = false; applyChangeList(); enableListener(); notifyListener(); diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h index da52fa7d2..66564a151 100644 --- a/rtgui/iptcpanel.h +++ b/rtgui/iptcpanel.h @@ -34,6 +34,7 @@ private: const std::unique_ptr changeList; const std::unique_ptr defChangeList; const std::unique_ptr embeddedData; + bool changelist_valid_; Gtk::TextView* captionView; Glib::RefPtr captionText; From b409e0bab2a63d718823df78862b8b70d1b739ff Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 25 Nov 2021 14:32:36 -0800 Subject: [PATCH 133/326] fixed handling IPTC metadata that admit multiple values (cherry picked from commit 8becb08ec1417215bf8f02c54000d37c2e6920f0) --- rtengine/metadata.cc | 66 ++++++++++++++++++++++++++++++++----------- rtengine/metadata.h | 9 +++++- rtengine/procparams.h | 5 ++++ rtgui/iptcpanel.cc | 7 +++++ 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index d372119d9..28a9c1742 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -81,6 +81,20 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname, return ret; } + +template +void clear_metadata_key(Data &data, const Key &key) +{ + while (true) { + auto it = data.findKey(key); + if (it == data.end()) { + break; + } else { + data.erase(it); + } + } +} + } // namespace @@ -119,18 +133,29 @@ void Exiv2Metadata::load() const if (!src_.empty() && !image_.get() && Glib::file_test(src_.c_str(), Glib::FILE_TEST_EXISTS)) { CacheVal val; auto finfo = Gio::File::create_for_path(src_)->query_info(G_FILE_ATTRIBUTE_TIME_MODIFIED); - if (cache_ && cache_->get(src_, val) && val.second >= finfo->modification_time()) { - image_ = val.first; - } else { - auto img = open_exiv2(src_, true); - image_.reset(img.release()); - if (cache_) { - cache_->set(src_, CacheVal(image_, finfo->modification_time())); + Glib::TimeVal xmp_mtime(0, 0); + if (merge_xmp_) { + auto xmpname = xmpSidecarPath(src_); + if (Glib::file_test(xmpname.c_str(), Glib::FILE_TEST_EXISTS)) { + xmp_mtime = Gio::File::create_for_path(xmpname)->query_info(G_FILE_ATTRIBUTE_TIME_MODIFIED)->modification_time(); } } - if (merge_xmp_) { - do_merge_xmp(image_.get(), false); + if (cache_ && cache_->get(src_, val) && val.image_mtime >= finfo->modification_time() && val.use_xmp == merge_xmp_ && val.xmp_mtime >= xmp_mtime) { + image_ = val.image; + } else { + auto img = open_exiv2(src_, true); + image_.reset(img.release()); + if (merge_xmp_) { + do_merge_xmp(image_.get(), false); + } + if (cache_) { + val.image = image_; + val.image_mtime = finfo->modification_time(); + val.xmp_mtime = xmp_mtime; + val.use_xmp = merge_xmp_; + cache_->set(src_, val); + } } } } @@ -198,7 +223,7 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst, bool keep_all) const Exiv2::IptcData iptc; Exiv2::copyXmpToIptc(xmp, iptc); Exiv2::moveXmpToExif(xmp, exif); - std::unordered_set seen; + std::unordered_map> seen; if (!keep_all) { remove_unwanted(exif); @@ -208,16 +233,23 @@ void Exiv2Metadata::do_merge_xmp(Exiv2::Image *dst, bool keep_all) const dst->exifData()[datum.key()] = datum; } for (auto &datum : iptc) { - if (seen.insert(datum.key()).second) { + auto &s = seen[datum.key()]; + if (s.empty()) { + clear_metadata_key(dst->iptcData(), Exiv2::IptcKey(datum.key())); dst->iptcData()[datum.key()] = datum; - } else { + s.insert(datum.toString()); + } else if (s.insert(datum.toString()).second) { dst->iptcData().add(datum); } } + seen.clear(); for (auto &datum : xmp) { - if (seen.insert(datum.key()).second) { + auto &s = seen[datum.key()]; + if (s.empty()) { + clear_metadata_key(dst->xmpData(), Exiv2::XmpKey(datum.key())); dst->xmpData()[datum.key()] = datum; - } else { + s.insert(datum.toString()); + } else if (s.insert(datum.toString()).second) { dst->xmpData().add(datum); } } @@ -415,9 +447,11 @@ void Exiv2Metadata::import_iptc_pairs(Exiv2::IptcData &out) const try { auto &v = p.second; if (v.size() >= 1) { - out[p.first] = v[0]; + clear_metadata_key(out, Exiv2::IptcKey(p.first)); + Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); + d.setValue(v[0]); + out[p.first] = d; for (size_t j = 1; j < v.size(); ++j) { - Exiv2::Iptcdatum d(Exiv2::IptcKey(p.first)); d.setValue(v[j]); out.add(d); } diff --git a/rtengine/metadata.h b/rtengine/metadata.h index cd27aada5..ff62e0848 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -85,7 +85,14 @@ private: std::shared_ptr> exif_keys_; - typedef std::pair, Glib::TimeVal> CacheVal; + struct CacheVal { + std::shared_ptr image; + Glib::TimeVal image_mtime; + Glib::TimeVal xmp_mtime; + bool use_xmp; + CacheVal() = default; + }; + //typedef std::pair, Glib::TimeVal> CacheVal; typedef Cache ImageCache; static std::unique_ptr cache_; }; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d874a9b13..8133a433a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1803,6 +1803,11 @@ public: return pairs.empty(); } + iterator erase(const const_iterator& key) + { + return pairs.erase(key); + } + void clear() { pairs.clear(); diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index a7aa38f88..eb6366fac 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -673,6 +673,13 @@ void IPTCPanel::updateChangeList() (*changeList)[DATE_CREATED].push_back(dateCreated->get_text()); (*changeList)[TRANS_REFERENCE].push_back(transReference->get_text()); + for (auto &p : *embeddedData) { + auto it = changeList->find(p.first); + if (it != changeList->end() && p.second == it->second) { + changeList->erase(it); + } + } + notifyListener(); } From 09d72259e3a43f1ab0b8370d4086c99973c3b6f9 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 5 Dec 2021 20:42:28 +0100 Subject: [PATCH 134/326] take care of some warnings Fixes #223 (cherry picked from commit f5bc793aa1efcba183602de3eec4746f4da3db8e) --- rtengine/metadata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/metadata.h b/rtengine/metadata.h index ff62e0848..7424b2720 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -90,7 +90,7 @@ private: Glib::TimeVal image_mtime; Glib::TimeVal xmp_mtime; bool use_xmp; - CacheVal() = default; + CacheVal(): image(nullptr), image_mtime(), xmp_mtime(), use_xmp(false) {} }; //typedef std::pair, Glib::TimeVal> CacheVal; typedef Cache ImageCache; From c7d5b5076dcb41d69248b6873b26eee331307b67 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 21 Mar 2022 01:09:50 -0700 Subject: [PATCH 135/326] metadata: fallback to Exif.Photo.LensModel for lenses unknown to exiv2 (cherry picked from commit 64e25471b003e302414d0cf48f64ccd1a988b454) --- rtengine/imagedata.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index a1db3c8d3..2caba4553 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -281,6 +281,10 @@ FramesData::FramesData(const Glib::ustring &fname) : if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + if (pos->count() == 1 && lens == std::to_string(pos->toLong()) && + find_exif_tag("Exif.Photo.LensModel")) { + lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + } } else if (find_exif_tag("Exif.Photo.LensSpecification") && pos->count() == 4) { const auto round = [](float f) -> float From 9fd136c2f3ab7dea5b13863ead0ff3243d868271 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 11 Apr 2022 23:11:27 -0700 Subject: [PATCH 136/326] metadata: work around misidentification of some Canon RF lenses with teleconverter (cherry picked from commit 3aae273f862f0c1611a134c6e84f460bba83bcf4) --- rtengine/imagedata.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 2caba4553..c8fb56a63 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -281,9 +281,15 @@ FramesData::FramesData(const Glib::ustring &fname) : if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? - if (pos->count() == 1 && lens == std::to_string(pos->toLong()) && - find_exif_tag("Exif.Photo.LensModel")) { + auto p = pos; + if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + if (Glib::ustring(lens).lowercase().find("canon") == Glib::ustring::npos) { + lens = std::string("Canon ") + lens; + } + } else if (p->count() == 1 && lens == std::to_string(p->toLong()) && + find_exif_tag("Exif.Photo.LensModel")) { + lens = validateUft8(p->print(&exif)); // validateUft8 (#5923) still needed? } } else if (find_exif_tag("Exif.Photo.LensSpecification") && pos->count() == 4) { const auto round = From 00c13bf2af65fb749d6d6ea4b6a6954c5080691f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 13 Apr 2022 05:54:30 -0700 Subject: [PATCH 137/326] tweaked lens identification for Canon RF cameras (cherry picked from commit a7e4ef71f9b400ffd53532c91d2ecb4e17e5ce2a) --- rtengine/imagedata.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index c8fb56a63..40a2baba4 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -284,9 +284,6 @@ FramesData::FramesData(const Glib::ustring &fname) : auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? - if (Glib::ustring(lens).lowercase().find("canon") == Glib::ustring::npos) { - lens = std::string("Canon ") + lens; - } } else if (p->count() == 1 && lens == std::to_string(p->toLong()) && find_exif_tag("Exif.Photo.LensModel")) { lens = validateUft8(p->print(&exif)); // validateUft8 (#5923) still needed? From 2ac459e927db8abb9f1f6c8a00a5cec2aa5c91df Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 15 Apr 2022 04:53:49 -0700 Subject: [PATCH 138/326] further tweaks to lens identification (cherry picked from commit 4fd18fed00eb799b8d82f472a98f270617bc3fb4) --- rtengine/imagedata.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 40a2baba4..8697aea09 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -284,9 +284,12 @@ FramesData::FramesData(const Glib::ustring &fname) : auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? - } else if (p->count() == 1 && lens == std::to_string(p->toLong()) && - find_exif_tag("Exif.Photo.LensModel")) { - lens = validateUft8(p->print(&exif)); // validateUft8 (#5923) still needed? + } else if (p->count() == 1 && lens == std::to_string(p->toLong())) { + if (find_exif_tag("Exif.Canon.LensModel")) { + lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + } else if (find_exif_tag("Exif.Photo.LensModel")) { + lens = validateUft8(p->print(&exif)); // validateUft8 (#5923) still needed? + } } } else if (find_exif_tag("Exif.Photo.LensSpecification") && pos->count() == 4) { const auto round = From eb7c15126055961668b7f17a631655618dcbeaa6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 18 Apr 2022 23:47:58 -0700 Subject: [PATCH 139/326] metadata: fixed regression with older exiv2 versions Fixes #246 (cherry picked from commit ac3e78c25ed5b14019661d5c6c58af15032e968d) --- rtengine/imagedata.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 8697aea09..d035760db 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -123,8 +123,15 @@ FramesData::FramesData(const Glib::ustring &fname) : const auto find_exif_tag = [&exif, &pos](const std::string &name) -> bool { - pos = exif.findKey(Exiv2::ExifKey(name)); - return pos != exif.end() && pos->size(); + try { + pos = exif.findKey(Exiv2::ExifKey(name)); + return pos != exif.end() && pos->size(); + } catch (std::exception &e) { + if (settings->verbose) { + std::cerr << "Exiv2 WARNING -- error finding tag " << name << ": " << e.what() << std::endl; + } + return false; + } }; const auto find_tag = From 7324ea723041ee2c20e1f66e174888566f32522d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 6 Jul 2022 07:04:24 -0700 Subject: [PATCH 140/326] replace Glib::filename_to_utf8 with custom fname_to_utf8 (cherry picked from commit 30b4daf9077e3c6780cefbf6c4223da4698b8612) --- rtgui/main-cli.cc | 19 ------------------- rtgui/main.cc | 23 ++--------------------- rtgui/pathutils.cc | 21 +++++++++++++++++++++ rtgui/pathutils.h | 5 ++++- 4 files changed, 27 insertions(+), 41 deletions(-) diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index feef93564..00272357e 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -67,25 +67,6 @@ Glib::ustring argv1; namespace { -// For an unknown reason, Glib::filename_to_utf8 doesn't work on reliably Windows, -// so we're using Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows. -Glib::ustring fname_to_utf8 (const char* fname) -{ -#ifdef WIN32 - - try { - return Glib::locale_to_utf8 (fname); - } catch (Glib::Error&) { - return Glib::convert_with_fallback (fname, "UTF-8", "ISO-8859-1", "?"); - } - -#else - - return Glib::filename_to_utf8 (fname); - -#endif -} - bool fast_export = false; } diff --git a/rtgui/main.cc b/rtgui/main.cc index 9f623a6df..08891ef46 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -44,6 +44,7 @@ #include "extprog.h" #include "../rtengine/dynamicprofile.h" #include "../rtengine/procparams.h" +#include "pathutils.h" #ifndef WIN32 #include @@ -71,27 +72,7 @@ bool remote = false; unsigned char initialGdkScale = 1; //Glib::Threads::Thread* mainThread; -namespace -{ - -// For an unknown reason, Glib::filename_to_utf8 doesn't work on reliably Windows, -// so we're using Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows. -Glib::ustring fname_to_utf8 (const char* fname) -{ -#ifdef WIN32 - - try { - return Glib::locale_to_utf8 (fname); - } catch (Glib::Error&) { - return Glib::convert_with_fallback (fname, "UTF-8", "ISO-8859-1", "?"); - } - -#else - - return Glib::filename_to_utf8 (fname); - -#endif -} +namespace { // This recursive mutex will be used by gdk_threads_enter/leave instead of a simple mutex static Glib::Threads::RecMutex myGdkRecMutex; diff --git a/rtgui/pathutils.cc b/rtgui/pathutils.cc index fc47a0e25..ef67564b2 100644 --- a/rtgui/pathutils.cc +++ b/rtgui/pathutils.cc @@ -16,6 +16,7 @@ * along with RawTherapee. If not, see . */ +#include #include #include "pathutils.h" @@ -48,3 +49,23 @@ Glib::ustring getExtension (const Glib::ustring& filename) return ""; } } + + +// For an unknown reason, Glib::filename_to_utf8 doesn't work on reliably Windows, +// so we're using Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows. +Glib::ustring fname_to_utf8(const std::string &fname) +{ +#ifdef WIN32 + + try { + return Glib::locale_to_utf8(fname); + } catch (Glib::Error&) { + return Glib::convert_with_fallback(fname, "UTF-8", "ISO-8859-1", "?"); + } + +#else + + return Glib::filename_to_utf8(fname); + +#endif +} diff --git a/rtgui/pathutils.h b/rtgui/pathutils.h index 482dfb82f..8ac1533b7 100644 --- a/rtgui/pathutils.h +++ b/rtgui/pathutils.h @@ -1,4 +1,5 @@ -/* +/* -*- C++ -*- + * * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath @@ -18,7 +19,9 @@ */ #pragma once #include +#include // Removed from guiutils because used by rawtherapee-cli Glib::ustring removeExtension (const Glib::ustring& filename); Glib::ustring getExtension (const Glib::ustring& filename); +Glib::ustring fname_to_utf8(const std::string& fname); From dcd2d3df0efe758ff797483fe115a3909383f6e9 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 11 Dec 2022 13:51:44 +0100 Subject: [PATCH 141/326] Replace Observer 10 by Observer 2 in most cases - see issue 6639 (#6640) * Change observer10 to observer2 * Another forgotten change observer 2 10 * Change colortemp.cc in accordance to options Itcwb_stdobserver10 --- rtengine/CMakeLists.txt | 1 + rtengine/colortemp.cc | 54 ++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 1f3cf352b..0fab84b55 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -176,6 +176,7 @@ if(LENSFUN_HAS_LOAD_DIRECTORY) set_source_files_properties(rtlensfun.cc PROPERTIES COMPILE_DEFINITIONS RT_LENSFUN_HAS_LOAD_DIRECTORY) endif() + if(WITH_BENCHMARK) add_definitions(-DBENCHMARK) endif() diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 36d42f063..a4dd8a4d1 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -33,7 +33,7 @@ namespace rtengine { -static const double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. +static double cie_colour_match_jd2[97][3] = {//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}, {0.001368, 0.000039, 0.006450001}, {0.002236, 0.000064, 0.01054999}, {0.004243, 0.000120, 0.02005001}, @@ -70,7 +70,7 @@ static const double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Des }; -static double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. +static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. {0.000000000000, 0.000000000000, 0.000000000000}, {0.000000000000, 0.000000000000, 0.000000000000}, {0.000000122200, 0.000000013398, 0.000000535027}, @@ -3388,7 +3388,7 @@ The next 3 methods are inspired from: this values are often called xBar yBar zBar and are characteristics of a color / illuminant -values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 +values cie_colour_match2[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increase precision used by J.Walker and pass to 350nm to 830nm And also add 10° standard observer @@ -3401,9 +3401,9 @@ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, doub for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = daylight_spect(lambda, _m1, _m2); - X += Me * cie_colour_match_jd[i][0]; - Y += Me * cie_colour_match_jd[i][1]; - Z += Me * cie_colour_match_jd[i][2]; + X += Me * cie_colour_match_jd2[i][0]; + Y += Me * cie_colour_match_jd2[i][1]; + Z += Me * cie_colour_match_jd2[i][2]; } XYZ = (X + Y + Z); @@ -3419,9 +3419,9 @@ void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, do for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = blackbody_spect(lambda, _temp); - X += Me * cie_colour_match_jd[i][0]; - Y += Me * cie_colour_match_jd[i][1]; - Z += Me * cie_colour_match_jd[i][2]; + X += Me * cie_colour_match_jd2[i][0]; + Y += Me * cie_colour_match_jd2[i][1]; + Z += Me * cie_colour_match_jd2[i][2]; } XYZ = (X + Y + Z); @@ -3447,16 +3447,16 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou this values are often called xBar yBar zBar and are characteristics of a color / illuminant - values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 + values cie_colour_match_jd2[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increased the precision used by J.Walker and pass from 350nm to 830nm And also add standard observer 10° */ for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = get_spectral_color(lambda, spec_intens); - X += Me * cie_colour_match_jd[i][0]; - Y += Me * cie_colour_match_jd[i][1]; - Z += Me * cie_colour_match_jd[i][2]; + X += Me * cie_colour_match_jd2[i][0]; + Y += Me * cie_colour_match_jd2[i][1]; + Z += Me * cie_colour_match_jd2[i][2]; } XYZ = (X + Y + Z); @@ -3478,9 +3478,9 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou Me = get_spectral_color(lambda, spec_color); Mc = get_spectral_color(lambda, spec_intens); - X += Mc * cie_colour_match_jd[i][0] * Me; - Y += Mc * cie_colour_match_jd[i][1] * Me; - Z += Mc * cie_colour_match_jd[i][2] * Me; + X += Mc * cie_colour_match_jd2[i][0] * Me; + Y += Mc * cie_colour_match_jd2[i][1] * Me; + Z += Mc * cie_colour_match_jd2[i][2] * Me; } for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { @@ -3488,7 +3488,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou double Ms; Ms = get_spectral_color(lambda, spec_intens); - Yo += cie_colour_match_jd[i][1] * Ms; + Yo += cie_colour_match_jd2[i][1] * Ms; } xx = X / Yo; @@ -3505,9 +3505,9 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; const double Mc = daylight_spect(lambda, _m1, _m2); - X += Mc * cie_colour_match_jd[i][0] * Me; - Y += Mc * cie_colour_match_jd[i][1] * Me; - Z += Mc * cie_colour_match_jd[i][2] * Me; + X += Mc * cie_colour_match_jd2[i][0] * Me; + Y += Mc * cie_colour_match_jd2[i][1] * Me; + Z += Mc * cie_colour_match_jd2[i][2] * Me; } xx = X / Y; @@ -3524,9 +3524,9 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; const double Mc = blackbody_spect(lambda, _temp); - X += Mc * cie_colour_match_jd[i][0] * Me; - Y += Mc * cie_colour_match_jd[i][1] * Me; - Z += Mc * cie_colour_match_jd[i][2] * Me; + X += Mc * cie_colour_match_jd2[i][0] * Me; + Y += Mc * cie_colour_match_jd2[i][1] * Me; + Z += Mc * cie_colour_match_jd2[i][2] * Me; } xx = X / Y; @@ -3769,11 +3769,11 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float } } - if (settings->itcwb_stdobserver10 == false) { + if (settings->itcwb_stdobserver10 == true) { for (int i = 0; i < 97; i++) { - cie_colour_match_jd[i][0] = cie_colour_match_jd2[i][0]; - cie_colour_match_jd[i][1] = cie_colour_match_jd2[i][1];; - cie_colour_match_jd[i][2] = cie_colour_match_jd2[i][2]; + cie_colour_match_jd2[i][0] = cie_colour_match_jd[i][0]; + cie_colour_match_jd2[i][1] = cie_colour_match_jd[i][1];; + cie_colour_match_jd2[i][2] = cie_colour_match_jd[i][2]; } } From 09e988475723bdf3ac7e7d686959ed3f83e9c5dd Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 14 Dec 2022 19:05:49 -0500 Subject: [PATCH 142/326] iccstore: Allow loading profiles from user-writable configuration directory In addition to bundled profiles and the system ICC profile store, load profiles from a user-writable/user-specific directory On Linux, this is $HOME/.config/RawTherapee/iccprofiles/output - corresponding to "input" being already supported Partial fix for part of #6644 --- rtengine/iccstore.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 2f443522c..d7bd57564 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -454,6 +454,8 @@ public: if (loadAll) { loadProfiles(profilesDir, &fileProfiles, &fileProfileContents, nullptr, false); loadProfiles(userICCDir, &fileProfiles, &fileProfileContents, nullptr, false); + Glib::ustring user_output_icc_dir = Glib::build_filename(options.rtdir, "iccprofiles", "output"); + loadProfiles(user_output_icc_dir, &fileProfiles, &fileProfileContents, nullptr, false); } // Input profiles From 9332333a12c781ec777ba5a825563dfeb5e1951a Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 16 Dec 2022 23:01:23 -0800 Subject: [PATCH 143/326] Speed up compilation of rtengine/procparams.cc --- rtengine/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 0fab84b55..c657d6f9d 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -176,6 +176,18 @@ if(LENSFUN_HAS_LOAD_DIRECTORY) set_source_files_properties(rtlensfun.cc PROPERTIES COMPILE_DEFINITIONS RT_LENSFUN_HAS_LOAD_DIRECTORY) endif() +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0") + # procparams.cc takes a long time to compile with optimizations starting + # with GCC 12.1 due to PTA (see issue #6548) + get_source_file_property(PROCPARAMS_COMPILE_OPTIONS procparams.cc COMPILE_OPTIONS) + if(PROCPARAMS_COMPILE_OPTIONS STREQUAL "NOTFOUND") + set(PROCPARAMS_COMPILE_OPTIONS "") + else() + set(PROCPARAMS_COMPILE_OPTIONS "${PROCPARAMS_COMPILE_OPTIONS};") + endif() + set(PROCPARAMS_COMPILE_OPTIONS "${PROCPARAMS_COMPILE_OPTIONS}-fno-tree-pta") + set_source_files_properties(procparams.cc PROPERTIES COMPILE_OPTIONS ${PROCPARAMS_COMPILE_OPTIONS}) +endif() if(WITH_BENCHMARK) add_definitions(-DBENCHMARK) From f64ddf0d8eb677ca5a13319c147a6028c43399e4 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sun, 18 Dec 2022 01:03:59 +0100 Subject: [PATCH 144/326] Updated logo image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae9efd9c8..a30a77212 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![RawTherapee logo](https://www.rawtherapee.com/images/logos/rawtherapee_logo_discuss.png) +![RawTherapee logo](https://raw.githubusercontent.com/Beep6581/RawTherapee/dev/rtdata/images/rt-logo-text-white.svg) RawTherapee is a powerful, cross-platform raw photo processing program, released as [libre software](https://en.wikipedia.org/wiki/Free_software) under the [GNU General Public License Version 3](https://opensource.org/licenses/gpl-3.0.html). It is written mostly in C++ using a [GTK+](https://www.gtk.org) front-end. It uses a patched version of [dcraw](https://www.dechifro.org/dcraw/) for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process. From bbe4558dff509604949e1bac58152ff0836b84f3 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Sun, 18 Dec 2022 03:55:29 +0100 Subject: [PATCH 145/326] Improvement to dcraw linear_table #6448 Merged on behalf of heckflosse https://github.com/Beep6581/RawTherapee/pull/6448#issuecomment-1081779513 --- rtengine/dcraw.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 6ca0e4331..4ab1694b8 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6319,12 +6319,13 @@ void CLASS parse_mos (int offset) void CLASS linear_table (unsigned len) { - int i; - if (len > 0x10000) len = 0x10000; - read_shorts (curve, len); - for (i=len; i < 0x10000; i++) - curve[i] = curve[i-1]; - maximum = curve[0xffff]; + const unsigned maxLen = std::min(0x10000ull, 1ull << tiff_bps); + len = std::min(len, maxLen); + read_shorts(curve, len); + maximum = curve[len - 1]; + for (std::size_t i = len; i < maxLen; ++i) { + curve[i] = maximum; + } } void CLASS parse_kodak_ifd (int base) From 38a8aa81602d536f6277f0f62f786c0d761db723 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sun, 18 Dec 2022 09:41:06 +0100 Subject: [PATCH 146/326] Added external screenshot to README.md (#6648) See #6642 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a30a77212..c43bfc2f4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![RawTherapee logo](https://raw.githubusercontent.com/Beep6581/RawTherapee/dev/rtdata/images/rt-logo-text-white.svg) +![RawTherapee screenshot](http://rawtherapee.com/images/carousel/100_rt59_provence_local_maskxxx.jpg) + RawTherapee is a powerful, cross-platform raw photo processing program, released as [libre software](https://en.wikipedia.org/wiki/Free_software) under the [GNU General Public License Version 3](https://opensource.org/licenses/gpl-3.0.html). It is written mostly in C++ using a [GTK+](https://www.gtk.org) front-end. It uses a patched version of [dcraw](https://www.dechifro.org/dcraw/) for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process. ## Target Audience From 9019c6dccd0bb942e568e3dd4e98764e5788e9fb Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 19 Dec 2022 13:28:20 -0800 Subject: [PATCH 147/326] Update libtiff DLL version for Windows workflow --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 296037812..f6f83f567 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -159,7 +159,7 @@ jobs: "libstdc++-6.dll" \ "libsystre-0.dll" \ "libthai-0.dll" \ - "libtiff-5.dll" \ + "libtiff-6.dll" \ "libtre-5.dll" \ "libwebp-7.dll" \ "libwinpthread-1.dll" \ From 2c9f5a735df5c9257d0627e531731060b4611215 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 30 Dec 2022 23:51:22 -0800 Subject: [PATCH 148/326] Add raw_crop and masked_areas for Canon EOS R7 and R10 (#6608) Signed-off-by: Alex Forencich --- rtengine/camconst.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 189d8f3f4..b7151f2c8 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1231,12 +1231,16 @@ Camera constants: { // Quality C "make_model": "Canon EOS R7", - "dcraw_matrix" : [10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183] + "dcraw_matrix" : [10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183], + "raw_crop": [ 144, 72, 6984, 4660 ], + "masked_areas" : [ 70, 20, 4724, 138 ] }, { // Quality C "make_model": "Canon EOS R10", - "dcraw_matrix" : [9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913] + "dcraw_matrix" : [9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913], + "raw_crop": [ 144, 40, 6048, 4020 ], + "masked_areas" : [ 38, 20, 4052, 138 ] }, { // Quality C, CHDK DNGs, raw frame correction From 22831866cd72c20a1d2f6952d76883b39e9ed4f7 Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Sat, 31 Dec 2022 10:16:38 +0100 Subject: [PATCH 149/326] Change RT logo to black version in README.md so text is visible --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c43bfc2f4..21f219a83 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![RawTherapee logo](https://raw.githubusercontent.com/Beep6581/RawTherapee/dev/rtdata/images/rt-logo-text-white.svg) +![RawTherapee logo](https://raw.githubusercontent.com/Beep6581/RawTherapee/dev/rtdata/images/rt-logo-text-black.svg) ![RawTherapee screenshot](http://rawtherapee.com/images/carousel/100_rt59_provence_local_maskxxx.jpg) From 401727fba9ab391ed8f4992e042e33860e2e272e Mon Sep 17 00:00:00 2001 From: Nicolas Turlais Date: Sat, 31 Dec 2022 10:51:30 +0100 Subject: [PATCH 150/326] Add filter for Paths to dynamic profiles (#6284) Work by @nicolas-t * Path filter in dynamic profile panel * Pass filename as a function argument * Removed unused include * Clearer translation --- rtdata/languages/default | 1 + rtengine/dynamicprofile.cc | 5 ++++- rtengine/dynamicprofile.h | 3 ++- rtengine/profilestore.cc | 4 ++-- rtengine/profilestore.h | 2 +- rtgui/dynamicprofilepanel.cc | 25 +++++++++++++++++++++++++ rtgui/dynamicprofilepanel.h | 6 ++++++ rtgui/main-cli.cc | 4 ++-- rtgui/thumbnail.cc | 2 +- 9 files changed, 44 insertions(+), 8 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 775b098f4..e5e053655 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -61,6 +61,7 @@ EXIFFILTER_IMAGETYPE;Image type EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Lens EXIFFILTER_METADATAFILTER;Enable metadata filters +EXIFFILTER_PATH;File path EXIFFILTER_SHUTTER;Shutter EXIFPANEL_ADDEDIT;Add/Edit EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 28516a1ee..6dbd2d0f0 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -77,7 +77,7 @@ bool DynamicProfileRule::operator< (const DynamicProfileRule &other) const } -bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const +bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im, const Glib::ustring& filename) const { return (iso (im->getISOSpeed()) && fnumber (im->getFNumber()) @@ -86,6 +86,7 @@ bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const && expcomp (im->getExpComp()) && camera (im->getCamera()) && lens (im->getLens()) + && path (filename) && imagetype(im->getImageType(0))); } @@ -214,6 +215,7 @@ bool DynamicProfileRules::loadRules() get_double_range (rule.expcomp, kf, group, "expcomp"); get_optional (rule.camera, kf, group, "camera"); get_optional (rule.lens, kf, group, "lens"); + get_optional (rule.path, kf, group, "path"); get_optional (rule.imagetype, kf, group, "imagetype"); try { @@ -247,6 +249,7 @@ bool DynamicProfileRules::storeRules() set_double_range (kf, group, "expcomp", rule.expcomp); set_optional (kf, group, "camera", rule.camera); set_optional (kf, group, "lens", rule.lens); + set_optional (kf, group, "path", rule.path); set_optional (kf, group, "imagetype", rule.imagetype); kf.set_string (group, "profilepath", rule.profilepath); } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index d91b91aee..654db3a8e 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -51,7 +51,7 @@ public: }; DynamicProfileRule(); - bool matches (const rtengine::FramesMetaData *im) const; + bool matches (const rtengine::FramesMetaData *im, const Glib::ustring& filename) const; bool operator< (const DynamicProfileRule &other) const; int serial_number; @@ -62,6 +62,7 @@ public: Range expcomp; Optional camera; Optional lens; + Optional path; Optional imagetype; Glib::ustring profilepath; }; diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 7d937e736..f83ddd385 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -508,7 +508,7 @@ void ProfileStore::dumpFolderList() printf ("\n"); } -PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) +PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im, const Glib::ustring& filename) { if (storeState == STORESTATE_NOTINITIALIZED) { parseProfilesOnce(); @@ -521,7 +521,7 @@ PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) } for (auto rule : dynamicRules) { - if (rule.matches (im)) { + if (rule.matches (im, filename)) { if (settings->verbose) { printf ("found matching profile %s\n", rule.profilepath.c_str()); } diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 460facb72..e8e48c17f 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -209,7 +209,7 @@ public: void addListener (ProfileStoreListener *listener); void removeListener (ProfileStoreListener *listener); - rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::FramesMetaData *im); + rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::FramesMetaData *im, const Glib::ustring& filename); void dumpFolderList(); }; diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index 865603b3a..feb6aea70 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -42,6 +42,7 @@ DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Wi add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_); add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_); + add_optional (M ("EXIFFILTER_PATH"), has_path_, path_); imagetype_ = Gtk::manage (new MyComboBoxText()); imagetype_->append(Glib::ustring("(") + M("DYNPROFILEEDITOR_IMGTYPE_ANY") + ")"); @@ -93,6 +94,9 @@ void DynamicProfilePanel::EditDialog::set_rule ( has_lens_->set_active (rule.lens.enabled); lens_->set_text (rule.lens.value); + has_path_->set_active (rule.path.enabled); + path_->set_text (rule.path.value); + if (!rule.imagetype.enabled) { imagetype_->set_active(0); } else if (rule.imagetype.value == "STD") { @@ -136,6 +140,9 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.lens.enabled = has_lens_->get_active(); ret.lens.value = lens_->get_text(); + ret.path.enabled = has_path_->get_active(); + ret.path.value = path_->get_text(); + ret.imagetype.enabled = imagetype_->get_active_row_number() > 0; switch (imagetype_->get_active_row_number()) { case 1: @@ -296,6 +303,16 @@ DynamicProfilePanel::DynamicProfilePanel(): *this, &DynamicProfilePanel::render_lens)); } + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_PATH"), *cell); + col = treeview_.get_column (cols_count - 1); + + if (col) { + col->set_cell_data_func ( + *cell, sigc::mem_fun ( + *this, &DynamicProfilePanel::render_path)); + } + cell = Gtk::manage (new Gtk::CellRendererText()); cols_count = treeview_.append_column (M ("EXIFFILTER_IMAGETYPE"), *cell); col = treeview_.get_column (cols_count - 1); @@ -375,6 +392,7 @@ void DynamicProfilePanel::update_rule (Gtk::TreeModel::Row row, row[columns_.expcomp] = rule.expcomp; row[columns_.camera] = rule.camera; row[columns_.lens] = rule.lens; + row[columns_.path] = rule.path; row[columns_.imagetype] = rule.imagetype; row[columns_.profilepath] = rule.profilepath; } @@ -398,6 +416,7 @@ DynamicProfileRule DynamicProfilePanel::to_rule (Gtk::TreeModel::Row row, ret.expcomp = row[columns_.expcomp]; ret.camera = row[columns_.camera]; ret.lens = row[columns_.lens]; + ret.path = row[columns_.path]; ret.profilepath = row[columns_.profilepath]; ret.imagetype = row[columns_.imagetype]; return ret; @@ -510,6 +529,12 @@ void DynamicProfilePanel::render_lens ( RENDER_OPTIONAL_ (lens); } +void DynamicProfilePanel::render_path ( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_ (path); +} + void DynamicProfilePanel::render_imagetype ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index 972ca1c4a..03b9e7c62 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -55,6 +55,7 @@ private: add (expcomp); add (camera); add (lens); + add (path); add (profilepath); add (imagetype); } @@ -66,6 +67,7 @@ private: Gtk::TreeModelColumn> expcomp; Gtk::TreeModelColumn camera; Gtk::TreeModelColumn lens; + Gtk::TreeModelColumn path; Gtk::TreeModelColumn imagetype; Gtk::TreeModelColumn profilepath; }; @@ -78,6 +80,7 @@ private: void render_expcomp (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_camera (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_lens (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_path (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_imagetype (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_profilepath (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); @@ -114,6 +117,9 @@ private: Gtk::CheckButton *has_lens_; Gtk::Entry *lens_; + Gtk::CheckButton *has_path_; + Gtk::Entry *path_; + MyComboBoxText *imagetype_; ProfileStoreComboBox *profilepath_; diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 8375ffe8b..cebced274 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -743,7 +743,7 @@ int processLineParams ( int argc, char **argv ) if (options.defProfRaw == DEFPROFILE_DYNAMIC) { rawParams->deleteInstance(); delete rawParams; - rawParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData()); + rawParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData(), inputFile); } std::cout << " Merging default raw processing profile." << std::endl; @@ -752,7 +752,7 @@ int processLineParams ( int argc, char **argv ) if (options.defProfImg == DEFPROFILE_DYNAMIC) { imgParams->deleteInstance(); delete imgParams; - imgParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData()); + imgParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData(), inputFile); } std::cout << " Merging default non-raw processing profile." << std::endl; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index cc8e9ad81..2baf03247 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -266,7 +266,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu // Should we ask all frame's MetaData ? imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); } - PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData); + PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData, fname); delete imageMetaData; int err = pp->pparams->save(outFName); pp->deleteInstance(); From d74524f2c57c4a4084352281ec7e6b3ba3f7e1ac Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 1 Jan 2023 01:50:11 -0800 Subject: [PATCH 152/326] Camconst support for multiple crops (#6473) Adapted from ART Co-authored-by: Alberto Griggio * camconst: support for multiple image sizes in raw_crop and masked_areas * Clean up code after porting raw crop changes * fixed raw crop for Canon R6 reduced-resolution raws * Add Canon EOS R5 1.6 crop raw crop & masked areas --- rtengine/camconst.cc | 195 ++++++++++++++++++++++++++++++----------- rtengine/camconst.h | 27 +++--- rtengine/camconst.json | 42 +++++++-- rtengine/rawimage.cc | 25 ++++-- 4 files changed, 213 insertions(+), 76 deletions(-) diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index aab2a252c..64fc4d4ba 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -28,8 +28,6 @@ namespace rtengine CameraConst::CameraConst() : pdafOffset(0) { memset(dcraw_matrix, 0, sizeof(dcraw_matrix)); - memset(raw_crop, 0, sizeof(raw_crop)); - memset(raw_mask, 0, sizeof(raw_mask)); white_max = 0; globalGreenEquilibration = -1; } @@ -192,6 +190,68 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model) std::unique_ptr cc(new CameraConst); cc->make_model = make_model; + const auto get_raw_crop = + [](int w, int h, const cJSON *ji, CameraConst *cc) -> bool + { + std::array rc; + + if (ji->type != cJSON_Array) { + //fprintf(stderr, "\"raw_crop\" must be an array\n"); + return false; + } + + int i; + + for (i = 0, ji = ji->child; i < 4 && ji != nullptr; i++, ji = ji->next) { + if (ji->type != cJSON_Number) { + //fprintf(stderr, "\"raw_crop\" array must contain numbers\n"); + return false; + } + + //cc->raw_crop[i] = ji->valueint; + rc[i] = ji->valueint; + } + + if (i != 4 || ji != nullptr) { + //fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n"); + return false; + } + + cc->raw_crop[std::make_pair(w, h)] = rc; + return true; + }; + + const auto get_masked_areas = + [](int w, int h, const cJSON *ji, CameraConst *cc) -> bool + { + std::array, 2> rm; + + if (ji->type != cJSON_Array) { + //fprintf(stderr, "\"masked_areas\" must be an array\n"); + return false; + } + + int i; + + for (i = 0, ji = ji->child; i < 2 * 4 && ji != nullptr; i++, ji = ji->next) { + if (ji->type != cJSON_Number) { + //fprintf(stderr, "\"masked_areas\" array must contain numbers\n"); + return false; + } + + //cc->raw_mask[i / 4][i % 4] = ji->valueint; + rm[i / 4][i % 4] = ji->valueint; + } + + if (i % 4 != 0) { + //fprintf(stderr, "\"masked_areas\" array length must be divisable by 4\n"); + return false; + } + + cc->raw_mask[std::make_pair(w, h)] = rm; + return true; + }; + const cJSON *ji = cJSON_GetObjectItem(js, "dcraw_matrix"); if (ji) { @@ -216,24 +276,32 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Array) { - fprintf(stderr, "\"raw_crop\" must be an array\n"); + fprintf(stderr, "invalid entry for raw_crop.\n"); return nullptr; - } - - int i; - - for (i = 0, ji = ji->child; i < 4 && ji; i++, ji = ji->next) { - if (ji->type != cJSON_Number) { - fprintf(stderr, "\"raw_crop\" array must contain numbers\n"); - return nullptr; + } else if (!get_raw_crop(0, 0, ji, cc.get())) { + cJSON *je; + cJSON_ArrayForEach(je, ji) { + if (!cJSON_IsObject(je)) { + fprintf(stderr, "invalid entry for raw_crop.\n"); + return nullptr; + } else { + auto js = cJSON_GetObjectItem(je, "frame"); + if (!js || js->type != cJSON_Array || + cJSON_GetArraySize(js) != 2 || + !cJSON_IsNumber(cJSON_GetArrayItem(js, 0)) || + !cJSON_IsNumber(cJSON_GetArrayItem(js, 1))) { + fprintf(stderr, "invalid entry for raw_crop.\n"); + return nullptr; + } + int w = cJSON_GetArrayItem(js, 0)->valueint; + int h = cJSON_GetArrayItem(js, 1)->valueint; + js = cJSON_GetObjectItem(je, "crop"); + if (!js || !get_raw_crop(w, h, js, cc.get())) { + fprintf(stderr, "invalid entry for raw_crop.\n"); + return nullptr; + } + } } - - cc->raw_crop[i] = ji->valueint; - } - - if (i != 4 || ji) { - fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n"); - return nullptr; } } @@ -241,24 +309,32 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Array) { - fprintf(stderr, "\"masked_areas\" must be an array\n"); + fprintf(stderr, "invalid entry for masked_areas.\n"); return nullptr; - } - - int i; - - for (i = 0, ji = ji->child; i < 2 * 4 && ji; i++, ji = ji->next) { - if (ji->type != cJSON_Number) { - fprintf(stderr, "\"masked_areas\" array must contain numbers\n"); - return nullptr; + } else if (!get_masked_areas(0, 0, ji, cc.get())) { + cJSON *je; + cJSON_ArrayForEach(je, ji) { + if (!cJSON_IsObject(je)) { + fprintf(stderr, "invalid entry for masked_areas.\n"); + return nullptr; + } else { + auto js = cJSON_GetObjectItem(je, "frame"); + if (!js || js->type != cJSON_Array || + cJSON_GetArraySize(js) != 2 || + !cJSON_IsNumber(cJSON_GetArrayItem(js, 0)) || + !cJSON_IsNumber(cJSON_GetArrayItem(js, 1))) { + fprintf(stderr, "invalid entry for masked_areas.\n"); + return nullptr; + } + int w = cJSON_GetArrayItem(js, 0)->valueint; + int h = cJSON_GetArrayItem(js, 1)->valueint; + js = cJSON_GetObjectItem(je, "areas"); + if (!js || !get_masked_areas(w, h, js, cc.get())) { + fprintf(stderr, "invalid entry for masked_areas.\n"); + return nullptr; + } + } } - - cc->raw_mask[i / 4][i % 4] = ji->valueint; - } - - if (i % 4 != 0) { - fprintf(stderr, "\"masked_areas\" array length must be divisible by 4\n"); - return nullptr; } } @@ -399,29 +475,41 @@ void CameraConst::update_pdafOffset(int other) pdafOffset = other; } -bool CameraConst::has_rawCrop() const + +bool CameraConst::has_rawCrop(int raw_width, int raw_height) const { - return raw_crop[0] != 0 || raw_crop[1] != 0 || raw_crop[2] != 0 || raw_crop[3] != 0; + return raw_crop.find(std::make_pair(raw_width, raw_height)) != raw_crop.end() || raw_crop.find(std::make_pair(0, 0)) != raw_crop.end(); } -void CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const + +void CameraConst::get_rawCrop(int raw_width, int raw_height, int &left_margin, int &top_margin, int &width, int &height) const { - left_margin = raw_crop[0]; - top_margin = raw_crop[1]; - width = raw_crop[2]; - height = raw_crop[3]; + auto it = raw_crop.find(std::make_pair(raw_width, raw_height)); + if (it == raw_crop.end()) { + it = raw_crop.find(std::make_pair(0, 0)); + } + if (it != raw_crop.end()) { + left_margin = it->second[0]; + top_margin = it->second[1]; + width = it->second[2]; + height = it->second[3]; + } else { + left_margin = top_margin = width = height = 0; + } } -bool CameraConst::has_rawMask(int idx) const + +bool CameraConst::has_rawMask(int raw_width, int raw_height, int idx) const { if (idx < 0 || idx > 1) { return false; } - return (raw_mask[idx][0] | raw_mask[idx][1] | raw_mask[idx][2] | raw_mask[idx][3]) != 0; + return raw_mask.find(std::make_pair(raw_width, raw_height)) != raw_mask.end() || raw_mask.find(std::make_pair(0, 0)) != raw_mask.end(); } -void CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const + +void CameraConst::get_rawMask(int raw_width, int raw_height, int idx, int &top, int &left, int &bottom, int &right) const { top = left = bottom = right = 0; @@ -429,10 +517,17 @@ void CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& ri return; } - top = raw_mask[idx][0]; - left = raw_mask[idx][1]; - bottom = raw_mask[idx][2]; - right = raw_mask[idx][3]; + auto it = raw_mask.find(std::make_pair(raw_width, raw_height)); + if (it == raw_mask.end()) { + it = raw_mask.find(std::make_pair(0, 0)); + } + + if (it != raw_mask.end()) { + top = it->second[idx][0]; + left = it->second[idx][1]; + bottom = it->second[idx][2]; + right = it->second[idx][3]; + } } void CameraConst::update_Levels(const CameraConst *other) @@ -464,9 +559,7 @@ void CameraConst::update_Crop(CameraConst *other) return; } - if (other->has_rawCrop()) { - other->get_rawCrop(raw_crop[0], raw_crop[1], raw_crop[2], raw_crop[3]); - } + raw_crop.insert(other->raw_crop.begin(), other->raw_crop.end()); } bool CameraConst::get_Levels(camera_const_levels & lvl, int bw, int iso, float fnumber) const diff --git a/rtengine/camconst.h b/rtengine/camconst.h index aa0702439..273bdd7a1 100644 --- a/rtengine/camconst.h +++ b/rtengine/camconst.h @@ -1,9 +1,11 @@ -/* +/* -*- C++ -*- + * * This file is part of RawTherapee. */ #pragma once #include +#include #include #include @@ -17,17 +19,17 @@ class ustring; namespace rtengine { -struct camera_const_levels { - int levels[4]; -}; - class CameraConst final { private: + struct camera_const_levels { + int levels[4]; + }; + std::string make_model; short dcraw_matrix[12]; - int raw_crop[4]; - int raw_mask[2][4]; + std::map, std::array> raw_crop; + std::map, std::array, 2>> raw_mask; int white_max; std::map mLevels[2]; std::map mApertureScaling; @@ -47,10 +49,10 @@ public: const short *get_dcrawMatrix(void) const; const std::vector& get_pdafPattern() const; int get_pdafOffset() const {return pdafOffset;}; - bool has_rawCrop(void) const; - void get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const; - bool has_rawMask(int idx) const; - void get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const; + bool has_rawCrop(int raw_width, int raw_height) const; + void get_rawCrop(int raw_width, int raw_height, int& left_margin, int& top_margin, int& width, int& height) const; + bool has_rawMask(int raw_width, int raw_height, int idx) const; + void get_rawMask(int raw_width, int raw_height, int idx, int& top, int& left, int& bottom, int& right) const; int get_BlackLevel(int idx, int iso_speed) const; int get_WhiteLevel(int idx, int iso_speed, float fnumber) const; bool has_globalGreenEquilibration() const; @@ -77,4 +79,5 @@ public: const CameraConst *get(const char make[], const char model[]) const; }; -} +} // namespace rtengine + diff --git a/rtengine/camconst.json b/rtengine/camconst.json index b7151f2c8..be7b3b800 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -70,6 +70,14 @@ Examples: // cropped so the "negative number" way is not totally safe. "raw_crop": [ 10, 20, 4000, 3000 ], + // multi-aspect support (added 2020-12-03) + // "frame" defines the full dimensions the crop applies to + // (with [0, 0] being the fallback crop if none of the other applies) + "raw_crop" : [ + { "frame" : [4100, 3050], "crop": [10, 20, 4050, 3020] }, + { "frame" : [0, 0], "crop": [10, 20, 4000, 3000] } + ] + // Almost same as MaskedAreas DNG tag, used for black level measuring. Here up to two areas can be defined // by tetrads of numbers: "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], @@ -84,6 +92,14 @@ Examples: // instead, to take care of possible light leaks from the light sensing area to the optically black (masked) // area or sensor imperfections at the outer borders. + // multi-aspect support (added 2020-12-03) + // "frame" defines the full dimensions the masked areas apply to + // (with [0, 0] being the fallback crop if none of the other applies) + "masked_areas" : [ + { "frame" : [4100, 3050], "areas": [10, 20, 4050, 3020] }, + { "frame" : [0, 0], "areas": [10, 20, 4000, 3000] } + ] + // list of indices of the rows with on-sensor PDAF pixels, for cameras that have such features. The indices here form a pattern that is repeated for the whole height of the sensor. The values are relative to the "pdaf_offset" value (see below) "pdaf_pattern" : [ 0,12,36,54,72,90,114,126,144,162,180,204,216,240,252,270,294,306,324,342,366,384,396,414,432,450,474,492,504,522,540,564,576,594,606,630 ], // index of the first row of the PDAF pattern in the sensor (0 is the topmost row). Allowed to be negative for convenience (this means that the first repetition of the pattern doesn't start from the first row) @@ -1216,16 +1232,28 @@ Camera constants: { // Quality C "make_model": "Canon EOS R5", "dcraw_matrix" : [9766, -2953, -1254, -4276, 12116, 2433, -437, 1336, 5131], - "raw_crop" : [ 128, 96, 8224, 5490 ], - "masked_areas" : [ 94, 20, 5578, 122 ], + "raw_crop" : [ + { "frame" : [ 8352, 5586 ], "crop" : [ 128, 96, 8224, 5490 ] }, + { "frame" : [ 5248, 3510 ], "crop" : [ 128, 96, 5120, 3382 ] } + ], + "masked_areas" : [ + { "frame" : [ 8352, 5586 ], "areas": [ 94, 20, 5578, 122 ] }, + { "frame" : [ 5248, 3510 ], "areas": [ 94, 20, 3510, 122 ] } + ], "ranges" : { "white" : 16382 } }, { // Quality C "make_model": "Canon EOS R6", "dcraw_matrix" : [8293, -1611, -1132, -4759, 12710, 2275, -1013, 2415, 5508], - "raw_crop": [ 72, 38, 5496, 3670 ], - "masked_areas" : [ 40, 10, 5534, 70 ], + "raw_crop": [ + { "frame": [5568, 3708], "crop" : [ 72, 38, 5496, 3670 ] }, + { "frame": [3584, 2386], "crop" : [ 156, 108, 3404, 2270 ] } + ], + "masked_areas" : [ + { "frame": [5568, 3708], "areas": [ 40, 10, 5534, 70 ] }, + { "frame": [3584, 2386], "areas": [ 40, 10, 2374, 110 ] } + ], "ranges" : { "white" : 16382 } }, @@ -1381,7 +1409,11 @@ Camera constants: { // Quality C "make_model": [ "FUJIFILM GFX 100", "FUJIFILM GFX100S" ], "dcraw_matrix" : [ 16212, -8423, -1583, -4336, 12583, 1937, -195, 726, 6199 ], // taken from ART - "raw_crop": [ 0, 2, 11664, 8734 ] + "raw_crop": [ + // multi-aspect crop to account for 16-shot pixel shift images + { "frame" : [11808, 8754], "crop" : [ 0, 2, 11664, 8734 ] }, + { "frame" : [23616, 17508], "crop" : [ 0, 4, 23328, 17468 ] } + ] }, { // Quality B diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 2354f343a..8478d56ab 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -548,11 +548,18 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog CameraConstantsStore* ccs = CameraConstantsStore::getInstance(); const CameraConst *cc = ccs->get(make, model); + bool raw_crop_cc = false; + int orig_raw_width = width; + int orig_raw_height = height; if (raw_image) { - if (cc && cc->has_rawCrop()) { + orig_raw_width = raw_width; + orig_raw_height = raw_height; + + if (cc && cc->has_rawCrop(raw_width, raw_height)) { + raw_crop_cc = true; int lm, tm, w, h; - cc->get_rawCrop(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)); @@ -584,9 +591,9 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog } } - if (cc && cc->has_rawMask(0)) { - for (int i = 0; i < 8 && cc->has_rawMask(i); i++) { - cc->get_rawMask(i, mask[i][0], mask[i][1], mask[i][2], mask[i][3]); + if (cc && cc->has_rawMask(orig_raw_width, orig_raw_height, 0)) { + for (int i = 0; i < 2 && cc->has_rawMask(orig_raw_width, orig_raw_height, i); i++) { + cc->get_rawMask(orig_raw_width, orig_raw_height, i, mask[i][0], mask[i][1], mask[i][2], mask[i][3]); } } @@ -594,9 +601,10 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog free(raw_image); raw_image = nullptr; } else { - if (get_maker() == "Sigma" && cc && cc->has_rawCrop()) { // foveon images + if (get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images + raw_crop_cc = true; int lm, tm, w, h; - cc->get_rawCrop(lm, tm, w, h); + cc->get_rawCrop(width, height, lm, tm, w, h); left_margin = lm; top_margin = tm; @@ -692,11 +700,12 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog printf("no constants in camconst.json exists for \"%s %s\" (relying only on dcraw defaults)\n", make, model); } + 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, (cc && cc->has_rawCrop()) ? "camconst.json" : "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"); } } From a9b8ece33583727ecccef9d3d1be374ce79cb391 Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Sun, 1 Jan 2023 11:01:48 +0100 Subject: [PATCH 153/326] Add raw crop for EOS R3 Fully fixes #6420 --- rtengine/camconst.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index be7b3b800..69b272d23 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1226,7 +1226,8 @@ Camera constants: { // Quality C "make_model": "Canon EOS R3", - "dcraw_matrix" : [9423,-2839,-1195,-4532,12377,2415,-483,1374,5276] + "dcraw_matrix" : [ 9423, -2839, -1195, -4532, 12377, 2415, -483, 1374, 5276 ], + "raw_crop": [ 160, 120, 6024, 4024 ] }, { // Quality C From 21a7c97ede0953e1c87e7c99d14cfc92d506b80d Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Sun, 1 Jan 2023 11:43:54 +0100 Subject: [PATCH 154/326] Multiple crop support for ILCE-7S Fixes #3960 --- rtengine/camconst.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 69b272d23..ebe195c60 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -3025,7 +3025,10 @@ Camera constants: { // Quality B, correction for frame width "make_model": [ "Sony ILCE-7S", "Sony ILCE-7SM2" ], "dcraw_matrix": [ 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 ], // DNG_v9.2 D65 - "raw_crop": [ 0, 0, 4254, 2848 ], + "raw_crop" : [ + { "frame" : [ 2816, 1872 ], "crop" : [ 0, 0, 2792, 1872 ] }, + { "frame" : [ 4254, 2848 ], "crop" : [ 0, 0, 4254, 2848 ] } + ], "ranges": { "black": 512, "white": 16300 } }, From 646065f64310aa4d1e83a5a2d2920ccb80849b96 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:22:47 -0800 Subject: [PATCH 155/326] Remove unused code Remove the preferences code for selecting the external editor since it is superseded by the multiple external editor preferences. --- rtgui/preferences.cc | 129 ------------------------------------------- 1 file changed, 129 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 2c993d65e..85816e39f 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -34,8 +34,6 @@ #include #endif -//#define EXT_EDITORS_RADIOS // TODO: Remove the corresponding code after testing. - namespace { void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::string &labelText, int digits, int inc0, int inc1, int maxLength, int range0, int range1, const std::string &toolTip = "") { Gtk::Box* HB = Gtk::manage ( new Gtk::Box () ); @@ -1205,78 +1203,16 @@ Gtk::Widget* Preferences::getGeneralPanel() Gtk::Frame* fdg = Gtk::manage(new Gtk::Frame(M("PREFERENCES_EXTERNALEDITOR"))); setExpandAlignProperties(fdg, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); -#ifdef EXT_EDITORS_RADIOS - Gtk::Grid* externaleditorGrid = Gtk::manage(new Gtk::Grid()); - externaleditorGrid->set_column_spacing(4); - externaleditorGrid->set_row_spacing(4); - setExpandAlignProperties(externaleditorGrid, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - - edOther = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EDITORCMDLINE") + ":")); - setExpandAlignProperties(edOther, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - editorToSendTo = Gtk::manage(new Gtk::Entry()); - setExpandAlignProperties(editorToSendTo, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE); - Gtk::RadioButton::Group ge = edOther->get_group(); - -#ifdef __APPLE__ - edGimp = Gtk::manage(new Gtk::RadioButton("GIMP")); - setExpandAlignProperties(edGimp, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - edGimp->set_group(ge); - externaleditorGrid->attach_next_to(*edGimp, Gtk::POS_TOP, 2, 1); - - edPS = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_PSPATH") + ":")); - setExpandAlignProperties(edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); - setExpandAlignProperties(psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - externaleditorGrid->attach_next_to(*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); - externaleditorGrid->attach_next_to(*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); - edPS->set_group(ge); - - externaleditorGrid->attach_next_to(*edOther, *edPS, Gtk::POS_BOTTOM, 1, 1); - externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1); -#elif defined WIN32 - edGimp = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_GIMPPATH") + ":")); - setExpandAlignProperties(edGimp, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - gimpDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); - setExpandAlignProperties(gimpDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - externaleditorGrid->attach_next_to(*edGimp, Gtk::POS_TOP, 1, 1); - externaleditorGrid->attach_next_to(*gimpDir, *edGimp, Gtk::POS_RIGHT, 1, 1); - edGimp->set_group(ge); - - edPS = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_PSPATH") + ":")); - setExpandAlignProperties(edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); - setExpandAlignProperties(psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - externaleditorGrid->attach_next_to(*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); - externaleditorGrid->attach_next_to(*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); - edPS->set_group(ge); - - externaleditorGrid->attach_next_to(*edOther, *edPS, Gtk::POS_BOTTOM, 1, 1); - externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1); -#else - edGimp = Gtk::manage(new Gtk::RadioButton("GIMP")); - setExpandAlignProperties(edGimp, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - externaleditorGrid->attach_next_to(*edGimp, Gtk::POS_TOP, 2, 1); - edGimp->set_group(ge); - - externaleditorGrid->attach_next_to(*edOther, *edGimp, Gtk::POS_BOTTOM, 1, 1); - externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1); -#endif -#endif externalEditors = Gtk::manage(new ExternalEditorPreferences()); externalEditors->set_size_request(-1, 200); -#ifdef EXT_EDITORS_RADIOS - externaleditorGrid->attach_next_to(*externalEditors, *edOther, Gtk::POS_BOTTOM, 2, 1); -#endif // fdg->add(*externaleditorGrid); editor_dir_temp = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_TEMP"))); editor_dir_current = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_CURRENT"))); editor_dir_custom = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_EXTEDITOR_DIR_CUSTOM") + ": ")); editor_dir_custom_path = Gtk::manage(new MyFileChooserButton("", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); -#ifndef EXT_EDITORS_RADIOS Gtk::RadioButton::Group ge; -#endif ge = editor_dir_temp->get_group(); editor_dir_current->set_group(ge); editor_dir_custom->set_group(ge); @@ -1296,12 +1232,7 @@ Gtk::Widget* Preferences::getGeneralPanel() f->add(*vb); hb = Gtk::manage(new Gtk::Box()); -#ifdef EXT_EDITORS_RADIOS - externaleditorGrid->attach_next_to(*externalEditors, *edOther, Gtk::POS_BOTTOM, 2, 1); - hb->pack_start(*externaleditorGrid); -#else hb->pack_start(*externalEditors); -#endif hb->pack_start(*f, Gtk::PACK_EXPAND_WIDGET, 4); vb = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); @@ -1773,35 +1704,6 @@ void Preferences::storePreferences() moptions.pseudoHiDPISupport = pseudoHiDPI->get_active(); -#ifdef EXT_EDITORS_RADIOS -#ifdef WIN32 - moptions.gimpDir = gimpDir->get_filename(); - moptions.psDir = psDir->get_filename(); -#elif defined __APPLE__ - moptions.psDir = psDir->get_filename(); -#endif - moptions.customEditorProg = editorToSendTo->get_text(); - - if (edGimp->get_active()) { - moptions.editorToSendTo = 1; - } - -#ifdef WIN32 - else if (edPS->get_active()) { - moptions.editorToSendTo = 2; - } - -#elif defined __APPLE__ - else if (edPS->get_active()) { - moptions.editorToSendTo = 2; - } - -#endif - else if (edOther->get_active()) { - moptions.editorToSendTo = 3; - } -#endif - const std::vector &editors = externalEditors->getEditors(); moptions.externalEditors.resize(editors.size()); moptions.externalEditorIndex = -1; @@ -2083,37 +1985,6 @@ void Preferences::fillPreferences() hlThresh->set_value(moptions.highlightThreshold); shThresh->set_value(moptions.shadowThreshold); -#ifdef EXT_EDITORS_RADIOS - edGimp->set_active(moptions.editorToSendTo == 1); - edOther->set_active(moptions.editorToSendTo == 3); -#ifdef WIN32 - edPS->set_active(moptions.editorToSendTo == 2); - - if (Glib::file_test(moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) { - gimpDir->set_current_folder(moptions.gimpDir); - } else { - gimpDir->set_current_folder(Glib::get_home_dir()); - } - - if (Glib::file_test(moptions.psDir, Glib::FILE_TEST_IS_DIR)) { - psDir->set_current_folder(moptions.psDir); - } else { - psDir->set_current_folder(Glib::get_home_dir()); - } - -#elif defined __APPLE__ - edPS->set_active(moptions.editorToSendTo == 2); - - if (Glib::file_test(moptions.psDir, Glib::FILE_TEST_IS_DIR)) { - psDir->set_current_folder(moptions.psDir); - } else { - psDir->set_current_folder(Glib::get_home_dir()); - } - -#endif - editorToSendTo->set_text(moptions.customEditorProg); -#endif - std::vector editorInfos; for (const auto &editor : moptions.externalEditors) { editorInfos.push_back(ExternalEditorPreferences::EditorInfo( From 3423a7ac55451ac5504f982787d1a39043a64d4f Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Mon, 2 Jan 2023 21:24:15 +0100 Subject: [PATCH 156/326] Support for GX680 digital back including DCP (#6655) * Initial support for GX680 digital back With help from LibRaw for decoding support. Estimates for color calibration are very rough... * Small modification to black level, add DCP --- rtdata/dcpprofiles/FUJIFILM DBP for GX680.dcp | Bin 0 -> 65374 bytes rtengine/camconst.json | 6 +++ rtengine/dcraw.cc | 37 ++++++++++++++++++ rtengine/dcraw.h | 1 + 4 files changed, 44 insertions(+) create mode 100644 rtdata/dcpprofiles/FUJIFILM DBP for GX680.dcp diff --git a/rtdata/dcpprofiles/FUJIFILM DBP for GX680.dcp b/rtdata/dcpprofiles/FUJIFILM DBP for GX680.dcp new file mode 100644 index 0000000000000000000000000000000000000000..dcfc174c70ab74330c92ea3c193c86f98b29ae7a GIT binary patch literal 65374 zcmZ_0cT`i&_dN`PpfpiHP!s_bQ7oV$*w_<$@4eFONbfyB5?bg@KoKky1sf_LLT2m@ z>;(&A1q%u`6w%*2`hC~>_{W>IvhHMZ6K?iBbLO0V_F?ACMU%V8$;ow-(>~uxPM41u ze;S=vk?YEjb^K}ke`8~LIk{Em73BCqt~-CO{=e~mpK1HQ&u-;!em}1$r@-gJ`1r?p zRk^+W8zR4X3m*wIAziT!;LQPhSOJ!u{M{J%bYDIr#VPY&fwnf z-~SzhI{kfZ-2C^o!pOg`Ta^ADr~djoAHy%~zw=-5ANk+0W8mN8f!4q8pJ@MkT-x;a z*k<|n{f!*P|IUy9zxTEN?{&M;-}(Q)>s-Zug8_g3f4@ggE)@Sg&5QzMqFdYXQ#}~w zCh6qx9dBF>4nR=CXVQ6g2p*sEMfu7O((OnH3gx_^y`_%G9}0w@DsCqf!fI+ToOkEfb z=sDqdLaQvTQG_E6+u-!ZkS0hXv8Z?(G^(f2gZrW}d(k#@T5Cr$tzwbAdn@4g@*93>+b=q2#Jv63ETS9O)Z!O37zsFyk!w!4N zY=^9an`JOAjuaF9(cWl&9)P0nFG=b6P z?`SofcBv50m+*T$P({}48H~2h+tKMus;t;80FN#@!Ds3-*(2W&yb5rFlSg;@YPJyD zKW~HAAycZdDh$))wqfA|3%cQ97{)kkLFSYpbV6wu2KCwmk4imSIwlN5cR1qMpw4t= ztq@1G?D3=HqpUSw2#cEam^-CSHoQ%Uq4U;Z^;lKZ^j$!!MLLi@kA*1mbSbCuFv^5N{Oy(a%Osu;@iNo?rLDk-?n=7i~na zl6hg>{5E2uDaPfO9$4P?g8X?(>sm&V6rvE=?tTa4SjM%L$O7?xMB!$k80*-3LD zn!Bxo%eit{pM$|5SJ$GZ?+e*jjR0s}S_{{QiuB2HKd3(7_vKm-YOnrxUjM;9*bD~H`u*yKQ$9@($<=0VVpwh8h_S1?RNriqV7Z|q6#VFEp&$z8KkaaM%=)U2 z_E9L_Y75goPSs)aA~7>@J(AY9R*yR+Mw$6~xZ97HZPOQ_zutQ2!&mmGEF60J>kmF`5A=-=iehmlTP< zbNz5QL_=_IR}2CQe6aIJH^G|EQVbgAjpudhg46HfasR0&8c%i=_?0Fi_nZf8H!BJT zuSmw{I(JNT`bn~`q+p$aJGAb+Cs&$MQ6J-mD*cD#vRxWx^>xFE;A%1;J{9XPx?<1i zY|?`!qjR(?Cgix2MOPD1wAK}sDHdeAd;%I ze*rml?%Q8)zyQ@xU|KP_YU_ylInQC46%8A62RNK9!K8pFeAr-*`&pS)Gm|3Fugng| ztEAO5A_9}UI{t(6)>&ql@NE+kj|YS9E+OffA!zLvgm3=e$k#Jslm`SL;*`3e?r02} zU;1Hrg^oaPRy-1&eR1l8u0Xp-659Iupth{1VB(4tczpAMino^F{ggC({NahCZ#4u9 zUZ=yv#1ju)y9x$P*nt=?4{TOY5KJ=9MBkV0m=yb!Xza?wdslbF^>|L6EXc%89e1$a zSIGX!JCJ_U4Xu|BlP~wu@v+biXTPTrnQI#QrMsbWWhfD7q@p&~4ac9XBX`FoV`GpT zZu?CmuY`%%W$6an$5!NPb3ByNUD0vLf(%NE!?q$9q^uc9mUv6yFL8!qkrg?-BNiT$ zw&U||kmQdsnE!qo_NdGtR-0pRFk>r9a_5mxjnPnAvIRb7lgWQLI~i=ow@oeh59gbA zHe&gzUFcjUMvdX7e{l9J*Ce{jwI(8Q zms& z+l~*T$B~zNB)HLM+dnwdP+y`b=ZUG$f^mLm3pubtj9pN(a!IM?Wxzq=1mS>@jdtYjykep-cFQ1@j$F;4Ow+56H#p*c%8t=r_c2*<&wFh65*`tg^1rfNw>Z6 zxY)%DE8b)gm%(wcuk}Q!UKUw@E*5&8p4e!bMOOI6fN;F*m!m z2}Xh^KKa<8?Sr-7dJ7JAF2JvY-dG52L6lwrRxI&GuvA^3Se}pGoxD-fq9o|kx*rP; zdEwL!IYIZ7eW+UR1Ahk8L=`JA-dWaFTj7y2KsBUW)c zFn*>N9F%X8lY(@ti}u3sPM3+_xKwnn_d=KFjHIkjMy8cF`dq6d+x8}6T9h{;Zk{Cl zIwb&CyE#2AG0-*V(+(I1?{TD@`fUM?B- zjmJ^kX43m*ku!ynunzP52j_+fkI41BF!;&yoJ37u(Dz0H_MHmC=nEqRhut#q!6^{O z1FQvor{rR?WdH^Z87FA#yB~8*{J|tv0_(6sT$=6&>5P$rnO6=#hsPunlFS4qyZ_sO<1ZKL0Fn-{Ts2&|;iswGOzUPg1E5DHTC%K5@c~PcSGkNa23kM#1QPq<$>_gER5)!ywTy zqFWG+vY~!Bu<*#A`9)@a|KJ>RQ(iFZqXfEYA?WqlRIuGW9deg~kYzni@bhafp7;l1 zzXuUGE-1v;sR1bNLj*>4C72I?yeJ+oXsS4Z0#`r0KR;Tq^3pN9sPl!Tbg00kz7&DJ ze6PIGUl2FpIDWzxZ3FZL2fH0dPZM90?Gc9ST?~QwgV>!Ue;H@H^2{w9VLiQuf&R9zL+Z;EVylT8tXU? zYqR?aRCP{6{je|2^H}A(b0u2N`C?h9n!v;36b`ofVoiaf;Nz-ttRL-%)9*US!yly> zo#F@ig`dfR*uyCK>W8mG-x0N`2hnw@KfKqzB(}o~kXPi7!F%h;jD>sA^vxft2kOXz zvfX$f;FyfOOAc+?iJP$jP|~?c=-Ny;Jq$n_YDh|II?9I!V)wzzB)v;2c8deCdi4cz z{!kKZo&~~o{#mj$A^|f=5W2)t5*ZqY^*KRs*QzG+Ik6b?D+soQ6-2<}4MKtuKu(fq z?oXNoLC_su`3L7dw*vmbdAUO$!BpoIH0XxlS(vq8)0%u-zYv6vI+F#PLQAnZA`nGE zQv`9tPveYT0A`vK!Rv<erUP>nauxn8gJ+MBT=b|)V?dj z@OpnVe0f3?HA`{AB>+#h-z5S5hp?kP0N;FSNoxNCm=nPB){aZ$Lg#$EeZ%*W4d=*% zk$ZSv83gN%lzcgmgY1eR#6CDp6t`#dSSuKp_g9c1t~+o@5{${!C&{mpG#vgAjAgx# zlOg?6aC=1vG>#o5Rp%3NhlRjfe3&dtiN~Ivp@>K-Awwim+@2i@MZF?YRU$=6Z3vF` zKS;(eibYj?2=320{Rd}Ng`j_MPVHkP_}#D@`T-#rUtuYD^|c%iO+#>I#00^6^-Dl~ zFl_9`3*^#oz*!uO6?ZKK&7OC_G=kyYF;s9;<1Ple2EnM!NN_`X8|MoH5qn8T(Bs(+ z9#;gwYf)E$TxAVrRQf|Z{s$p9uOO)_zel%Tkr&z*ff9e54!lp!TQCfD48Rx9tK?@$ zB}DpxSh;|ao@OWUz9tY!kIPB^=%eW6AB1DyjuO+|DI53PD(2F8MNM7d9J)!uQNBvR^9;X11ZYKQWs)4b8y7oKR>h zWRkuCsYrYripDM(MD<4!V)TV*oSsIs_a;Dpr4YdtDWs6^j}y~`c(5Un#9fHP+CgCm zUYtS}OqJr5eAqvB{=Ynu*V$fzUDJ=jlwZSQ=^(+cuo^5}8;XLnLj*S`J%J0qhUkf= z0_pZwSbIN|?;l2jwak@T=XuBLh!I4mWT`eN>Eb?*d zN+^mlgd}YK9*k}Z#h^!lWboM>BpC`ZAlQd23(LkSCm}XBx|2;oJ23L35CPwui4xBR z=E{X3KVch*>7IgVGs3VxXEV8!lZYAdVMutgk-R<|hex$xxPEOJA)n$ghI33l?#swL zuQ)`k#- zNMks9D;^?0>R!W3GXgIAGRYFNr!W{7f#E8#WMt)CY;ljkr{WNjY+M7QLlJNtv5nkv zIge`}B4E&M715SfW65X{KHi&6BG;88IZy;yZ$chiK8BeWMR>n`3@NBAK|ftFy1EZ1 zU5$%Sx><}NcLtGO@Ajdvl5-hLjER*-9twI$kYC=Hh6g!i_TN3cTN`wQ4 zI+ME6IE-x&VdQizqF)sUp{D2`oZmM*C1*V^!zz*6+w(@EliY}$sY1-{@|rXSen%)@ z3te)b5K)yJS$-@GH}bBNJ3jJ6Xd2Fl z+zaSsEkf5h4Jh=N;j_I6CUWPordI{D6GYhKatO0*OW|BCg3aA*h{qhl-H#$PiKK9o z6ruY7F|@cHD^A+ac`q@%Ip1osA`e~S#b~|18a=9ZVc~f(zVDxlms_$B_e+e(Hv&vs zoPixy5_DKwqnAf2=DSHyHNhP7&Lkn@fCNL$!FlL7xW1EM%tJ$bK9Ydr6D06UG5tHg zUV_Pb3iz}qp5J%LKRD+sDk1lN)WCuJhfdAK#H`^xW;k+RbgzJX2>6W?Bf~I!Uk<7M zsX(^0g+X^{66cx}Ny+|j^z{rSxrz#;cvJ*l?O8@v&;1SCoe`*znUcyu-w@Ljfz@?i zP}hi@3oc%09gk@3H$q%Jy>Mh2mM<1#ROAg`CBr)KrUA>~Y2o2lB zu)APZeKTu6W~GU-`<6}hzWh8Kr(*c6o>y(qIR~xp#W>!vs=BH$3-^0VFmL>Z>NBw! zm@-3x+Q9AA*Y~HQm$w96bv>&OwD34&uLSq^tg3#=abER6g6I#P)zwcE5Lp(9!oi#V z%Y&TqpG@IA@1MtCo`1wOSF+>&EnF!M#f`)3iN&r@hzS>B!ozvQxvdj< z=okj8&~ap_k1{!B6ONlR49WCGT}Yi=1m>RUfNYHtdA2J8Bi|Kcva}OX(GkJPW*Fq} zv?F$l2%;a2r%WSSp->>gsdCk7VeV`EzAM7)Ah+sw%OAn%w+N{}^QuEP-9+mkF?y(+ zukLi}67&~|apm)~YLEU5p21?=DE?7>(ESv;7xQzJm1P5j$8m-8-HlBevh3l9VW%m9 z&jKBpwcPeuAJuu%d@=>S>#_beZPW#$lnQg zVHSl2R{j6X51tY*!@Qhepd*vm7Kha11BJ$kwmO z#_EAlXj6-oof*0VrCXx#JU>>}Zk2|Rk|`0<$RWWpINu8~07vrIO-tP<EE`hD5_U^Sq2^?0}npG{&`^mu=5VL(Ao8w2ZhQTU(P1svpC7fhyT^ZqJ{* zW8h|XRxh(I2eoL^M1)1wd981^N%3e*>CEIKx;OP5EMuzASKQ|F#S(EI} zJ#BJ(ju`8Aw#oL6(jX6?{pTMP=|Nv5k~&p_`W>n?cJVI^iIbqRK$DK%(~L>A5)|#! zrXuSGyyP6>$x>Y!V}2Lo9e7ODvo|$WyoSZ)kr>>pPn}1cL#}odbXN7Hr&d*Aqem3J zyBg5WbIY*fb`;_#_oK@7N0DL`jWbXB(dD0u@tW5>uFWx|IX;D$A|HdNsfN^c#Xh)h ziosr)A&rm9l>xR_ucqYc|jK#G|LwYSI9m9F;t)r_Uz3ZO> zM`tOrWP0>JoYS96v9P`mwTetceIc(WIraK8ulYiXr8W9g$v6QEE=d2u`GWgpSykT_ z;5*NiHnz!1j8w^ep5w?hb)jwwJ;~~=;h4s2&Gvr!L|hnw1%`T5ZcZQa^Qs8`>kX*U zIz1viCdTuh18C7+O)_wn1mAX=(R~_S$hCtKoH%Ylduz*){BIIOp0cFlt3SX5k=Xgb znl3hYhVOCQPg;$qvT^rt`)wpXcAiN4o7KQ$0gq8P+EB&y=dq^jB3K}SFvzLnsydknVE6i}0`MVQF71)A#wR6Le*t-RK# zuu?#muFS)Si?R4+BcKbacj3o)Dc)-dsG>s_Rvwa~`$IyvOw2%=aU3M6Hh*yLof(HO znPX@J$N6sWc(n6t_TG_*)VerW%(412e}m75z8y=~4N1U}A94TSyzGh!4S4nq-?|8~ zxZglp-Mbr6o)w0IZKLR}iM`2(9G-)ePM|j``Vq6%2n2~H)3K`!Nu`MxV;0Y(Nm=?t zj{8{KPxI*Wk{-mkPy*4|C3M)@uB1#Y5=9qQP`9UYq=N59Gfu3gnqNPnyf_j^zpkY( z1D|7=S`^Py*3+c3_p#eI3aa02sqTqd)V_&AuXlE|@1qMywvEQmG<$mEgAAANM`Ndw z106;yaAi>pvZp%Gf?>zepWElTH4fBO|1dIbY|^GNXqf~Xh-#)XW%r6$B&C^=^bv*4d;0M zc;Hg{l;fqKF+ zzrkK?;5pmEh%oBCVmA)W;59j$Fj{*v8@LsZUSEW?yLboW*CoKIB#7STIP0|}z;UbR zADqj$zmQ$@qjenTy77rHAL8|AK3|fE6T^LJxkUn6Z4>{&`QiOlbW10?~}8?pFtqSG7Dxn3YJCHW-qSN(pAw zCQ)^v4!JNl5;ZN!ROFyaT2JwMe02)FlirE!?;nLwl1f*<_zeHlC}{6XrS#Zq4AhE- z>f2PBeC83(W<=vz_cVIb=@!sG2CMp{(bF@opy_Z77HXtXYwfeRNn&x1pD*2g8n!oM zvAHaj7GF7uVH>0f^+}~o0Y~wnO^SN6RJvkkFS{W81%s3wVf>P-9Z+p?D zEFRScDYT+jE?&${z^=+ zB;=?`=>v|l-!?v<_IJLcG6@dDV(FTZ2^f%^^bgK9>0wl^L5Wz76+&r73O!$~PZn{# z$dtgHbkl@E#EnGYq0%0DR%0kRc2bh$*CI2?|745`~hYLMrV34YpmQ@!?bctBFH~G@tg_Rf5aT@$l8kr=1mxAncX^Y3hD@N45`pxn5+M z&VJf8#qGJvlw?fG%>0A1Pir#v z#P9rr^Y0zW@cR6Beq2j3FnKQx=6};|aLPY8tN3M5U8X{^X9}?;-~f#qXh;I@gkjm( z53Z(%>y5eMDG~`&s%e|0F6r|y z5^W0AG{#h&INS2P>0}k{AFD{tG;s||P!$ax{v9a+(U@pcMJIfE3lp6fuFpA5zssJ& zx-Hb{-FxWAu^nr4nzrq%!I_`j$L3bjs-73Hc`vtHol5#YrE8+&!hx*$rUt6d4%J6Na>Uek?RSXU6hHvN0O0v=kOn#bGN0S|I!2W3Ag9afvG5PE}{3i zJ&(GOg33dG=S>ErqIh=&^;sPUPp{N}aK5W_h{l}OAf~H0*NQWAMAiUuhVvLUuGeVR z{ShRU#~9~_-=ddhk0SL`#ZYU#Lo;6wCyRGTaCP}z8eiO>ob}_e?!`M)@1-tD?;C~K zmfO_4n+Dl>BnqpoZd0G|&SdlKXb1{!QIUB&wBK>PSMOVN+spSDpB#f~;Y~Uu@frFd z7Iz=spseaXT$*E1V|s&{=wAofE#1Ra3Zt3-^>xkB4{U0}zqBqZOtOxM-t z!Et#q+PYn)6XkMv{+@!yZWn15$JzU83Veq#dXwAp`@~deZLXw`InGm;ry)JzEbU#B z!1X7oIQr%+74TS3V?!FO3!l?byv|~*pYadQ36|&Sq#HfRovlL7?LMS4`V1zzeZsM! z$1CchI-2M|j=-W*Z|P{CG30?z4EFv#jhtgn`dpV_-2V6U%klvv_y~_BeBaSrsUB%v z7ll*3-_m*Q8f0*%Xsr6(M6bChk*)`$5!knhrmJ_L+v*tTp^;8J_yO77Vqv@THEkI6 z0tE3XLK4;?5u;m%O zX;6uYq6DOGY@q#Sok0H?d~e$Llum0oj2zV@^xIlb8x#&At~Lo_9#3eHC$AYLC&MEA zF>SHhgN0n*b7jXP`gBSTe)dU4PqjLl$#G8P7^=U#MQ?DNMJLjD4dB`zoR>?|F-7qq z9WED-xT|Ss_IgYMd&XkQ(sUH;`9Ll2^Zjb|zc{;VKBOZ?tCEGbLaaR1LiaB)Bxe=E z@w??GEodAKv6I)$vKl#kWM>j?&>#~s2GbOyMEGz ziuGu&h()1SJ5}s=2m3swVAFrl7xq_i&^!*Kdw!=TJI*4YISvlbztI^Pr%_lOkD?=A z>11*eueK*ZH~b52^*MsC!xOP;>$tG6TvJ$Q93gp4~`~bQLk1yl~vp_ zBA*i@uwt(oyLoQ_G3UIl#Yc5^e~J+?_miOJqB=XgM~@WwL?Yw88e3eaL2SoIA*NoH z?H{g0lp3SpcteE++W*33o>L^!jN%|QK+6kNLYn-18Wf-fBB4|}<72>AL4Ps2G$2d&YKgLpdEpPg*`;~%QD zGH^Yrm5xh_z^`W+$ZG#dgKZ@!-|;Wb$(3?!U_%?ObFHd&vN~I7+Kqg=6^0{?T5P~= zJ+jd$0_HPx*{BwMa_^G}JrC-!J~q9`i0Kk+i`8R}Dm_Ta{78gn>9UH|T}h+?_Zu5} zvTcjyiN?(+B%11Q)$A864v9uVw&yL@R0_O*| z1Z%Q6MYT}hCdJu+ZfvRl1#~lu!>&LLrqYw=Derh55vInRBZm*nYnfF*yLauR?O(k+8d>~yegSw6bX&PM(oXI1)}mJ z64RF(vI)c6@ToKkZ<`HRe&Sn9+YpW8lD@3nr~w84X*YHHFr~ozsNi{=B&s({8gv6T z@jUNn&|}g|m+@)26yf%|?8C=1DC!r7MCG0=tj}qDd>MzcW!g-9^91a<-&p0P#oRTH z;FA~k&l7vFi)RiX5Q(7OyR-0@`|+S_61ui_V_BQ>@b-2RLZ4`GMe#0V>`umjd+O|o zLnf{|@qF*08oS4RtgtFV2NF-Py0hkI>Uvh|2r@SfYIglJ|u{^vQ&& zj#MU^#t~f0I)tf?P$3T!MUV~~$~y1rLWVr#oTu(kR++6peBVp(v$Gk?SNnmfHJqP} z9n73wzJqN-6t=eyVp`)HaAHa{&TlbcpO@c*&(~-yyE1@n?Wn=K12LGR)}Q5Hxq$bZ zV&P|E#7=rs7@JA4ynjEIS9=N_T>E>YdtcVK`~)O?zc0|%XBX}s!IZRkd|TFwC7(Ko z1C9x>KCH`De$B@nu9-9M+mlsB@4**^Bq;9GW=-xnP`HzXWh1m$LVgzB?N7$5Tiscn zQ3mq-QVBG6+={c905T!=o81~EDDd#Lk#@W{#$ z?8mqc#C3$DefTIgV6!~AX)D6+6QkLX!E)qSo*0YLM>Fk)Z}2)UL5k}r<`wh~zp^6H zaLa;Czw#8mj#1d!%be{oy^EoJqfxPLID7c{Dr~PuqbYqTd!>2~5fPlHEgZsH460x` zF&4AKP1%5VC-J#G78lG-SpEE?kjbP-KHs06v*J3j=r{~sZp4nH7GU*C?l(Rdu-R+& zLS)7{g|t3wcF1nX$6OlMfj|FD#KZ~v41=qe!$L=9& z%ztVmLbz6S#0OMa@^Ne-*CC8| zjD*fdYqskRuZ3A~PPnrbYhQF3N1CJHZ(zwvo>6?~vBzYKQH(}b;M(#S4AHY-j`F1# zsS%65$A+`jY9;Ww6pNS2Ls^cr07Ijt7-Kn@xrXjR)qL(ZmYJ}yr@OGYS3G(K_h(M~ zGBJ|(3Culi$h6L-;mUDt+no$pj%70URf(9tS)a}0`scl?lW?s`kL`aQ3rCA&%!=&E zHuHMO?JgA3iZKqG8igTN%XO3f~Iw!EiEgEwytl7HNhmbHZ2Ae)v zvK>nb5l|O{or_1Yn({s9ksOOfQ_Y#F(=OyJkYe%Iq0HT92X^=1JrzlV*?|`+7!w^h%4}9~yw=+=ncj-kp`L@`f?@A*q)&*xCj+OfgPF4|g?oxnetL z8_!3e!WtX4Am@5IJok5D9%H@GH#;4@PAIc^MP6|2|1Zu8*G*XP%>qo(5+b|%ICi#N zhJ*9MFgQO)S?AS#y3vWjr(EHM^e8yxy_b zn#H#7#Q3}z{JLey-rUVV>55pCEFH;4UrXlPuoM+8!`X&koMXEsMe&v)tV9%zqp5M& z?`XohZWLqLDqdrDHD-@?gn=3+z$nFlRgDZrPGbVRZue%V%Y9IBBoPs#blH~*H@pu> z!lR>FtZ;}E22W4MwZ)oD@%Kh-(Mmz4p*mafp7&`zO+olT6}C~}0Ifr*xM!=(f(z`B z8Jvb8HxyZ;p)FR=PsfBiitK^M7OZ}ghO9jb%-(u4E-vDF(Eq7-C$^e0QlE`N6(Q!G zn8>PXk7Dzi%@1ZlUY7GiC)!W z)E}M3)E*tiD4xH(IWd`?iYP=4*O?sIN7$IeJUm1cmX=RshZbZbwLJ=l+sCnh%W06~ z_1>c_%rp#{^HMq>Z%Sg4l{Wu>3OVVxw!i1&k7Iqz*8 zuqX~!`uAtg7WtrDD;|1I2FxPH4Uu=_@wB-Yiyq;E>6u(-d|Zc(Z+F7Qb%_W(-JSJm z+=>tVlc21i!FIN6#<8X(bPrcybF??1*WqN;j#FmBxf?LTCk5XJDY7A14p2oZF3*r> zDeZQ+q@0F2s}8z&yDh{w((p!2o(*6Q&<;(*3nzK@s>U88c-`xNajuRY%skhnVnHV% z*CK)uw|%&5!s}KAGgvbBlS3ATBdK^c%e#CCTAWkb>^7S{<2AU`A`$kEp2=D+b*Y2R*;lR+8}W$iUu9g~J z7;D7gz~Mg3(AyJ+*W%zWugCJ*+;A(F>r|4o*xr3E_%tVh>o2>pTCeR`qMnF7+f~_J zhiz!MmWa@!%B+6d7No`{VdgMJ)+1&U0_G=U-9tGxzj_0TIM=b9=ck{P96@fTU{3NE zdc@Wq4k@V!)A&d|uh?QD=Q=#Ef1_QF+2NIX8pgN%q~knnQF@cx(Er%;g5QIg$@OGd z{|LokOTyH6obo`6+jGkdw(N2aWFy0IvDa+2BWO2_W^#MpJCi9++KEr|L{RH8ja|RX zb5Ma8Q4HAd;ZbD+*!fhqDRq zBVaWm8sUa!td_6$$1kJtc#O&o@Ilcn{9$1o*iq zvef2n_~4g_erM%a=GQG~woC$z|3O!1ZN`4CiJ9E;iB6cj5u=Kekx}@b_7gdxa&rpy zo_I}-?%Tta^Ku!jZ)w3e2h8r7id*a7(wzc(e2q`V@I7CtL$)pKQvSucd+8A7&-Y=+ z)=+e<0Hc{{*uk}4eFf85bY41KwfS28F`XG#rXj%~0_`uSFw1<-tMn4#_EoT_&3rBL zJ*LO=vFt%x96oaG%InXgScGycesHanozHN#g!_zlu8~-kF_>LHB*u;rQJ6PxAUnV{ zAm+S2m9fEyB~Rf!1$n%$EWR((+rTwwt733i)QipV3PLcio9v#b!%PCW&h%<5jy}<3 z&(HhdhFFRtJRjUS%?l?4ad@(}3%mB-9d?z@n+&t{ z`)&$UKMHYg`&6crl!{4QujsRK3Nw(T!1YTwB9r;O@JT}E%Lr&Fk7YiM@#r|u^YK;- zraVfDfGn;j)Hh>~q|xZSQG)ev2e4(lrX4ak67NL)*eI^yvTBUPrw6?mrQvwACkmgB z_GG7C3UOj>G~%!HU<0gq48U{7ls6hIVsj9NT#rFey9$%f=bGrKSiDtMW?p@KK_^Qw z)=+^>JLQG>9h^Je^^4B;^FYrNap-ROjTX*#!|CnuxX}3{eK^(yY6B85U$co0vfPe$ z_Y?4I(KFhPZCD$dh>cetQpw6K@UlrlL%<#CCESEHACgdRS4&Tw+<=)m$ru`Pi8}vu zK;XO-*sZ%lL$e(5(u&tmwp^sHmmE+kPQuuXTH1^6o22C5y47;!VNA-oTha4Syt@FV zJvtd9>v^s4@nrUCZ!*U6-f7J%ge~&mvFEjLhQ{sGV7+yHEFk^;ki?RUFJP@8+lF8MNN*4yXB9h>D-=se5bp8cpr?s z6pseA()_XB_*gDQ@anfz+}#u4d%%~H7xdS6H`JKKqt56Fef7Zw8|&gR{@6X5-okN? zNkD@A4eIi18ytC!&&K=;_3614O^t~-)At4bo-@4qR_d-|{(k`)sY#^=;pWwgU&GwcdDM;~^STA$sB^_#Zgb(F$hI$ zr}3<9LI8fu4@FG#L^h*u5I%7HJq}v4CL!;iC<=wM`Uo~I#~<=sCsys#pY^i#Meegu z6iRg2)brd=e&QPM>1u32oCog932|j!C+1(m|8Inv5WXir(a~nEc&;l%+OwDRXPYzT z4dDFM^E$dt!5O!yFl>IKIhy6DLK|&0?SU{6X zH{qAR5Xy`8(CQZ(@zhg@sX04olKMt8^LmHbiFDd#u>mXB3bAQ-A|0^Q5uW@SCT)$O zbNn4p$hjc>Kr!_jvH{_>yk|ZnoXS-=!sTN)D8lG{xs5Ph_OJeVfYg|Et6YzC{}AZD zwq$}{8=)nv8CiC?obHdsPfpVIC_A3( z`=Qs9BC1nuhl%`uP@Hng<+Un%MBVX4YWFPa7;2AsQ+yGepGGqp?Q#964o=sC_ZZql)4@89c*y&3WrxLd^*~2#+wF<%xncA} zZ%6cg>w%Lhfpk-w16G;we$R3@T16e8Z|9D=b{pxF00*4oz06+?S5f1k4(NBt6+aB; z(jWKiA-Lp%_K^$d!;X#6?;DEmp0lW4!A5+T7K)QUXVWEbH(}&8t~L6fxbFCeUaXLZm^st!cq#USEtMwt>*l9n8$9EkW|Y0E}zw%?_6>#)UdR^xoQ) zW!Egi1)(p-9D7d_zAnU8{@Y8RT%u1s7h-R@7mCgm(ydMlVZO{0*YCyAYcCgK$9H$U z+2TPvWJ|Cj-yLO7mr`HXRp`(AUSEHlL{*~J0Ty0x$+V{Ttn4s;j~C?6jH1ha+G9+H z7rg5%=s6olyq)L;TVg?NEjM6jnI{HZF{hfpH{ik`&;Li&S%yW~eO+9o1Qf9o8ymaP zS!YmD6tNQo6qQCo1d;A;K}u;v8YBc{?sL<2cjseacfI@l_V?RdT=VeAo-^m(XP>ox z3wLv;@JWTcVROt0BXqU+{zc}vu*C^lo5%CKW^-I!?t~ArQT)*q3;Yas!jjM-{F;Xa zW>44)&BwiY-vSHF80(B~sw#ZIaSOcg+lM#Fe}tw43#?z@iaXbP@@|S&7{3g*$MM2L&t81}Wh-#sf9vdD)m=P%c{ZK-JTU(EXz`lLLU<{=!}ju6@i7PH4{*aM z_n~4$97EbbSNyl4yC}0_C{Wo)^Yae=_Zc947%Li%M2Hv{c4RG)OMrFp`}ZVtFO-y0HxQepTU2i*JUh1wM-glW?q za7o7ti_-*QVP6NBM0-MLZW2mf+Cx#%6M~TN96Sl%Jp)h3+UZ!}VwIo?suCNE261>rGQm~-1(hgRKe2{&)NKoo)hn}H6Q1!_Y z(z0#Q`I`^)uU89=rgmuA>;KPszE|;`YrY$agt;D==Snkn>3D1mal_V}A)@KRNi++0 z!Eeo8;vqvV7?BU!=Ee_h;H(8lT}M>sHS+nRwUE7Q4+iWDeq;D;L*lw|gg z+%O=5W+`cx8l3&z;piHGq-Voqi~hJ{DS1G8Uki|}ZgfZ0UGh^LZIemH5c7n3p0KTo z!Ue+v@aayyqrzxmkB=M11kgEi+dM%pi}s}6{&1*UB-C0TsKL)a{mcbR(E6{f#ssgd+OdqB_VF_p3r3!M;5XR&g3bz#F7M=a|I z#IC(RWV2U0B0o6@DmNwyKV~{&K)}Cx{+oNx@Cuv02qflFVsKaSqDntVy6?v-_a35P zI1u~OoDpUqFLH4ZJ`Hn3zY*8DZI%Z5btOK`uN2-pYbwlJ_aLQEpYKv$0@GuTaNsY6 zYp$E2w95tXT`Aa2qqS=80p-?14J`}zVfGIn%-?vmJybC1;yh(?&%MxvG-=PLJIUT{_JjuU zm}-_xmNi$oqm}xEW!T@a?x!21BSO)vk}T;pc0V2;2!osTZj6)AIdpIYG#cY2BPO_D z#Z0=#oY@P7Y#*-ujlg`d?qu#~XH1#?Z(rBrQYK$248&XRjz?85c%M{d^bA1WuQ0ZTd?eQvhroGI9xJ9ZV?7VY z`jv%D*Eke9+EHjx%w!6Np;(hgcdTI%>~>KILPo{F<;*T-OkVYmcj%7$-30d8hcr7~ zqw%!n5ll7)BIa=ZJNx?Vn0GZ#$#8=FKC(WNA2T(^+-CR4~NrdjhK-Qq-h1v4S7)HFE-g@rnIv^EV2}omaR+`))gI7~NLGLZ8OM-zx>*jSsW!kE5|jE(Pc1{Mky3@%qFJjYfPquP=5IRpyfqzsa8%up| z!nafyRHw2bbl)`K@?jYKJ<96nnHE`|j*S`>Oy9{HYLS_+e^JZQdJ{)#Yc^?>jaX1>G|<%hG-#UhHSmU_abHS?c3_evhY*Ax%M)l_%bsHO5L3Gx{Ba37ZJ zIK_w7e3Cq=w?|^qX?}d$Pf5=LYdm$y6ka4lf7D^*S++4ndE@cre7trjWp@^nmv`?m{J4_FQV)1zvO)eobxybaA`EKRz)&Z5;&z2|1^Yje zc@y>_{eBbocX%v0FWG~6ug~$dWzQsGhL*T~EQi-WmB*^}yTLP;@+;0`aATeYG~TBP z8>g<#DkadL)Wpg){ZZMw6y5yu z;p4Daq5aJkoXN3A#0DRU?(85a(OJ0Q`aEV|odo}J;TUG=$A*v0g1_t_K3h`e}|Jgyoa?hqmF~fx?M)kt~RDn5DPoIa?JYE%-&Z=;mOf*DE<~%5^2xNew5=(7a0q9 z9*RDZ70~Ei%l48tt5D}S^(e=gzE%)CJ|0JjMG^Ch55SM0N=)pQ%Zh0ptox}F9}5n% zwnkrkUQh*{)rXk=KtH%DRYL#LL6${*j>)1*ls($U%IKa%A*1S_I&W{;BJ7VFfZJaW z;Nwa|ZkK&u^3h-~`rm2bpPH*A4Kda@yyhNn(LXK`9-HC%$YMUe=z(OGoGC)mwE6if zBN0YF*E9(iI*#oICOP84m^TfpjG_^E-47u<>(M+W6a7K=q~`~+?xT+(wRaLWA6m#< zMij#2b2_wtZe!i<97E%VJUlz>!yf<4gI`f0bd3|)pN~11ZB&NJ8Aa@zZx#$}E0H$7 zntkt`j`s!CIM=I+9hOgpT%Q_LT`DKdS|V1wtA^W_V)ksj*m6x3kMw`A7yTPS7@Jb`?jIA*?xh&E=Y5TD;!F1``(GgH#oc62>1nEJErzDMx-dmX0i@?^n_Q}AsEzh*>$r- zcsbUiY;IIDcen2v(BID(X-z?wu1KaSug8hj)^Sg zMG(aE_0ZlnjP2hafX*lD@#yb=kgX(5UFb>Je=37)lpl6zHsGC?ykyEXAB1cW{;Bf~ z?G{WF`$KF!fbXVtf`?{>?<8NXcu1nP zcPsL|4EVYy%6NLm7^Rg<~`#k6?*{W@V9aBpAP3dZh zR_tb|Ic(%JFWi<)TWd(?ae1DS~!svft>z+_&zjWNOaG^%DO1{Z;lY8 zX=Qk^AO&t}X2P@5Dr}#SgVZVG1g*Q(7>YNg1-`Wl%b4E~)BQglQ`{2GVzH?aZTiFjR!y>35RP+=wa7ni#vDiUeo8dlc3p%DpK|eqw|M`H1=Kt3V z8;EFZIoz;Eo%BAPMC8x!Xt+VX^SWG)&esOX4il%La6QNF#yPTm)RQco$T6*g%O0!K zz0;3>>ueBQ$|_4oVi~d33fA9dD5{klH77=>&PNvOv_!K1n+0?dlv#xKy@dg%jPd>D z7`}g@)>W&LtbfhUg1xcWt6UzJKNsWq@OSU|>z+9_` z(om;I3$1dEp>t7A`rEU+B*teG4()j@>}s!<41cx-1EI-(YAwarzBag4F@gVCACAf9 zzUW-6N&dbZ=omyH;@cp;ctJVjSqfGacH^~QsxdPo2adD83wJ$EV3}Pp0#4l!R%F%S z+WAVT$=3K1tYau6ObCcoE}W-M!RAy0iUMzLm`j`I*6T?@eDoF??P z^AYCS_#tU@6Ru6M7W&bw&iPg2KXrb)sbYi}%N>(j0LDq~UY5DUBlIv!hVcMfeFgkTja$}+q`c=;5t#+%hX{;SI z?i!E}E(*DpG=FPY#fMMNgTcmVgnH<5p}7Lm1*uqZehyzZ{sca_=ECUl7(Up!7Tx-k z;Kk#h-RdRC*Ue?9cOe-PrXR^ULAfG)~+1rya$=(aWz3+S9syu1K7 z-i#3YCP6+l7fU)?Frv#zVfxPuj4f-$#81`2p(66Ejcmh-v&V(=*+~fA(1uRqD}cluLlFVr~g>*u`v}>%9WTnbhZ0slzdS?8Pz}W=D=da^m z(v5H?(*bQc&irp)9Hex2xMa!!zTD;*HqjjBN`@o<{u|rd^<8neGmkZ_PLvFXl#8iB#{2ScxxLRRX+&J&xT-Y zRV)7T4?^IuAjp2SAgS@Gup^r|G`TJ4T7FwtGa`^a)0Thgd|S|vF3OvRzM90>iaRB3 znR!OihxX^)YIAhjh8>iwD6m3++A^JM+HMk)r8{u-Vytx3)=0_jB}Q0N{ZN?kt0x|q zn?dXKULNty1~J3;A@oQT*A7U++`u60coWCd1B>Zd9uK9xQM{w91{z0?;Oyf-u3%Y@ zkspqtVuc&OTwIURL#41;ZqD=j)?vqoD%=^okvCh`V5n9-Y&I(xW@-gIp%tGU)HvF*|$*X@KM&OWkl=UCR zpZrS3wYYX@#tq?D<|X1*YddCC58_GXaTq3R$H!d*c>vw%`+BzHWZ(dPNuS&h5)4x+pJ)_>~U%Wk|hsM|~| zpgQ*-{zCe_>t)FaPba+UtF3dpp;VH2)0%isb9FAypkD5j88XWZrNbvzNNislqy8pw z1{BB9T+kfnwIX@)Z%<-m9e`>|4nIN9pmDmSol8H)h2a$#-6;{JdO3V{LLJhJG9Wpc z!jDdA!1KAs@O@+q|8e;w`e>J-XlM|h@}v&YeX4QT*qsmSaRLKA*FiCF`6PboSUpyEs>Z8~Xuh=U1ippWA?|W8zocJ< za6=i^y(9DB^D^{VAi^iXoomjdKE<^OH81w^Td7AeMbd)w5Ia6>RyNF2Tk%Po{OR)P zSf1X7-)O#Veml1$_LNscJGzZB=D`=pclE3t(Yc0vj(-e}TqJLK#ulz% zL#&>FcIYT==8*wm7^KpUr)M_uGV(4s+O?rYPMqn+VvK2>L1^fSq|sdjkmq^7ej>8xbx<=r^C!I=I0 z(-{L4cAJ=i--o=sCxe#u)Rb1nx3_fBRG>Z#(jrmCoE3d-2oteC8O)bj4)xs|} znOjg_ZI;=9(KqAyLj7`hT5{~263umzi_pKY5zq_glCJq!>C+7Dzrj2@m-@-iEwpb3 z@-GL{aYwxkrq}#^ zOK$waJDPjjw_|U+D^FGl$NL`b$WC|QH*&)f^Scc%E?Myyr7#R^Y{TTIx_nS*FbY=u zTjxJAJ?Q}Rx#-lx9Xnsk>8#(`8-wZIWz=;|oso8(V83+_l#@H8U%o$=4BBb|zY`~A zuXsPa(6b;GbOQgVYejrNQ`p+-8s@`$j9v+7czOVSXUIJRT97gH! z2mHEfBiuA|@#nwG+>Lt7img=Vj8^{Of&jxqWw39o=gWsQz?9D9zQGlI?#EhOl-6R; z#{&M%xEg)hPNHr{F1M;E2MZAJxjlp5>RgPvvm(AfOXK!V~(UGKNSXhsb8Ie!q%v)hpz8^vFfhHE;l z`H>SN`9Oy#SZKFH_j@?c3#0SP_clC93*|lih`~s&j|2ztM=!$A<4W5<>->M$^B38A z>5AVAuyM3I+75QsslPXzc)a`2IBTHJRrBtc?q`pg%7Qeie`gGPY>64~T7(lDCZZ|L z8Uf~IT>gS5%!=L6{`Nnf_#zVumBBcu`Ne=7rt{0>^B(wyo}r{Q zawX4&%Lm$X>eF}+l?V*E)P|$?llkeONPKxh-wVfsyor1sAL;Wdz8}HO4u<1G!oTbJ zRMuwc&!`nJj&sM1EO+6CK(sOmhLKM2kR4mhA5E6o_Lh8#O*!b^RH5$*JBWU*%AJR%cZ762BY6^8|a(c^SEbg zp~xKZwf9s0g!Zv>%{~}ut|B&EDur}q1f1UY6o+5rXe~VijTdTS$<$VwlcmFJU02b@ zvK8Z+bMeWdv*=UMjQ3#$IG05Fr4fx7bE^c4l3()~GX>25T!GZ^Cp@FmNqAqchV#CA zy!+J}eABGMm#Uk5V)x_le|!?3v#)Y-LkZj#2r%n;i6^!mL--sKPad4(8n(G`x!nkj zE@$}N<>V=t(u^d_c0Pf6>AMT)+}ER(+m_`$f;=wY$mf2E!$Ord z3}3~0-jisgt!%^l;FG+Y1F`*0TacD`g5M#3xp`{~F3-y4=F1|;x7`Lqn^OKeB@!L; z{_UT8ZqbuwPO`u+J7UGR+?6(KEQ7OIlc1vv>?nK&Qi9!

M~b zzU7kbC-8lHE&A5KFy~RUs9ENvnGmZt`;48`;eS;Y-cU3(V`qB+J8>7^{7yF zgyw|5d?9(u9_DzXcjtj(#@A!m6&woh*(1c$p|yzZ9uMz9!^BtG0xk?lLGbwj;-fAc zla+~;bG4_ab%%P47g?}sQx%6QH{gp;9%lAd5<{QXVbACScw5Mc{pk!opqzYev7N;2 zBdc(`wG7{7zxWrrKiM_+IIcYY#>*m#kV@xthh3k!%a(k6{;wKmrhMR&400gOJAtor z-jbIg1EC9QVL@DlkEhe%^|KZSJ6`YsTj*@)T}S-W=lse*^0{8C!+5u+d`-7_SSi&b zIfgh7PcLu09Oxii2LORiJ0r<_m@Oh~!HGeq`0jKw%*N**M z{q-WuePD-ET0i+lZPM&e9+mgh!Qv9*BiKAK5U=Nt5#Qb{f$CxMkMtTNj-eUF_mKzj zG;X-KOYsD9(vl#{87QjP*TCvUDxBbxc2z_z{xwUFy*R55^SI)w!>8fIE>2Vm% z%Z1FMt7v3e4)uZg*s@enyn3P-M$~)%-YzfRd3g+Tx)o8c+eM5YnTOx>T$KCMNnGKa zg-!cP;6R)Ng^nXAoKlMPKRMB44?dNm=Ydbe zLx{uJr=>JQ`@rvgibjd76!V_H;|oYv?mVUppYOlr2`{73Z*Un7ZGXtBF*Yw0dqURAWdnTN&qvha9?vbZ}U8xqAF z49rpz^Yt@OO!qY>l@-OAV)NOfn?j{2ic z7P*Kz&`DfIvyM&Ua?vXL!_~>3czVTwx z?-YdRz;e|$z9p7C{ciLO{-1M-%b-a1;gKygNoQO2%wIbD+j>ms?uNw1XzAH&i*c{O z8Bv#1rJtO&(cZ-Y30b{)>D@V)>1cz-PWO4w+s0^kXb<5r?ZcCam%PCpA%^3`K^v2h ztxH9Y0oSx$S9(m9SD{DY&4f7qwh8~ zQSVp=ZXHU&k;-o3-1~>2Gb$Ck)m6o%bcfU3C>784DvK|?lEBxdV%RGsao^trg!WIx z0XIc4Hai|&YE!Utyn?vGJ{DEWQn3BEocMNoG#oA_lUKTnxO{yKjNT;Uqb+36Cll;K^KDF!M&9d3HG__pyQVFE#Ov?taXcbB5!h z(IU%?K-67NRE(Y|W_LOSiz9xhOdT(_?M%Z+VzTLf7$wf3ed6$hVBFrMAnRSiI}GKivFLuahgdoy6&tBu&qk?%V`#qV2kM^U^XPyFHhC=}Moi|ZSsarI6VbT#G0 zdBii%jG+1N_0Hm|Rnd66AR1B8oyA`-qHuHIzx=v)W`}U2Vh@I0@IZ*4j2f`N46xgWf^mOY)wab@qr2>f{!zj@dns=HvPHL|G=A@e4ot^cp;p#e^qjc^ z-}~9Yd*5L3(J>$RWH@7!o~D==Nvxwu?l8~O6w66dq)L8)Q;H)*JJSSIk;Yz27$gQe z9)gLgFLqS)6Fcos#=$?ns33o3QhX{NHBj!_gude7-)Y$F8i*JB`iQc;G;FO6!YrrW zV#RLCIPf7Y;^1E5&eO>lek~aHebmKDg(S4|U~H7Bi9=@-TZ8mwK5x5;@s8yGBS!Io ziK=2{TO4Wa0`W0OSm2~h~&<&W#*<;AqY(YW*8 z9~p^q;%xsYEK4Dt!-URa@r@{`1O)>BbrQ?MqQFc7|5?u()w&Hn>+G@ejt7E=kCtjJ zHA2@kH<)}{D(!Y;6}qzu1SK#p>e4p|O}U#|1h$>f#ad>J?Y)$FT)HMJ1m^WbJUr^G!X)4U-Qc zb-5>0&Z>*W1&P=+%L|D|dx%w~2^c{+4pY0UiCgsuSbM1L2PB2`XaT zvsk3YxxrSut2nqmhPb8`t!g)b$*#uA#)MzG55I# zoD-F$L#7+Uy2TCsb*D-v7pz765EnQ)Jz~8#>SG0*peWFjchhp5aNdKu@e8^2NPRr` zO?t47A|A4Q4Sx2p#E_mZ`9hN|7ItANyL6F4`QWUsXk`92ZzTus~7|RWV_X z5AH3qME6Q1aR%w!V(Bi@|FnWAnNEBZ4NGkKq$nB=h`^5!E7*MMD$X~LM!Jy==8aSl z4TjJj5M_%a6IH~?#1-;YY`gcrd7tNzI8tGXuY-Q_xkZs^wK2h}Ip2Bbz(@>R zV2t#-&%BpBF%sx^F7Nu8za|gv0W&M4`@iQ&#K%eu*up5N}1PL&nK&3-rz)Mw_Xi~=%d(PM#Y|(dKR1<+g zaprj2@|(Z2i$Z5_a}+E6g0x*f<1d(GcmrhC8*+iBgr;9Js&h49-1b$-wJ3=iVNb7ORrKI4m> zB8g+Y4c*>8{|mgvE(p(#(E8tWgRd1rG4zc&tS3I? zLBs}rr(!`~#pj$)h=Rc#bM)T#g3m~aLfkrY@+>^(dI!n>x_vh;UwX`q*GA#ppk0`D z{~jOlGZJbUW-yv?i_bn5i9P*xAo{>He%Fp_a>x`LXI|k|#P*0?XadQO%Y5NV;+*s~ z#;Kc^dC#4Zu%LX{V5iI6*f#FwnSaQRP( zjW6DSUV9v1BQ+6LY}^dPAUk~S(}QPtZNqlzJj?0S|zzZ!{% z_MMas)XI}7-^5DY44;xjZaN{7_;TCHcO&CdyHI|_8PcV!ZQyG=MdG^~t>O0#{NC_L zTy@-r9`6M{z=(9~RYv$cRNyo9h^;$w8+Og${Ihu^oNgJR*<0jicSj=r%{F{dYUFG8 zMq-3)+dp-7c^D+PnAqcpf+uoQ64)g2G!0&Q0A0MkvBX?MG)!}aQsfQh9KIPFl%4T3 ze;rFcy&1Q=I3oJuLD}OohG^5guIGZFJH?VbA-P;A3B_L> zOO(H;;On|ZAX3W`dD4^IxRSo_f&~h;%lJ)NtLx7Y)4{%uM<1uW9_`(*`gENCKW}*7 z#+_IcRLlq6iNJ1?|M$z~^Py=G_(tnZ=Xf4ZkB-3YZ^l?L@+j9mPMlqF8$#la@p|$x zm%cQ@HN9f~(6V&KdoD zWu?(Sb#6!x7phP0!D(erNY$d*eOogmZ971o_pi)Mg*0@#U9o@se=M$gD-3oyc9egyjKu8ml%5Z}!c1>@t{p`YZtv_F9Srti#ds4Wi0Q=Zy?-s1HQ{37`k_?aDKT1-H#J5lkVJK zR0Z)x#NjZ66}nZ&@VPG{@Y=)@_}YpH^NZgR9@*uxj);D@I5G-+fbb?;*C&{pTkq=bBU+_ z_J7aaodaTp)|CBd@biLaTe5JTQ3l;l>Ny=Vgl$ju!`xFk(lsOyf0rlYx zg33c*7-V?hIBzQn;VuR3m5a~zg z-!N`MgV2w(BoSLY;6Xnh2+GEpLq0yO1_7%Bu&9p*Ql>NrMW&Q{-r)|1X$?YyJ>?O# zkOqKWKlBbj3Hcq4)B6v^1i*+i`9>b*!nkC2*eiQuNy!!==;#5c%<#r_y{W>}bFK(J zPAq``nQvS#SEI}qd!!b6;r!rX!ig?>&~KF&p7fq9xOkE0`kN;@nidGpqR4w#?upoy zD}+&h?BL-?{zt1VLTJt&xY&~aF@3j?YDK-CJ!QJ-ISPB{I^bE5C)AG}5EME&BDKg9 zONaRgpKd$i!VU654)GI?QlHpO&I_An`U^?cdyzce3;C`7Lg|~m*hyR-GqnI=AZgyW zn^Wf6@Braklrx;%y9L} zz4zggix(d3^cU3o?}O_eFDRM#3)2QshUYFXL~Nw@XzWABRxj*!9v}=VcE{Ibs^ z2ITX)_W$R#_p-hvf4MgrPRR-VgQ`%6`d_}W-185lux+rs5gdukQd%Qaf24IeipjQ3zNv>Ijhwh zMK9$9^_y8qU3EtH-e za+G=3Q(oxU>xRwhJ~%d9Ua&NA!{H%5$Q>;&tka`x$#KMR9x5+9o9>1$(|zDi@3$L5 zHC*U}XY<@-FKBP9H}w6d&YqvH;_F~v*#4%x!lnkSr1zfwKt8S;IanrmquU!Vm=klv z)6E+f=;uA>8$)-KH|de7CN7#N(etKkH*e%w-InlW-q=Rpoo(4>l0gQV<{`jY)q&E6 zc>3-(o%5wWGO8g+>WL?$ulV16!{P2i_Vjlkih2?IY57d{R3#9ZBfJr~YCM~>hw`bW zdn0R_2Ae2P+B~Y`icRWlKe39xQ!Q3bkYjyl|Lh3##`LkTk+#~Oa$~5@UoO$V!=HKp zZ&)SP;i;lOW(}Y-_K#f3jV2!6S|4~=B%pJXAErh4KrKBCKePN0-9#+eg_N%r;D@*` zK6L-$2Oo1k%-8fq;cH*4(DTFHHNI$j;)@Lv{Lt6K7atA%uvNtmnt8r>H#P3)^wUk@!hxJZDuu!MGK{r1{H4zW)nh);e z_(A=A5Z0vmpzWd`#ugHr&&&r~|M+1o<+m~V{F5j8VieGBpP)h#S-+isieinN@jJTfO=)cK_C@5jI{Mb?ocJBa4rB7=yOs?QDQ571K@JU4+n;J zWjlIO{@W0L{7Uai*_!^iYvhlY1C`miv6Rbqm~scal$m!0-EBVbhxDv6Gi8489z_{v zomE&1t<7HM0npG;VegE6VP6n{L8Dbzr}sWcdq;U*gH>4f03XE74uq+a3ez0y13jAe z-iv>S(4IbcYx?iJZlGTjt3Dcy0rR~Pd^nu-^o>HIy*El)gW1*WNW9MTM)y_z>;d&T zy&h4f=Oa(HhJ38UhWp^Wu$L8+ZXsod53zNuSn+atoll&QgQo1w={J91(*5E;X38pZ1cy%AM@FR@L()Xr`K`X?DXp(T z>%Qb4c3|CHBOyPF*giE@>>7P`QE`5dSngt}wsbCd?}u$6+u5D>;ZQapUcpKew$LLS zyK||Zb2eu6#F#(+!=H4V#w_$`82ai5;N>r4wve75_L%{&&oW^p6GH)-A%8M3WdjzF zXOVoEKVF)$npKn&NO@a&_S@M93(8>B3BuL;+nHBzApR5w;qQVS%(0kyHjQ8m4&A{b zZ~5a9eSVg$JD6oRe^~ww#<0&jSo$K;blZjCc3(60&C3@99)>_;k{Q$H$Y#;6Q z>~0^*pP{|rfA{BoTFK01Dlw4hnKX4}5{qv>gzYDZ!?P`s)vWc}W-($y2V9;tRJTi%pxsCDrSlIgz%7qR_rKSt(Pxk<4V}h|T&V@a148r1G#PxmR!dh!7S2I2Ynj>AA zel7LY#Km%4>&iZIe@sgY#bH-hHktP9QIzenEy0yJKljDg{4g{Wy0Yc+zBo879Q}S- zvEMenh<*HTUR$61IM(p&Fz!2f!{c=v>#{BluW5hK?h(g)XNQhNVNO0V3Fmt-YvM69&md;+V-ME% zEalh;!SGJ;WGUpeZ!!qM_!VC4;h0c7y%z$LOJ2<5SumJGDB5~>vm<3e7^_J9hcVu) zp6*6o6RU8}EN?c|f>>Fz!m*i>b{4Jm$M$pK@YeNax=Z|!X%T_o72Yh4(oIgtMPlMr zCuUyfi|IxG=7`N%9LVm*ksh0RhLNX&Sm~tvNv;`1H&Q3k_fo3sceDg=TG|{n>f)3}*WJp*7!^O-V?Gft)|yPW541NJo(A zPv^H(FSe%S5LPMD{y5Hqg`ZBu+n@jpA4cB)_X$u@4#eH~{p>OEttW*9Qs3sv&KVxW zH>DsP@8-&O9*KuG@f_!Ub73*-NPFKi7!_KstRyc6FA9QTe$bU&`9t1uy$~>s{cOA$ zgBE!jJ>Z zU=d}?X+$8j^Z>g+nV&Y4zZTg{uUm-==SZ`p3kR4h`R=a_jY9t`2Ur&uU#OgkLfVBr zESbK?lW0Evzx&2uyiH^ z>XXLXvyDOqGHJgJr{C%0nvNGc{owq;jy=~of(;-1FoxT*^dX0#=uM0}a~pO}E)8G0 z({o3~n(2Q{!S58}&!4hn7GFr)HlA`bxdp4~l#Hd-f$;fb&c60d!e{zByN8*xSLFLU zMtxSpE^~HwWg-Ss9+|19IeSJqF!EhOU@Vxk?;&w`Toi)t!z@^@e7Zw1qFl>J3#LQ7 zx{B^$&{nWy+lEC_o_H8c_FJ;KuHksMHyjF2ELq#*P<)?23|?5VB2&uDd=vqN5G&^P zCJ31{*Kj0A(M{UJM{kV6-6vM;(6j)2?MYr6+8^?sQU35b(#I%Uv%b_WG zL(k18WB%m?23AdH4=xpw50|pGv$dI4{xJ-qy&}z9%5I%Mib3yu5bwQ&rH{!&LWD2= z%wEQ39LYiG|8ez}VNrJN_pse!VPFS}-gYWd9HIsFBh!)Wvn<3OhO#%;G7226r1Y_m}>3{AI&u7 zs((Dr{BT8~oTgYTilc`dJ$Cj_Q*QQ+W$q1gg#xB2Xc~jACsdfSd79GrZxpjt`Rtoc zQ||wW#HHV?XDy~F=G7u`IoJb{(R@#6IJ`&l-g!Jt*|(L?0?*v5W2P%w<6u0^R+Ha5 zU9q9hVTz>}ZZ?>qR1OV*&j4?%*fv8+oaqOX&)%>)J44B{XQn)T1GD%a6Vprma@2yD@^wU z;&}5}%FT<;h?*1x`{Iepa$6TPyk0fmYI5u=v|5vgd6kYl|7$2A)pB6Y8YS>;1Et;P zO!Q&>(BHqA(z643Sm)RirO;o+A`MQ~F39t5tE{-5g6duAL8R`Wd|H}}$P@GoJ=96* z@+k?2h{f2g>Y|uMCgNyo6|DTaD!<8XIa{fM&H8T2EBZG)S>q1lM*51~Yi7hW^1zND zeP!&K7@vY@npCXJ$lqU&OyMP&V_quT9LlRj;1P(qM0R zUZjul!k$XrS$fJ+L#S`pQyJRc6Z_o)a66)>(snQN2bKq-cYaUh{A)Li9UFvahk7bs zEqGS9)!^9qp33}RT$}G2KF=MMe^`@WtVYhw|NZ+Pp5%zkOJi~HZ4n&K6KCKo)_ht4 z+J`vd41JBw>gT~|zBBSe(y*{*4*qSz9wFrb2KCHB+%Xs2I&~NyHfNx(9nS~%vuJrX z4LkT;?H+j*{U)ZO-4i!#9DExC&mY;qV4V z7GY?S?TxG@Z&B}OFc$dwU~iXqaHmgsI5GE}bIg_`&ogwMAFSsS7 zn%*tjih`lJ{{fa=T(B#F9>sZgaNsU`$F!<`xoabTR}R=(3VYTV<&8#Gwow;j{sAX^ zI=gA?%3(#&r&jspJv+l0Rt2cH(FMhZXARGm=V8}WSDf;$3#+EN_|Tg**vl@g(X-J= zM}^3S!!hDQCM@5pus41(a>i!h%td!xnm-SZ^V9H|>v{dUDH;z-#nBMvkltC1xbkF- z*+U;!osFnAZy#1H_QC_suoq8BL^C7$5}R(t#aVI48c*+5hwW%-9u4=2zBoI52Nrrq zpgy1X>>E3A@OCI1$yssfw;NF=Ex*SV=CyCGJUOj5Y2>`eX1Wp6NfWnFq#P zF#6hT@VCL7W!{K!4#wr0#M@S?vC}UEkCxhEmV*br(i47sj4cv#RcMwGhLz`Rard(; zv$Dgn@1rg3r!o)ocm(y8ixJKqz4UlhpY4yvkF|a2e_(cvSkRUO+O^tZlorr)+do8` z^rZ-nLC$Ddf0y>ws6tfibisX-DcV!&d>m$9Z`!M?wmCU~jfv;F?x~^eJw6AWx~tH! z=7q}sDOvDqNd5V$l*;SPn72qT=>0!cm2uAL=yu%$zuK5qp8m;ouJ9z@II>dNn}SR9 zCAK`?sZy_gGUm8@;nh%`$_KrZP-e+K^Kp$z`_A$BYtH=__qiguWelw6`eOc{rxm*7 z)=rw@N506d3e}1*G%@tYaJP#UDfIbB7!rV&WhX1%jSIs4-hpUpc(|hGQ}PnK1!2R3 z%8KcnP5)`9L6~D{#bA2zmgxp#@%Q}|(_QFA-8ckK3<@h2@_txSHxxP_^D1Uma6eZM z!|AcP6=uADru-s5?`w9&^T{sA_!5qTwoNMg(Z6lMys#?g#=tE`LStNtr#Boi{(fKa zWZMC>DRDxtRqe#Ny#4sgzQa<#ktqJR5D8AibrS#8M$Rk1^bM}id-q&BDlZQk=eWTj z{;IYf{a0+qFz;jKG3~QG*{E&cj<#P*wL>0eLcAN zi5at!v;#+^;@%lGLOkNM=_ScXE%L&l>M`2%`ui{~ig_Q-QQEa{$+&NE?exOREZ5KO8QfD4VowJ$<~uzaUimHko;q(?ZbD zCseB(rAJxsP@b234|~(ujlvK-KUCX+ePa3RFz6LTXzvkIIb&FLo#$Wm7B+87iM

cP)W8`;kHZ7UJH zhApnc#r?av=rNC3V>kMV9HSguU~lW5V<3KKWkEfVIKY=KqF?Jwob5zUxsVPb(?~EvaPUwmx{$d)KDh35z|+vVAf+VoWI*j=Niyr%!S8lj1S)SFc&-9 z#L*LxGuI<#qTTfH{2{?`lpn~HPg9w=1kVcyzQ zTsp%nwObk_)G`&RU%A(I1oPZjCZ-az8Qv%a^SsT(oR-8x&Q!ez-)ws*&JHd|KJg-p z8JERa+ftODpoj3syl_f{h`iWT#1f})`y4Ey{!NBz05K+2u$Xlq5ktQCV8z&Ap-hT{ zI+Jtm+QDM=_b9wG^+Vh>jhKIn-f0ba{$^{$==UKgWoAudwMMiaqCp&aU>7%NL}>zb z5X@uJo2e1CNBE&z3O&S!X~f9)-sol=gv@RlQHOk0#}`3ZsjCsrT<3)z8u-`Kh_>9% z2fH)l<8P2qkWnFchjX&3slP;IT^syr*{r*>M z*QeLTIbz&DKZ+wRC2-U_qtm_TVjHyxlUNr%A9P0TYx1v<|7IRumb|bf)7*31($3(=79O$s8P5X36EHchUjE^VkKNjLqY$jY)%!ofy zDZHMgW7A${!EdP$TY9CzcnkZrpmL#Jl7jc9K6t5HF8V!9#GS6b@GdPA2CL%Gm}l#5 zt1?m2AR3PXnCmgDOf+~Aj_DKpVOXt9?D-vnW*?ccd$ClEh6Z*q0eF^KDz;|^;LMaj zEb=WC-{{*koY@DRc9n{*U%l}-Gzi;Qm5P#6>=VcEew<$_9#qhWjae$MrJRM&uE*TIfI~0OCt; zWtc`R&aG5OejQMX!^b(BSYKZr2tR<~f;by}WA@i5Ms}$yRz0gG<2M#zSuy7>zkZ4` zY6U!sn1j&vi|M*C}X_SOF^zd%e4 zeIR;~%d~Dx5Rx4qh@CZjP(e?4_pJ}az$Y&`7AQW?YH>@@rvihyZd}? z`apCe&Rwhu!AyRAKo1wp<^59roUh$y)Nt)c{<*8i@C0 zwd9*se%Q%yhbwut%hlTou#Q;FqV-+mtI|9){^WrU6FNzk&p9~%)f3AiJIG+YY>ef6MKNtJ4-e0T z>1QvfH@1^OYtj++&Ksl3+REKEQjtc^)`BT*rIA?@zOvrU`k*H-osC1St>jGS=*g0; z(KtNNAJR@wW=@X4()a%K)7F!VXNO`H&xrM7^yC@VYgiiy>z;b@%4=p15qrJfR!{ES z#SG}nL73fKPuB0|gD!mEyT*EQ#yd4uj|s+$MtX87>-{o@ewxdGDOxOk=ZL@$3uL3B3K%~lURNK|{@Mu6hnWxCrJuCg9E$5N1JI^UKlv;{L#;n^#6IlK6|>q}qxp6k4NZ5W2E>?dFF9_-z?YW@7Ka+maZs73FOte;Ib%d7J$vF(i$dR$v0 z_ns*S-Z>*K#$4K?3|GF;n|jd_IX1Zjr~bNP*R}a_$=_n!pmzRswK?+Jl>Io^#vT70 zoGGh06=Ga>4~*BDE)VU?r=K3P8*UiO*`>K?KSGVK&8NuIr?RnXtQTzQFY*0VCOwpi zp9dJpG=mI$Wq&QsPn4a^QW4spy@bg`IW;2*9m(^4@_vFG)G8is#D8|APmtyX(fBvY zAES3qkgMDx;JP{h)#px-_dG+fuNO0pM@^9L>Aze4n)O@n335wY<`8BFp+>g}a%GGk zIb9lT={!O9Frs$2cQA%^ognQSdg1bOo)rcYq{CYeSS7JW>_0(fzf$3;St#y|m>>^V zqwjH>Fz8O4AZ2gP>(7TVH)Vnx-kg2nj;iZC{+3E^vlXbtnRU~TPIB<4N@RUCWLrQ*jTUj*G=EE}IrLT73cOdJ+Vr@`?^VL!5T%woCnY&2{x zQXAZOvD^?7@qcxN`P)VEGPPNQSQ~%4xkyG{(BN(VAZX4nlIlKzc=;s=&CV>6`?CBn zx0JckXBWx!#P(*{1;hUGA{nCVh3|$T=yzw4T>9Aq>#56X^L&vU`c{R4%2339UL;>~ zuf1fhv2l&X(v|f_$5G)JzhSY|^4v(iRdt>Hw+6~tEhL_NV}8nfA34Kci=RK}#kR;( zu4`I}ku_bQ(NW1|F6Hp$^I$dAMTS2t#YoQI^*=gFzkf=g;hfI$rJY>5xES@Oy5pOl zjXb)g2%U+^`ybpbopu!9>L%*iw(pepcIMH0ialVEmAvPggFh}_@X*^XyJlzMsE;>h zeBUbbzh$6)C}*_ew#t3ksZcqS^LliPyzn{+tIYh+dFvKAb9Ox14E0Cnp#CNPH`&XqbVu}N z4>|Wi5lnY`z_OaV%(+>BbWcy5z2qj3Udw|=IOoC-T&2fz>bX ze9A*-*|!aOJ30{6#DJ!2FTTh`IuO$hIKc8`FwURJrup*vcXRda?8fyTi#gk&{tmD zpNYfd-G+zw%KqO|QAu9@`*ptZ0x*o}7`sa(9OqY~B%o9s_)( z{gVjXoe>CwKEAT>F86cyAhhP|F|~t{_LKEnKVR94*oMnl?(f0;o+o+U#|0yk-$%RB z2OqbEph)qR|LS?+=(teKo8l`kzVX2BraT`^eC1iz8}05=gSW_6o_^p8nI4Yq%YEhl zxIEUoBA|Ry%k&@A+R#Jbzc~N)vxSU=E5cmX8?_eX$Sy^NnE%2FT?{hhvhDP^cJHt&7-^E6!R&Vr z=<7tw3zyUIk=W6LlacZhv5Rf`Y7`!dko~9Ahr@s~`cL7qMp_aE_ToJ_FI-;eLSJIe z?93mB$vP$R=-B(Vo(YaVucJm__Gfd9?NDsWa)T8bQlS|u0pcApqp&P@b$?{Ng zSOTzeZJ2CzRD;OKK;-fDtLcH*%yZ+;hA_E~`pW&r8vL~klm5j%NbMMm?K{Kd#85A6 z{1}X~y$>6LaEJ<%T4sOBl|69Jy@=QUEO5*&%Ir8m> zWK=71!Ly1?sSMnQ_VhC?nvpK2-AY7ax*IG9rb@^438+UN#eCCbS#UQFo#Wi``ec&y znG%a>Va)a3l_>Y+N5jt76K9qt$lC_=StZUpc6YqoL*1}y7c+Se$I0FF(pkB|8*P+0 z=}{{T`pbN%1!9KO^$@IPKe(zQR@xI+&?Od{n-D9fvHL?h~=BU;ugljCfY{y+Tr&%so=CPu><6?r}@ zQe+>)AlQ5-zhZc@Z2vd_#pF>$joT;nLj7^%kec^>l2k7xmx+8M)8~oOc8D(qdDC;> zIZ@8g_krV9A4E<}ly3~Y(PzFd#&=4T_eXf41#!`o`iW9!t{PoB`D5I_39{J^@{wvW z6ZS`fTpQs5w-*8E$kz>zFmvoIHHW_v=3OJ*jEl9^ixyzlvn*K+Y#uJHw(NUrxN}i<`t)AAQV`Z~js* z)7lkd1G8j}RzBqTyJC!OhRh|Fx$lA-rX-|Eg>`=YZ1&(aQst7Xp5#ur!!SHqE>7oJ zx6%U!Yxc?6j^t&I@&2)*l~p6&nrFt#7Gbt9vbDdaeM$ULW)_!Am#>*wdfqG?x;@YNo*=!iKHo;ZvIz9Sn zPc3pq_5F@meLG)1=FDXp^UIc;%a*msC)zv08HG_9vf>T7tkqrc{!^+fB(K%`vJ&US7RVjed1^)V~rdGi&XI^J#Z< zjEiACV}m!G36(}h%a|$FXl>?+T}Ptit{e1c>i$0+eU$vPVHXCxR%2#Vq&)ub4&2K3 z!pQNF@<+H8BKgdZtQ9G}MsJ6`;zPf+2zlY*RyfzC_OCQT_V(L?*t5RO5{-}siY3ld zTi7cgLT>qDfo7(hAv#CMBiWmEGW)O{JswnWvj~@P=5u)uYVKe7V+C0cF5m>HZ4IQUE7*Bg*toB7C{g5}?? zThK!lh>PBlvJ-t@7Sl85zx#Z)jFw@hHc%g{$}2d}&-%a`?y+!k<(G!YyRGaoa+DK! zu|YDqqXTsBJ3-$uKyD~@z$H&-6hHTq@!uU_NglE$%va8T>wpiBT`+r>k6aPwKu;uB zWbN>l3tKv%1v4Bw`FhERbM4Xc6S-beEt{`qu5KLpa*fo|+GH=L&v3`Ot)6mRcUvs| zPQS>P9@65CH8v)AAj;N5w#?gu%hQ;J)Wt(iW%lli&*UTCaF+#RcHus`g?;1P<&t_k zacz7>#tkk);r>UQ`}{C=61Xb^TzFN?(#YH&aK$X@2u`FuPvu<0Cj8b_f>L& zvIQEAFU|;+{L|Hv8E}4Bn4prk>utuYXT1W@hHI4k`eP@3o~y3&z9wGMJZCRvdO5<@%U$lG2f&OD%v)UH zChJgx(yWkY^(z-S=r;8+tX&%3b(TGwlTZ4}88394y5zK*`w*56t7UTKMoeW_V+G%h&gDT?Htj`Xq!CiW{;iK$hmE9DGPQwpr3~m zOov!VC+bmVwBSs(-6omX+Y!3)&fLQr<%^+?xITcrOp}dr9yI~4CHu!?8)Q@JU1I0D zqL$AF8AT0KzbCHvGH-+QyvVFb<{k}iw?S6^vBURT z3u)Ip(dETjdHmi^93~GV#CNS+|8NIhzfq%MzqL~DxfL}8oGBb%Ba7Z|#|C=D=Ph3& zTm9aKLw???>K;_D*I(l(=`gC7Rf zQp+oMHX)wA63xE{O1XIh&-JRjul0`?%9nHP@XOK>j#KB#SI3zj^vDt4o6VN#Sq`vR zMy#WoiF`;+jq!CS=4Z{4In=3SFK~v#I1_nyF}=RXY5acFM0S|(h*yiq$zMHNZXL~h zs9P?0N*phY`l@wiuEAyXZ6N$!vq!@?OzSoP-*$_Rf};mziNwu14`+6KVg& zia5U)l9n%%iQ}x$?vNKkrfek3avRz;s=Ci#zS|>JCR0H`(l*1=J0y?(_fd z=ft}sb!SGlf5J4d24Vi$1;o49=rPxoBBFddKlQF6*;B#Ee)mjY&$fmufp$QL#eUe zi?m&wH(xW9H52H6{8)v)=M3fFQ#LS}?T+_}hO+s0Yq(dk_g`!%_t1y0ytfDH^Lvh4 zxCh_ZD;e93l@@AxlhpCVsn28NOYJTMTQM`P`gpn2np#5gPRDF8k|udO@rX6gkO52O z$?x0Aon)4?$1=J9+IC#5$sWqULYmy)ir>`G{vKs7&$wCQEOWL_4RMqjLrcW!R^{c6 z$l@mglV@IGbMU}(plvUG?8{I0uV!k?b4UPYittZlpeJ=ZrZ@pxZr!4~V$fGUnCA(g*!L26lXg|G|RJFB% z0sSV@kM@-B*HGun+OkXUo^oZu9z3K+(+<@DnK5J!c6fQ9uGa{u`+FB6r+QY|=e;*h zm)_Ak@cXJ7O<%8)cTaDFL%MgB^SrXr4mqWA3o3Q0<_{VheHC|h+M{qH?=zbZVwZ5h z9Ut!9`X5B|366Mh!x3*6e-am5IoF~-abm|mDUMjtj^*~DotB3WXaN8E_ z-Kg2*jKp?CI~l*g20p#r;nztk_e@@?t<15s-r?Wx^HrbBEy}VEV@8AE&%XNOeTWq18IK3xxx6f=9rbfi=c%Ka# zxm`?-;l6fpg#HI>@tFI1EBA4bsf$Rf$L!fB+}{;m;_5&rEN$b2pLW4w6#JW%GsqeH z9xHxOGxW^G39a^|3v+KL%q(N?GqO-j@nik+k$TLqa#7Ek&xC<99>yFJNprdWOP$eo z-3d`{;DlgbYTrJb5j*%?%#qY;jlUq;@!lx=MxA%cYo1-tE(rY|)P+;ixvAp?@p*$Ceo$MY zBwiEaI`aO_rk>|N`+UdlZ^EG0UR>a3_bZ}<9GY(pORoRz3wm;>yEWSMa7St80GUIN zVL`3SRj;{n_I@j@SXEUAG=IevZQH;-n9F`+?xSPcTWf4k_R0b8&L7u)f-U4T2RvVO zMcZ9%i`;7t7_{`YcBu`sunPFQj;S@{gGnLw zSl4!nsQ%R&J$}-^)YM#*23o^>k{ui}cL>AL*4XN@7sz%IapUM6`_dK%!@Y!GwlxYv zY_Y9&pqS9y2G7UYLhnV0DBNO$#q@3(W)dNMj@zJRhz$-cjuM?Z+M*w9&~;F>NTLVl z!DrUE)-YO(IBd(=jy1ycqQr?-d+~iZdARBbp|f!>-rw7Utt)~=D)sS?xyM3s14S-h zx8mnCt4^Nie!(7_>N}&f-C^O=-X2p}QynmCBS#OQ9()KjTz{)ezXP`Do#KX~y9QD? z?SbLcs{8!E``OAR!?4XW?o%E1=XGuw*3Bd))14UUtp|q6PbZj<;n}+6u;H`n&Pba{ zE$1W`!;)LP4;PXzo#ilgVi+^C=2CAMGqLg`&j%uEc)#yY<-+HV7}}O~Ufw)yB=1eL zV-DyZ7ozoKz1?^Wd&{*_`{uL*wbJ&uT<~1`i#?IobNVwJs4a#*w8x79^oUrYE9?^O ziBa*{uHIRkQ`^InyyJFuJw>F(9wtLMZ z5AyDx$5B7r-dU)4clTl4_1}GdI8G}Z8atpPah^8I+DJ9me#en#zj)hQg$wf>ao}5ZW$QB5Q2ZGQXR9f@C#%pl-x0ZWzaylk3Lmc0 zE8y5u42^SR?gO9aXJ=s4%MHExoWE$B4ck;cmv0@>?IQF2x)aa4ze^MSThAG% z$J^uD%Bfnj57aal*`Y(%HQFn$=p``D4*CzRwB?*3H+r!bPxkE58dDz@l*v5T?>n^Z zJ2<04&FqrJo3xvWjWysMx%W?;HgS|QhBmN6j&+Q-$jBMdwVCBzQK;QhK^?iD1B88n z_9rp;w!segX*EOKAt%n{uM_e{x{0gpobdeu?-%lg{`ahPBH!Dq@}amzpOW*rZdJ}_ zC!a~m+CgfBvp&9qaVWx7D9M2Uz zi*KAZR=(#m*V%_Wgbm{qXFX5+!#=&tVyL2L<$+Vjs3+>#L+N&$-hfA#w>nE#dB8re zHu3F@d)1UoM-}XyoG|On4a}qt_%)vgzjXz;PhDotPp&yJwI9@LMrX2za$ke*2bs6X z&*jvU;W+I}&JXL7!2C9tu*DT$Z#W?ALmfOfcSZA12WYLUq3JTtNq6z{I$8r!{Ca!( zX{>W@hzaXlIR~bf;M}c-s}{MUQ-A|LZgMhwy_6ZY#At@E4KHt@a>b4Xj__L0q5Ogy zbCl?_V74So8~ok{t>c}Lu>GSpXqgKlJ5@c;?S=*m>&5ipFs-Vi*RI&BjJ@xR5xo0G zYaEp!V4_8?e^jYYt45Gi*NgL{6Yq}}3|K|&Iop+vvtCDxY2MhbM zPM+ed{A%d~Q|?8RBYTzo#@-l~?9Bdfo3ei=x%s@yGW}L6BgxsXf0%nfcee7Hxb)&o z)*;WwD)-tlXNUdH(5e3@Lv~OLNPYdi*w#w$Gk1h??@pOtSMl0SJT--S^`2jFx0^cx z);Xc}$wx4JL2WUyuhY6W(fJ^GI{Hp{6L=LasVeC3^}V=jm>;Tw&oC$Sym1T1sP$gX zwU`}Qj8W8M4x8fyJ{e7^U@S9uW>gjW`vch?J0{BHyy z`mrOHx&$e!N`jESg0q!Z!OCaqh`;iChTjcU>Q&IombF2HpJB@4Kh%1kWtQiSFy&~c z0PGyBM4xkaJawnT9%?xx`g>!SsZ>%HL2AT=?S*s}A*)@4g;b+K|0f);sjpcwjZTM@IVZ zvEI)E{rXc|6?EBfG<9RU_;>Ai^00CxKQGS#Ro7V>g(%50!jR9i!n$sll42c(kGib8 zVj`5Mc9NbCfimjj2(t2rd|} z#F9^bmRenV%>*SgRgEI@jfXrLtY|aT*hue)c{7G6V~D>xbH4^g=qqj!YQ$x8@1D|E zCIzVxSxkH^qNQRMN}a_y-b48x0A8TrrnV+Sm}be|M>j#g zi(_d@vrb_cyVMQuPNpl>PKDsk9XHOA)0EK`!8kZpg`LaxDQ9%(&Av^AMcZSP7TQ4k zwNgQEbFk9HBLJEyDnxJcQWkCZ=VwSihoer4tt;~#qIqZk+@b6|>WhCCx=>YBi;~Tp=>Aic91;4s9u(e^#N}P>N{LMn<+ys zd*d?i{+NB{%E1h8^j^%fqsT;ANiIpPiR=?=&Q`4Ayy38fyl4IK%7s{Zj+v;CGG)B- ziQ2>1rSv%2*o3u{D@fAf6t8?4ZW2Hm*e5gGr7dUTj_Bno--Ww zb-}($s#QFijB`e}djZPaQ*mh8+=U(YBi6m5D0e5rA(Y?P*~(hJAQ9n=S1Pgc69$N`{_%Z`@uN-)pF z4%eyED-KiALp1nIkBePP{FJkEf-q;DJ8B+PDT~LFhuGX58P%PX7;^KQv0qMg*{du| z_eaT76~brPDDRv5W3vwZG45L{E&TjY!^9nfR@*2o+Y+-+VW!$*TV+YEFXlG)!0mhs zC4#)jqnF+Bxcz2jOrkHEG~kT*vYBF>?@OORchst8uJj5g@2oa`s^6F>8FBP!{6a1e z*MAh}13PQd583w>H8TOY=i!A$T~gph?L`*3djDPLfsVVCJ8{YII!#Px*DmFde=-L0 zuBljLtyJ%jj27O`xM1R-SS{a&XwJK5e05Qb)+V9dM)tYpo{G-UMD#LsLwS&&VstSc zx-(SxQZGd5F)5p-vV^yDRt=d>=wIc)Ry!#AwCn>wsWEqor_ydu z6iRoiF=@ZE@-Qg^jpnPdBga}EPv~#otgNOM#FXEse=`du zoqEiF-;qO5*Fw2up+VQKp(nN=Y?+W zW{N>sAf`9-LjG_wC3+{ZdFn%3U7f9TC5LxaUoR+!XDdrM4^+?b!nen_FqfLnMT31Y z`jihA%@0O!q92R~Ez%av3WJ&+G4y888U=))*D+0%{aiMpi4r&?7k7WNr?^>9dDS%+ z$?P{DdDc~~_~sz4s|&ohG*G@|WW(La73GVYDG@GNXiDw&52Nw* zmUIlEw?L6HR$1bnii_lFysI-?(I>~|M-w#+eymV>bz^?(Pc>#gTBTg({tw>fg^2-6 z6|3-Ac-VVkxyM|kwr4a>nt4G#aHf)+8Hs~Km>t!AhEl731atkoFk{S2<#BWvJn3Wd z)r__MhEVo~UNHPTTbaHw1YY#osM&mu5)r|B`7+n)s)-W%mim;1ygNJ2Qd%w0pw@S9 zZ2U1n`5mW$F3;aZZWEN?IT{pEYu~=DzVenjw)e|@u>8BOa^!R{{-L+VfA{T+vVSXf zuhh_|IuO3caci&JZkk#?ciyFcu}wFd{Ff&5bgUGp+`$6tiNK9=KcC^p_ak+8g67J1IZGjMv7*!Hjw+4^twrw!JrUR`gaf7lotG zbZ`}C4J`W(wn=_Bs8WUMRFr*4&N=)&b11|^jaDe3hvv| z5VT0v;Ey$5)4xo4PEGxz8e$MN0xw!uUFVyRZdX_~FNITI*5U6GD_>nH;To`Jn|Qx6 zN52H~OI#2#=W}Jxb_Y<AJcm;dGX%AKu>kaE!-;ntTcMz$(|C%wqq z&zNNRwk#L*$?59fwl2yWX5$0-MNgBBP`z^oKRa*O=x&6@AQgA%@40rH2Rx?kgYI>2 z4DB6{FNp~#xa5sSNfl_!bAB}aTgFwt35Ovu*munvY3c9r#32fQ$shP!{}Y#PBBVMIrb3Y%{ikw>6D?0`5^kBXFbhM%4 z=zYju?1Otv8sm3-BC^Rlde&tb;wL8Hsfu3PtZ!~Nj>p*(KG@aS4PRfzB2V!}Dt$fc z+=;>UC-l=;W{EnlqA|484*@qeGh-ndyQvR4vU(d#21KFzN%CQwVhj&n4M!2BS5@7&)>qny{XBbWe%7Fm=qAGSz0i43 zFdX}i5EI*bAcFPlf9s7sbw`SO38naVGV5fUnWFuw5{!r^#(UOOIQ=QcC3^gs7_Ao; z4*M~YbLy>sH;Wr@$SHlU!V*tQVLY_}pBM9fueL#)56r_{!QO1;GVxBEgMtS1#PFFS zJP&2TrlU9FKlc+$qL|_HfEjW_nu)Jl(_p&LhuKvRwQ_R`BFHUY6%(&DPTq&X<;;e6 zovQuZHVKi}$?s}&v~t101O)u@VK&71is3%-s37<5%aM*1Q`f{{73-~;leHB)r^Vv= zFh9&*)2uRPdJM+=^utfx=9Q1uM#Je9vp1&Ht{m$T1$|~x{&(O0s`S)m(%0e0kw9E~ zcT+q2WDruX1|g}zPwn5-02Hj&;On&-!ss7=^t;K|6}lpBqz_ys2cuK8uK2i;USuV~ zC`z6sN;o%bWL0&YADwU)-#V0`>r~W0g-9D)P^}(A<4aF?m zB&4!ej}5+|UE41adzSkmBqT%o&%g258tcnU%24f0YBu%%`eMILsPd5;5#W= zYhw_N>eSTBg)!Ra`H?vG&L94>qP2VH&`071`HgQQwK0FfkWG!-Ee-c=ZYX^21ywn3 z&voe~&a)47>&iRNW2ksqOO1dW4W92a5;guI-=TgmHdam(`u1+Pxi%QB_02^16lZ+S zth&xC5(>nqh%$PQaQ2rW#Jz6JuB6vb?~bQLuTvweruF!f!9N5%vLSeXOOJ;ur+mar6}1*-|7%1>kK9>acpW6uxJucl!{8 z(|2{ntfutgzoMzKZ$}K>EauizL3Sp0I@C(6B{ndVXL991Cn1&-SG!(yozFJDFY;QK zQ%gz?Qir#~OjU~W>CV`d_e1=1@&In=xMB-utdHOBN84TGC^o1gO<9vPBd>jhUwt{| zc|N@#Jog_X=-@SZYUe9%f$3d)?KbO(!+v-=h8pk2X5zM)4}92r3~Oj64!8Hh%T52Q$;`yapUkvr6@;G+%tU{3cl(~A zuY|6du&CvRlkOV0b~Y2H)L8YJN}Yg#nYg;f38F~|%8N8&O(4(RhE?^j!&G(T%8+u@ zoK4MOZ5_G$Whrw=ol(zNSMF<8f?CvQC6?*Qrfrxt$8{dy*ip8tQG_#Bi4_KRmDv~b zk;b|3&+_gv#y6Mza8KOcVj%mCrv{TgW}61}ke?f6qKgZ?2<~-|-N&V){!(vv>o<{$ zAEsgfu~enOUol}{3P$AmFo*1+xVAeP8C+*E;iS+xnuN3jdN@8W5$o0Qu&z!n{@5&W zbrL<4s0r$qn<#2`iNp`BAO1dy;EqlXCt`cpLy_s6i?!J<4g5MjE^`ts3; zSF8;>MFwDcO^x^`$p`iN210c^NK9bOzU^cnhCU7wM#DXEa(fWE^F2Q~1AnWp!IFL& zv1uf|i0)~SYpM~AOvx>$=3KbIOZZ_;TQB!JcC~fX$U>N@fyB9;`eS>sd9pa7e@Ac)0=cyRO zzQA&&t{i_N1>?h6>kg|eU5b)1k~Qt0haW_ncKhfFPk;6))MeA>q&ablx}3dEFN$Hl zfgg10o)R}gBGLVuA8NKgEb^nmU}oWuE-SU-(sBBfJoiWC>T+?iZ4g{H2f#b0RP+z< z$Gl$w=zF6?4CBv92n<9$-x5*q$O{pJgK$(+B084Q=jLt@dY>#2$Ftlqms;<*Hl;$Z z#0`bR!2)kGJSU^UJb#O&1FJE{`q{{s_Q&-#SrNjT7h5li5+E) zk@t(s(2-scrr{H0T1p96(4&8#u^hLv7>nq$k(4`A_U&1OJLl+wbbXHOc03=dmc&xB z=1bibxi~xC6ZM$uvArJ8=hPL>~2VvVh3dei+*_Urk}JMcCA}0GbR;bFLnFR^ftoij`++smvO^}iQtvZFvsjjgrepqZFZlL1mU)}gFuc+m z35FwN=Z&fGvgCgL)>GcxmVz5Cs6%PlK~Da(4{h?8F|(zmG^Ib@xG{eCdZvk#>9IIY zkAe%y4dpaujV)$IT~ty%`7$;f%OClpz_X5Abv}f6Gy6FG+HyyC4YkjKh@MtUMn(r9 zJ}(emZq<}8Sp(i&$QedaP1&8A@>2GCb&k}OH4dvW=YR(BUu#N3dM&tZ52l}5EtykF z-&bN=e|@N(Cugef4{B!a)sh<$GPL*T~_k^lu}f7afRDlYkB!`@&BvpyyIg`yEm@wDq$CkgkVKkC0I40UV;?_ zS-lf2q_-)VOcLp3CQTxhR3TjmAtabfeTlX@t9MZs8};RP_UHX${q>CJGc)qJpL_26 zKIdH5_u!~sC??(T<9U~IysHkwI{N@#cvXgDk~3VfFM#zUB~K#k;EqT9S#7%oB|UXm zQ(w&q?!}n-lOD+h4qX1F5Fa1v@pG$r)Lt(@q3EUtjF`Y(xAJjR_M`)ohqB9a@gFr6 zR*Y$1nkhG7Lmgps9KCkP@R;J>w35bK;TT>3}o`$aC z1M1nW9Y4)UM!&slrFWGHjZ4-+xilW%4KrcAZsJX8l7R8Ij9Df=&Ak-~n0>;S&!w-2 zo8+NFYmDhRK`+eLL^LrsVROkNhTcnrX`l&rNRDA+zVNATn@}V9?<9|8G-}t1K|4ax zs&g{B<}~Nf^bmM@e>=|SCuzB?^M2t;1Y(wD5F3A}Lid9~sI3+aWQK5)ei08$VgysV zR^Uj0?1ND{cF!osVj1TxYxER=K5T_SSKM6B@T#qFHjPAHNd$jhzXjV(MTdMmnB%V$ z<8^&K&YEj@)u#xqlHa&tx0)@N7GmZGS)a@1aFRm-%!Dg#Z9S0ew()zi7orG z+wEk$5^l`*ZTm2Puz2ES4)4?T=9%Jn>{y-vE8E@-mGj7!w(Br;dT$1O5MS5%b?6h^ zo5?5i=$4R(#^>dAMI;QflQ3v#ANp5GuD4^d#NBEck#x%cfjYxYHQMgD$N+sV0PbquFD?8UXCLGXCGmN~V15MUmHGQV|f1Mi^ZhR*1TYyjb!m1uk`qhyZdEGo<9yVHjQP}@bzesD)ZTG3|}~=V4-+6 z8<$$qPuA4_4H8gcW5onvV;b#CKx{uNwyG9pm3AGRCtGp7f)H?lq?GU`_Y3Z%}PP@cy4t9wy-LRj|gGnhTS5*MYOn6o^KzU38I7!is_s%(xn z-HGpIeYX86n?@PiG5dqCzOQBQ==^PP_(9mJ+BEKUD#gksIvjeRz(IeO2y;S*$)EKs zNGnGCQ8`P82D4X85q^u482m>yPp1{4M11T4o{lWYEx?4fF|hw(IrV1waCs*F?qiFY z)nF5*7D=zllMDDoYCvK3!i+AP$8w1QmzxQbXXISEA6bu@Yise=W)3Ufq~J_yJiH9E z+0i-)o98AVD0DX8S0>8`Z+F?!9+5T^fitE?1c2t>!R7@>r3sNhl4O z!zH4RUOqe-bsNm(=c)+2Ya;zYBj++l&Rhqtr69L_E?*xFM~dX~TECsk8FF7C_y0Z4 zs(Cp)yUT!N`#_BCn8!0y_TivtKWY{fvTIo-)Z)>4YF*5~zTb`4QK4vYyqIlQ@5CfI zZ#>B^;>cIqaq7MFrVPku28A1AByso1jdZOkMeg@HEbFv^RW4gF?zs;BH3@XKEWvL_ z^e~CiGvn7{n9F>=UmMKap+%S=e$3O)e7VQ6Q2O@9z&1$5_S^EYLHaCizTnBq_)Rdq z5({@*civo@13RhX-iULh$AnB=wUb!R-i7squ@=)c9=l7OX(AqL^T+X+Gu@duorGbf z!j&5C%+q7mp__Ugx-W3%=8J1F%qkJtx#C%fkpD;6fcu-eu>0(2_*_d8PmT)%M(UAK zl8h!lxiWo(_@@Kp`DMD&Aew6j$vxfN>%cDKBQWGp3JxBZxgoW+M<(C;2V<{p;jdOi zqJ!una<eC4y6KH+D z81rO()_fPug_nc{;U;X8u@PKRU5IVdW3a|4REVSnI4Wn1$UlNPs?%niYbw9a71NR zaz%L=ZZ?fX=A#{)*k~K-G}6KSZ86;nOR-<_{NwX;xj%RdPXD17=D-HF_mOp5YRrpr zlX%6e7>)JP$59*4+C@bu*2vyh8_N#Dh8^c3JuhQpy&RuX3Ph-UV@7&uhO`N2J!V@E|nyH?hL%4inLTD`(a>Ix;1 z>_1wEolO&wUmMO6InVBRl?eA+8WzNbBXaGxOw1isPh&^td4 zHZRuFc7yaPm%8u2=lQ?q^F6Oq?AoCa?S-@bqVYMpU(LrCiCI#7E^w=39(s#rud3}u zE|z#I8_vQucNnsZFK=eyz%JpO?ki=-B4Pd2h*!d)fVZSRd+z5@6jtTZVTvMZ-`aK1A`-R%K@(?!B<`4rXw#)NP;JNKD!$gOS3X+LINAms``R?2>{bZ)Hsj zNN3njNidb)@O*VTYh~ZNRveCk=yWz25|3_15t6q_XMM*wG;of<@Q>*Rjoe&~7~kz7poQ_`H^d z#q)V~B$i68?cd{EvGpti`eZ;mDFEXJU*Z^TI`$_ApsnT#J7h>N@f+e>xqgLJ73)#Q zBoG;j%ba>I4YgK*_!$@IHaHD&^8;~b`WZU!k$p!zEI+v=?AEDOojh= z(Y3x3|9D6$l6r~;edBiS+?k39(X9VHzl6763K#To047K0b3nH=q>8>Y8k^X6avB;O z5{>1+jkLU)3hRRb=+G#K4JV|ar@SY7ayA!jNP?Zz>kr+?V)pBGi2f*A*1{}ylsIpU zXfK~MT`~uex(?4JK4vCjv$^qDVB>>euVQX|EA^t~8azqL{H{w zt!#c228_0`8m&{aI4DKu~Jqtj5bryLokM1e)Y3q4O`}g4jr` zGFBinu!#B)9fpK>BGrBqXN2lu_SzloBD0tg9)+>aZm1Q;!j@;zxU}CDbMn%dBV&~% zb@;y4soc{(7Rwbb_`yAev(jSl=7KZQUM6$;r)c!+>n!^AWLD0S_|D%62Xd2{QW}Mc zM;)<$Z!&lN5QY9mj;MZ}EM8PS`q?;0pW+mLxi7I)#A@_RP2ngz@iZS=g?1lPSa?r- zZ(r=;vN)9%;(_xYZjVA$66b%4#HKawu-=%&@M7^P+Pb6gega3uW!b=D1I-4 zdnwU%kw50OIlw~}N>~;7;_jaZIe(}MNgt)RT;M_0w@{Du&dv0~y;VhA92*RWKuuz|=o8 zSR~KF!^;EPDue}eU34@pJ@B$9k*5MB<}GnY_lkJ-xfz9r1KjcFjyPWZ5{=CDZpcu^ za^?IOJg?^_dbJpCk+FTCaD@kA_{c9BXRf>8ef=2by^g}jQ7%~YcQi9sMWG_u83~Pr z$#X*wK5@bX%NQmulsv|8C(Q7P;Va?&pN?>Z#jzOPanr%_yaRT0jAf;)$L)T0fP*5I zv73e4@3z|^G4Gq-dLk6q_w9OH#e)G z7`T~l#mBuyr4$c!HXBOZvuTY2jUKFLmZxZ1>4i~cNxUUFzgdI5a9!g1r}p7UtoB68 zV<<=bqQioIPFQ6h%F95Ef-$XNzUI(G~C|YbzG023Qs&gs^U;#%!Kvx#PU2P4KkiR z_IRM;p@JjEMWJ?t2QK<4`1+k5(YxHSYrcZsq93s|cgG?(1>4WnV@0YPhHO#rlGNlE z*LOoZBPEv{&|#*dE6RM7%wMB}$7vVb`Af->V|92r&;|Wgs<=eB;Gn+zSbsatY3IXP@1_a{gFj4_I^G(sLhWilJf5Iu!fqAD zH}i${B^^69^~S?0AM98aNo{K%ObwMad0;rl?C`}_4{vny3ZXm29~Y@c_>w?2jtE5E zGr|#A?#l#A$<2;Y!5J#XTnoX1%Sv=8ai{Gv(Zhx-G3uog@9qu9|Trt3IDSgMt zXZ5bKH`xiBPT0|Lga)xs>mohM{X7RnKx4RfK#+-WSd0ggZ(c8#jfQt>x_MuS8zxWDeV?6aAzTf7IHr<5rpfxeDp^Ys0i+ z@znHFV3ofOJ;kr#TJD8c!8RNqUYlvMc5TYD;ZmJ2IJbJ@@0&LC3y`tx>50o-CNoT< z!_`a=Sc})#SfxW~YvFekPG*|CHjQ$}f}xXn%wAqsyW`^g$!xG%@;9Nv_4sJRdL}v; z8{EGc=g*UE*!GSZcJ82K4{B1dV zk`}tRK3KMR3NMxV!Lh#&R3(#`)i(fb)@oo=V9mc10@10B1`l-OIO0tZ9#wivj}0u+=Bfjrehr?GP5k`VWGo~Kn1!Tv*0wTvn70yz5Bfdi(RB{<>Lhl^C9dK zCHaHDJrOc%2s=w`a?;%sh8Gsh>?F_Vh9^FJKZM84b@)Eh6BZ9F8TdRBz8Rk1jB|9| zUTiqu8*e&GpVUA4Q2ShsszLrpj{TKoIyqNN^h5t<{dncB29~bA2rT`TEstx_r$mdg zU47}((jO0-YB6J0A9kH6Uhr5SblPIhSFwTc9OQ$)?)Id2b&z=8HLz{lgHxZ2Z}^x7 z4Lp8f=}Ymx6=-m$VK*k9mRe1;2BV&Lp`%_rbgmkF?%IVf#c!$}ufhEdow;IjI5xG^ z;FLvYZumj^T%Ga8PZ!O2YDEP4ukpsbATvJS5`k1RZ}he?N1TpBZ;LN5V>ew^A`?w(tw%mZ{Kqz8TH#M56yg;S^}hcu$_i00$*ZQ_UD6Jk)wM z3N$P;qhF%*402N7;~X<;{bf9V62^zU8Dr$U+WJog?j7#Vy%Hndmb3T2L;GA=IkK;R=ba~=Y43-c9y>IvGc`|-YrTwfNMe1>1}F%TBMw#f{CmEkyFHw&GK5@J}5l2w}an_+j*qbVvg@xIrb_Q6<9Q?AGhL$4wqJhW`e zixOKqX?&3Mw-LRDhNH!B9~kX1Vu?pMn!nbde}WO?awVsdtHHYfBlZ@}{?XqxIOk`? zqje*2^qn{Agc{MRujtUzy-`ozKX`rw7LM}9^jstM6W!~8>+;(vH{z}`@e|AM=st}& z@|LV)CTh6q+c0>vXwti?@G`Ltt0gyc{<-jjayzo6@Z83aP<}Jco{i5MPFZLqm%j${ z4qY+Szv_)<;zb|U_NKwyUxQA@{#Yhjquf(IxF6<+vZx1!%yrTqyoDc}tsfi4X8Ysi z9@z_>o*2|Cq{p%Ni0?gqYIq=?uod>c__+O<;qGeDGc1(P{Q1oATD(&u7Wral>NCUH zH`2dvsV}tspBeO#A);Xuj?C$&hWNUnh*;)}#Q{$ZJM2PHcdjo&hdwnt5wFR$F}^r? z?}@?rUMQM&_C<2Q6GNkx($lF{_KrSJ40WX*9V&j~cb{tv;SzH#jnTs7X^kPrFAUi; zwdnPz#xNi~3@44XSpKZWaHKK}eJ}fqbB5;19>_J8Ua2VuS$oPK=Z^JT6$=x+q{coKAnblvt z^wXEBXRco9xzv5-%1&d)_N()@eVsbZyVt4nM}x1|yY;_b7dHEP-EQ*rTDR`kYd!g< zf8PI4Ui@>N-r?)DpYhl0&)%adG Dvh#e+ literal 0 HcmV?d00001 diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ebe195c60..7a143e850 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1586,6 +1586,12 @@ Camera constants: "raw_crop": [ 0, 5, 7752, 5184 ] }, + { // Quality C + "make_model": "FUJIFILM DBP for GX680", + "dcraw_matrix": [ 12741, -4916, -1420, -8510, 16791, 1715, -1767, 2302, 7771 ], // same as S2Pro as per LibRaw + "ranges": { "white": 4096, "black": 132 } + }, + { // Quality C, Leica C-Lux names can differ? "make_model" : [ "LEICA C-LUX", "LEICA CAM-DC25" ], "dcraw_matrix" : [7790, -2736, -755, -3452, 11870, 1769, -628, 1647, 4898] diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 4ab1694b8..bdd92c7da 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2464,6 +2464,30 @@ void CLASS unpacked_load_raw() } } +// RT - from LibRaw +void CLASS 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 = 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 +} // RT void CLASS sony_arq_load_raw() @@ -10067,6 +10091,9 @@ canon_a5: } else if (!strcmp(model, "X-Pro3") || !strcmp(model, "X-T3") || !strcmp(model, "X-T30") || !strcmp(model, "X-T4") || !strcmp(model, "X100V") || !strcmp(model, "X-S10")) { width = raw_width = 6384; height = raw_height = 4182; + } else if (!strcmp(model, "DBP for GX680")) { // Special case for #4204 + width = raw_width = 5504; + height = raw_height = 3856; } top_margin = (raw_height - height) >> 2 << 1; left_margin = (raw_width - width ) >> 2 << 1; @@ -10074,6 +10101,16 @@ canon_a5: if (width == 4032 || width == 4952 || width == 6032 || width == 8280) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; if (width == 4936) left_margin = 4; + if (width == 5504) { // #4204, taken from LibRaw + left_margin = 32; + top_margin = 8; + width = raw_width - 2*left_margin; + height = raw_height - 2*top_margin; + load_raw = &CLASS unpacked_load_raw_FujiDBP; + filters = 0x16161616; + load_flags = 0; + flip = 6; + } if (!strcmp(model,"HS50EXR") || !strcmp(model,"F900EXR")) { width += 2; diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 849012cb7..f78bd8aa6 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -432,6 +432,7 @@ void parse_hasselblad_gain(); void hasselblad_load_raw(); void leaf_hdr_load_raw(); void unpacked_load_raw(); +void unpacked_load_raw_FujiDBP(); void sinar_4shot_load_raw(); void imacon_full_load_raw(); void packed_load_raw(); From 2101b846c386035f8d1ca5f2d68fe9fc3227d43d Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Mon, 2 Jan 2023 21:27:12 +0100 Subject: [PATCH 157/326] Implement file sorting in thumbnail view (#6449) * Use mtime as fallback timestamp for files without EXIF data As suggested in #6449, with date-based sorting it can be useful to have at least *some* sort of time-relevant information for EXIF-less files, to prevent them from falling back to getting sorted alphabetically all the time. This commit simply defaults the file timestamp to the file's mtime as returned by g_stat. For annoying reasons, it doesn't suffice to merely forward the timestamp to the FileData structs - we also need to keep track of it inside FilesData to cover the case of a file with 0 frames in it. * Add DateTime to Thumbnail Putting it here facilitate easier sorting without having to re-construct the DateTime on every comparison. To simplify things moving forwards, use the Glib::DateTime struct right away. This struct also contains timezone information, but we don't currently care about timezone - so just use the local timezone as the best approximation. (Nothing currently depends on getting the timezone right, anyway) In addition to the above, this commit also changes the logic to allow generating datetime strings even for files with missing EXIF (which makes sense as a result of the previous commit allowing the use of mtime instead). * Implement file sorting in thumbnail view For simplicity, I decided to only implement the attributes that I could verily easily reach from the existing metadata exported by Thumbnail. Ideally, I would also like to be able to sort by "last modified" but I'm not sure of the best way to reach this from this place in the code. It's worth pointing out that, with the current implementation, the list will not dynamically re-sort itself until you re-select the sorting method - even if you make changes to the files that would otherwise affect the sorting (e.g. changing the rank while sorting by rank). One might even call this a feature, not a bug, since it prevents thumbnails from moving around while you're trying to re-label them. You can always re-select "sort by ..." from the context menu to force a re-sort. Fixes #3317 Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> --- rtdata/languages/default | 8 +++ rtengine/imagedata.cc | 39 +++++++++++---- rtengine/imagedata.h | 4 +- rtgui/batchqueueentry.cc | 2 +- rtgui/filebrowser.cc | 89 +++++++++++++++++++++++++-------- rtgui/filebrowser.h | 5 ++ rtgui/filebrowserentry.cc | 4 +- rtgui/options.cc | 17 +++++++ rtgui/options.h | 11 +++++ rtgui/thumbbrowserbase.cc | 44 ++++++++++++++++- rtgui/thumbbrowserbase.h | 3 +- rtgui/thumbbrowserentrybase.cc | 5 +- rtgui/thumbbrowserentrybase.h | 32 ++++++++++-- rtgui/thumbnail.cc | 90 ++++++++++++++++++++-------------- rtgui/thumbnail.h | 3 ++ 15 files changed, 275 insertions(+), 81 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e5e053655..a33b2a9cd 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -166,6 +166,7 @@ FILEBROWSER_POPUPREMOVE;Delete permanently FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version FILEBROWSER_POPUPRENAME;Rename FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPSORTBY;Sort Files FILEBROWSER_POPUPTRASH;Move to trash FILEBROWSER_POPUPUNRANK;Unrank FILEBROWSER_POPUPUNTRASH;Remove from trash @@ -2060,6 +2061,13 @@ SAVEDLG_WARNFILENAME;File will be named SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. 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_NAME;By Name +SORT_BY_DATE;By Date +SORT_BY_EXIF;By EXIF +SORT_BY_RANK;By Rank +SORT_BY_LABEL;By Color Label +SORT_DESCENDING;Descending TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By TC_PRIM_GREX;Gx diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 3c10e7dc0..fb2fcaf3a 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -19,6 +19,7 @@ #include #include +#include #include @@ -57,7 +58,8 @@ template T getFromFrame( const std::vector>& frames, std::size_t frame, - const std::function& function + const std::function& function, + T defval = {} ) { if (frame < frames.size()) { @@ -66,7 +68,7 @@ T getFromFrame( if (!frames.empty()) { return function(*frames[0]); } - return {}; + return defval; } const std::string& validateUft8(const std::string& str, const std::string& on_error = "???") @@ -85,11 +87,21 @@ FramesMetaData* FramesMetaData::fromFile(const Glib::ustring& fname, std::unique return new FramesData(fname, std::move(rml), firstFrameOnly); } -FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) : +static struct tm timeFromTS(const time_t ts) +{ +#if !defined(WIN32) + struct tm tm; + return *gmtime_r(&ts, &tm); +#else + return *gmtime(&ts); +#endif +} + +FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir, time_t ts) : frameRootDir(frameRootDir_), iptc(nullptr), - time{}, - timeStamp{}, + time(timeFromTS(ts)), + timeStamp(ts), iso_speed(0), aperture(0.), focal_len(0.), @@ -1068,7 +1080,8 @@ tm FramesData::getDateTime(unsigned int frame) const [](const FrameData& frame_data) { return frame_data.getDateTime(); - } + }, + modTime ); } @@ -1080,7 +1093,8 @@ time_t FramesData::getDateTimeAsTS(unsigned int frame) const [](const FrameData& frame_data) { return frame_data.getDateTimeAsTS(); - } + }, + modTimeStamp ); } @@ -1366,6 +1380,11 @@ failure: FramesData::FramesData(const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) : iptc(nullptr), dcrawFrameCount(0) { + GStatBuf statbuf = {}; + g_stat(fname.c_str(), &statbuf); + modTimeStamp = statbuf.st_mtime; + modTime = timeFromTS(modTimeStamp); + if (rml && (rml->exifBase >= 0 || rml->ciffBase >= 0)) { FILE* f = g_fopen(fname.c_str(), "rb"); @@ -1384,7 +1403,7 @@ FramesData::FramesData(const Glib::ustring& fname, std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); + frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0), modTimeStamp))); } for (auto currRoot : roots) { @@ -1410,7 +1429,7 @@ FramesData::FramesData(const Glib::ustring& fname, std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); + frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0), modTimeStamp))); } rewind(exifManager.f); // Not sure this is necessary @@ -1430,7 +1449,7 @@ FramesData::FramesData(const Glib::ustring& fname, std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0)))); + frames.push_back(std::unique_ptr(new FrameData(currFrame, currFrame->getRoot(), roots.at(0), modTimeStamp))); } for (auto currRoot : roots) { diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 4bf9bdf5b..752fafab3 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -72,7 +72,7 @@ protected: public: - FrameData (rtexif::TagDirectory* frameRootDir, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir); + FrameData (rtexif::TagDirectory* frameRootDir, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir, time_t ts = 0); virtual ~FrameData (); bool getPixelShift () const; @@ -109,6 +109,8 @@ private: std::vector roots; IptcData* iptc; unsigned int dcrawFrameCount; + struct tm modTime; + time_t modTimeStamp; public: explicit FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 31a6f40c7..9fe4dd605 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -34,7 +34,7 @@ bool BatchQueueEntry::iconsLoaded(false); Glib::RefPtr BatchQueueEntry::savedAsIcon; BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm, bool overwrite) : - ThumbBrowserEntryBase(fname), + ThumbBrowserEntryBase(fname, thm), opreview(nullptr), origpw(prevw), origph(prevh), diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 66c84d86e..ac4a27dec 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -167,6 +167,41 @@ FileBrowser::FileBrowser () : pmenu->attach (*Gtk::manage(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p + 1); p++; + /*********************** + * sort + ***********************/ + const std::array cnameSortOrders = { + M("SORT_ASCENDING"), + M("SORT_DESCENDING"), + }; + + const std::array cnameSortMethods = { + M("SORT_BY_NAME"), + M("SORT_BY_DATE"), + M("SORT_BY_EXIF"), + M("SORT_BY_RANK"), + M("SORT_BY_LABEL"), + }; + + pmenu->attach (*Gtk::manage(menuSort = new Gtk::MenuItem (M("FILEBROWSER_POPUPSORTBY"))), 0, 1, p, p + 1); + p++; + Gtk::Menu* submenuSort = Gtk::manage (new Gtk::Menu ()); + Gtk::RadioButtonGroup sortOrderGroup, sortMethodGroup; + for (size_t i = 0; i < cnameSortOrders.size(); i++) { + submenuSort->attach (*Gtk::manage(sortOrder[i] = new Gtk::RadioMenuItem (sortOrderGroup, cnameSortOrders[i])), 0, 1, p, p + 1); + p++; + sortOrder[i]->set_active (i == options.sortDescending); + } + submenuSort->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p + 1); + p++; + for (size_t i = 0; i < cnameSortMethods.size(); i++) { + submenuSort->attach (*Gtk::manage(sortMethod[i] = new Gtk::RadioMenuItem (sortMethodGroup, cnameSortMethods[i])), 0, 1, p, p + 1); + p++; + sortMethod[i]->set_active (i == options.sortMethod); + } + submenuSort->show_all (); + menuSort->set_submenu (*submenuSort); + /*********************** * rank ***********************/ @@ -427,6 +462,14 @@ FileBrowser::FileBrowser () : inspect->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), inspect)); } + for (int i = 0; i < 2; i++) { + sortOrder[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), sortOrder[i])); + } + + for (int i = 0; i < Options::SORT_METHOD_COUNT; i++) { + sortMethod[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), sortMethod[i])); + } + for (int i = 0; i < 6; i++) { rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); } @@ -610,27 +653,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) entry->getThumbButtonSet()->setButtonListener(this); entry->resize(getThumbnailHeight()); entry->filtered = !checkFilter(entry); - - // find place in abc order - { - MYWRITERLOCK(l, entryRW); - - fd.insert( - std::lower_bound( - fd.begin(), - fd.end(), - entry, - [](const ThumbBrowserEntryBase* a, const ThumbBrowserEntryBase* b) - { - return *a < *b; - } - ), - entry - ); - - initEntry(entry); - } - redraw(entry); + insertEntry(entry); } FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) @@ -724,6 +747,18 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) return; } + for (int i = 0; i < 2; i++) + if (m == sortOrder[i]) { + sortOrderRequested (i); + return; + } + + for (int i = 0; i < Options::SORT_METHOD_COUNT; i++) + if (m == sortMethod[i]) { + sortMethodRequested (i); + return; + } + for (int i = 0; i < 6; i++) if (m == rank[i]) { rankingRequested (mselected, i); @@ -1632,6 +1667,18 @@ void FileBrowser::fromTrashRequested (std::vector tbe) applyFilter (filter); } +void FileBrowser::sortMethodRequested (int method) +{ + options.sortMethod = Options::SortMethod(method); + resort (); +} + +void FileBrowser::sortOrderRequested (int order) +{ + options.sortDescending = !!order; + resort (); +} + void FileBrowser::rankingRequested (std::vector tbe, int rank) { diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 4602ba9bb..0df1cf9eb 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -83,9 +83,12 @@ protected: Gtk::MenuItem* open; Gtk::MenuItem* inspect; Gtk::MenuItem* selall; + Gtk::RadioMenuItem* sortMethod[Options::SORT_METHOD_COUNT]; + Gtk::RadioMenuItem* sortOrder[2]; Gtk::MenuItem* copyTo; Gtk::MenuItem* moveTo; + Gtk::MenuItem* menuSort; Gtk::MenuItem* menuRank; Gtk::MenuItem* menuLabel; Gtk::MenuItem* menuFileOperations; @@ -131,6 +134,8 @@ protected: void toTrashRequested (std::vector tbe); void fromTrashRequested (std::vector tbe); + void sortMethodRequested (int method); + void sortOrderRequested (int order); void rankingRequested (std::vector tbe, int rank); void colorlabelRequested (std::vector tbe, int colorlabel); void requestRanking (int rank); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index bf3f11a79..b89fe340d 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -45,10 +45,8 @@ Glib::RefPtr FileBrowserEntry::hdr; Glib::RefPtr FileBrowserEntry::ps; FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) - : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), press_x(0), press_y(0), action_x(0), action_y(0), rot_deg(0.0), landscape(true), cropParams(new rtengine::procparams::CropParams), cropgl(nullptr), state(SNormal), crop_custom_ratio(0.f) + : ThumbBrowserEntryBase (fname, thm), 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) { - thumbnail = thm; - feih = new FileBrowserEntryIdleHelper; feih->fbentry = this; feih->destroyed = false; diff --git a/rtgui/options.cc b/rtgui/options.cc index a1cc88c03..b2ef17d77 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -685,6 +685,8 @@ void Options::setDefaults() lastICCProfCreatorDir = ""; gimpPluginShowInfoDialog = true; maxRecentFolders = 15; + sortMethod = SORT_BY_NAME; + sortDescending = false; rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc cropGuides = CROP_GUIDE_FULL; cropAutoFit = false; @@ -1150,6 +1152,19 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("File Browser", "RecentFolders")) { recentFolders = keyFile.get_string_list("File Browser", "RecentFolders"); } + + if (keyFile.has_key("File Browser", "SortMethod")) { + int v = keyFile.get_integer("File Browser", "SortMethod"); + if (v < int(0) || v >= int(SORT_METHOD_COUNT)) { + sortMethod = SORT_BY_NAME; + } else { + sortMethod = SortMethod(v); + } + } + + if (keyFile.has_key("File Browser", "SortDescending")) { + sortDescending = keyFile.get_boolean("File Browser", "SortDescending"); + } } if (keyFile.has_group("Clipping Indication")) { @@ -2217,6 +2232,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string_list("File Browser", "RecentFolders", temp); } + keyFile.set_integer("File Browser", "SortMethod", sortMethod); + keyFile.set_boolean("File Browser", "SortDescending", sortDescending); 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 bc5e41c91..d7523e699 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -452,6 +452,17 @@ public: size_t maxRecentFolders; // max. number of recent folders stored in options file std::vector recentFolders; // List containing all recent folders + enum SortMethod { + SORT_BY_NAME, + SORT_BY_DATE, + SORT_BY_EXIF, + SORT_BY_RANK, + SORT_BY_LABEL, + SORT_METHOD_COUNT, + }; + SortMethod sortMethod; // remembers current state of file browser + bool sortDescending; + Options (); diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 06c662e51..8f3499c2a 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -1091,6 +1091,25 @@ bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) } +void ThumbBrowserBase::resort () +{ + { + MYWRITERLOCK(l, entryRW); + + std::sort( + fd.begin(), + fd.end(), + [](const ThumbBrowserEntryBase* a, const ThumbBrowserEntryBase* b) + { + bool lt = a->compare(*b, options.sortMethod); + return options.sortDescending ? !lt : lt; + } + ); + } + + redraw (); +} + void ThumbBrowserBase::redraw (ThumbBrowserEntryBase* entry) { @@ -1218,9 +1237,30 @@ void ThumbBrowserBase::enableTabMode(bool enable) } } -void ThumbBrowserBase::initEntry (ThumbBrowserEntryBase* entry) +void ThumbBrowserBase::insertEntry (ThumbBrowserEntryBase* entry) { - entry->setOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + // find place in sort order + { + MYWRITERLOCK(l, entryRW); + + fd.insert( + std::lower_bound( + fd.begin(), + fd.end(), + entry, + [](const ThumbBrowserEntryBase* a, const ThumbBrowserEntryBase* b) + { + bool lt = a->compare(*b, options.sortMethod); + return options.sortDescending ? !lt : lt; + } + ), + entry + ); + + entry->setOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + } + + redraw (); } void ThumbBrowserBase::getScrollPosition (double& h, double& v) diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index 2d41cdfab..8c1ec49c8 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -208,12 +208,13 @@ public: return fd; } void on_style_updated () override; + void resort (); // re-apply sort method void redraw (ThumbBrowserEntryBase* entry = nullptr); // arrange files and draw area void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshEditedState (const std::set& efiles); - void initEntry (ThumbBrowserEntryBase* entry); + void insertEntry (ThumbBrowserEntryBase* entry); void getScrollPosition (double& h, double& v); void setScrollPosition (double h, double v); diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 306b491be..3d1e6bdc4 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -119,7 +119,7 @@ Glib::ustring getPaddedName(const Glib::ustring& name) } -ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) : +ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname, Thumbnail *thm) : fnlabw(0), fnlabh(0), dtlabw(0), @@ -153,7 +153,8 @@ ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) : bbPreview(nullptr), cursor_type(CSUndefined), collate_name(getPaddedName(dispname).casefold_collate_key()), - thumbnail(nullptr), + collate_exif(getPaddedName(thm->getExifString()).casefold_collate_key()), + thumbnail(thm), filename(fname), selected(false), drawable(false), diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 764f806fd..3db03a96e 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -26,6 +26,8 @@ #include "guiutils.h" #include "lwbuttonset.h" #include "threadutils.h" +#include "options.h" +#include "thumbnail.h" #include "../rtengine/coord2d.h" @@ -95,6 +97,7 @@ protected: private: const std::string collate_name; + const std::string collate_exif; public: @@ -117,7 +120,7 @@ public: bool updatepriority; eWithFilename withFilename; - explicit ThumbBrowserEntryBase (const Glib::ustring& fname); + explicit ThumbBrowserEntryBase (const Glib::ustring& fname, Thumbnail *thm); virtual ~ThumbBrowserEntryBase (); void setParent (ThumbBrowserBase* l) @@ -174,9 +177,32 @@ public: void setPosition (int x, int y, int w, int h); void setOffset (int x, int y); - bool operator <(const ThumbBrowserEntryBase& other) const + bool compare (const ThumbBrowserEntryBase& other, Options::SortMethod method) const { - return collate_name < other.collate_name; + int cmp = 0; + switch (method){ + case Options::SORT_BY_NAME: + return collate_name < other.collate_name; + case Options::SORT_BY_DATE: + cmp = thumbnail->getDateTime().compare(other.thumbnail->getDateTime()); + break; + case Options::SORT_BY_EXIF: + cmp = collate_exif.compare(other.collate_exif); + break; + case Options::SORT_BY_RANK: + cmp = thumbnail->getRank() - other.thumbnail->getRank(); + break; + case Options::SORT_BY_LABEL: + cmp = thumbnail->getColorLabel() - other.thumbnail->getColorLabel(); + break; + case Options::SORT_METHOD_COUNT: abort(); + } + + // Always fall back to sorting by name + if (!cmp) + cmp = collate_name.compare(other.collate_name); + + return cmp < 0; } virtual void refreshThumbnailImage () = 0; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 2baf03247..30766ebc9 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -31,6 +31,7 @@ #include "../rtengine/procparams.h" #include "../rtengine/rtthumbnail.h" #include +#include #include "../rtengine/dynamicprofile.h" #include "../rtengine/profilestore.h" @@ -718,11 +719,44 @@ rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::Pro void Thumbnail::generateExifDateTimeStrings () { + if (cfs.timeValid) { + std::string dateFormat = options.dateFormat; + std::ostringstream ostr; + bool spec = false; - exifString = ""; - dateTimeString = ""; + for (size_t i = 0; i < dateFormat.size(); i++) + if (spec && dateFormat[i] == 'y') { + ostr << cfs.year; + spec = false; + } else if (spec && dateFormat[i] == 'm') { + ostr << (int)cfs.month; + spec = false; + } else if (spec && dateFormat[i] == 'd') { + ostr << (int)cfs.day; + spec = false; + } else if (dateFormat[i] == '%') { + spec = true; + } else { + ostr << (char)dateFormat[i]; + spec = false; + } + + ostr << " " << (int)cfs.hour; + ostr << ":" << std::setw(2) << std::setfill('0') << (int)cfs.min; + ostr << ":" << std::setw(2) << std::setfill('0') << (int)cfs.sec; + + dateTimeString = ostr.str (); + dateTime = Glib::DateTime::create_local(cfs.year, cfs.month, cfs.day, + cfs.hour, cfs.min, cfs.sec); + } + + if (!dateTime.gobj() || !cfs.timeValid) { + dateTimeString = ""; + dateTime = Glib::DateTime::create_now_utc(0); + } if (!cfs.exifValid) { + exifString = ""; return; } @@ -731,33 +765,6 @@ void Thumbnail::generateExifDateTimeStrings () if (options.fbShowExpComp && cfs.expcomp != "0.00" && !cfs.expcomp.empty()) { // don't show exposure compensation if it is 0.00EV;old cache files do not have ExpComp, so value will not be displayed. exifString = Glib::ustring::compose ("%1 %2EV", exifString, cfs.expcomp); // append exposure compensation to exifString } - - std::string dateFormat = options.dateFormat; - std::ostringstream ostr; - bool spec = false; - - for (size_t i = 0; i < dateFormat.size(); i++) - if (spec && dateFormat[i] == 'y') { - ostr << cfs.year; - spec = false; - } else if (spec && dateFormat[i] == 'm') { - ostr << (int)cfs.month; - spec = false; - } else if (spec && dateFormat[i] == 'd') { - ostr << (int)cfs.day; - spec = false; - } else if (dateFormat[i] == '%') { - spec = true; - } else { - ostr << (char)dateFormat[i]; - spec = false; - } - - ostr << " " << (int)cfs.hour; - ostr << ":" << std::setw(2) << std::setfill('0') << (int)cfs.min; - ostr << ":" << std::setw(2) << std::setfill('0') << (int)cfs.sec; - - dateTimeString = ostr.str (); } const Glib::ustring& Thumbnail::getExifString () const @@ -772,6 +779,12 @@ const Glib::ustring& Thumbnail::getDateTimeString () const return dateTimeString; } +const Glib::DateTime& Thumbnail::getDateTime () const +{ + + return dateTime; +} + void Thumbnail::getAutoWB (double& temp, double& green, double equal, double tempBias) { if (cfs.redAWBMul != -1.0) { @@ -802,6 +815,16 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptrgetDateTimeAsTS() > 0) { + cfs.year = 1900 + idata->getDateTime().tm_year; + cfs.month = idata->getDateTime().tm_mon + 1; + cfs.day = idata->getDateTime().tm_mday; + cfs.hour = idata->getDateTime().tm_hour; + cfs.min = idata->getDateTime().tm_min; + cfs.sec = idata->getDateTime().tm_sec; + cfs.timeValid = true; + } + if (idata->hasExif()) { cfs.shutter = idata->getShutterSpeed (); cfs.fnumber = idata->getFNumber (); @@ -814,18 +837,11 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptrgetPixelShift (); cfs.frameCount = idata->getFrameCount (); cfs.sampleFormat = idata->getSampleFormat (); - cfs.year = 1900 + idata->getDateTime().tm_year; - cfs.month = idata->getDateTime().tm_mon + 1; - cfs.day = idata->getDateTime().tm_mday; - cfs.hour = idata->getDateTime().tm_hour; - cfs.min = idata->getDateTime().tm_min; - cfs.sec = idata->getDateTime().tm_sec; - cfs.timeValid = true; - cfs.exifValid = true; cfs.lens = idata->getLens(); cfs.camMake = idata->getMake(); cfs.camModel = idata->getModel(); cfs.rating = idata->getRating(); + cfs.exifValid = true; if (idata->getOrientation() == "Rotate 90 CW") { deg = 90; diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index cda69f030..491151028 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -22,6 +22,7 @@ #include #include +#include #include "cacheimagedata.h" #include "threadutils.h" @@ -73,6 +74,7 @@ class Thumbnail // exif & date/time strings Glib::ustring exifString; Glib::ustring dateTimeString; + Glib::DateTime dateTime; bool initial_; @@ -124,6 +126,7 @@ public: const Glib::ustring& getExifString () const; const Glib::ustring& getDateTimeString () const; + const Glib::DateTime& getDateTime () const; void getCamWB (double& temp, double& green) const; void getAutoWB (double& temp, double& green, double equal, double tempBias); void getSpotWB (int x, int y, int rect, double& temp, double& green); From 8d29d361a84b21d6c248e581f81d2ce4c1cf54e2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 2 Jan 2023 21:30:06 +0100 Subject: [PATCH 158/326] Support dnggainmap (embedded correction) for Bayer files (#6382) * dng gainmap support, #6379 * dng GainMap: control sensitivity of checkbox, #6379 * dng GainMap: partial paste * dng GainMap: moved isGainMapSupported() from dcraw.h to dcraw.cc * RawImageSource::applyDngGainMap: small speedup * Change GUI to separate gainmap from other flat-field; also reorder checkbox Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> --- rtdata/languages/default | 3 + rtengine/array2D.h | 8 +++ rtengine/dcraw.cc | 109 +++++++++++++++++++++++++++++++++- rtengine/dcraw.h | 20 ++++++- rtengine/dnggainmap.h | 43 ++++++++++++++ rtengine/imagesource.h | 1 + rtengine/improccoordinator.cc | 2 +- rtengine/procparams.cc | 4 ++ rtengine/procparams.h | 1 + rtengine/rawimage.h | 5 -- rtengine/rawimagesource.cc | 35 ++++++++++- rtengine/rawimagesource.h | 4 ++ rtengine/rtengine.h | 2 +- rtengine/stdimagesource.h | 5 ++ rtgui/flatfield.cc | 36 ++++++++++- rtgui/flatfield.h | 8 ++- rtgui/paramsedited.cc | 8 ++- rtgui/paramsedited.h | 1 + rtgui/partialpastedlg.cc | 9 +++ rtgui/partialpastedlg.h | 3 +- rtgui/toolpanelcoord.cc | 11 ++-- rtgui/toolpanelcoord.h | 2 +- 22 files changed, 299 insertions(+), 21 deletions(-) create mode 100644 rtengine/dnggainmap.h diff --git a/rtdata/languages/default b/rtdata/languages/default index a33b2a9cd..82216f18f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1406,6 +1406,7 @@ HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength 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 @@ -1736,6 +1737,7 @@ PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_FILMNEGATIVE;Film negative PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection +PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control @@ -2481,6 +2483,7 @@ TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal TP_FLATFIELD_BT_VERTICAL;Vertical TP_FLATFIELD_CLIPCONTROL;Clip control TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. +TP_FLATFIELD_FROMMETADATA;From Metadata TP_FLATFIELD_LABEL;Flat-Field TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. TP_GRADIENT_CENTER;Center diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 10d797999..eee6c3210 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -248,6 +248,14 @@ public: return *this; } + // import from flat data + void operator()(std::size_t w, std::size_t h, const T* const copy) + { + ar_realloc(w, h); + for (std::size_t y = 0; y < h; ++y) { + std::copy(copy + y * w, copy + y * w + w, rows.data()[y]); + } + } int getWidth() const { diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index bdd92c7da..8eca727b4 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6938,7 +6938,6 @@ it under the terms of the one of two licenses as you choose: 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(); @@ -6957,8 +6956,48 @@ it under the terms of the one of two licenses as you choose: break; } case 51009: /* OpcodeList2 */ - meta_offset = ftell(ifp); - break; + { + 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; + } case 64772: /* Kodak P-series */ if (len < 13) break; fseek (ifp, 16, SEEK_CUR); @@ -11079,6 +11118,70 @@ 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 f78bd8aa6..e0a6cda92 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -19,9 +19,12 @@ #pragma once +#include + #include "myfile.h" #include - +#include "dnggainmap.h" +#include "settings.h" class DCraw { @@ -165,6 +168,8 @@ protected: PanasonicRW2Info(): bpp(0), encoding(0) {} }; PanasonicRW2Info RT_pana_info; + std::vector gainMaps; + public: struct CanonCR3Data { // contents of tag CMP1 for relevant track in CR3 file @@ -193,6 +198,18 @@ public: int crx_track_selected; short CR3_CTMDtag; }; + + bool isBayer() const + { + return (filters != 0 && filters != 9); + } + + const std::vector& getGainMaps() const { + return gainMaps; + } + + bool isGainMapSupported() const; + struct CanonLevelsData { unsigned cblack[4]; unsigned white; @@ -200,6 +217,7 @@ public: bool white_ok; CanonLevelsData(): cblack{0}, white{0}, black_ok(false), white_ok(false) {} }; + protected: CanonCR3Data RT_canon_CR3_data; diff --git a/rtengine/dnggainmap.h b/rtengine/dnggainmap.h new file mode 100644 index 000000000..25a01fd0f --- /dev/null +++ b/rtengine/dnggainmap.h @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Ingo Weyrich + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +struct GainMap +{ + std::uint32_t Top; + std::uint32_t Left; + std::uint32_t Bottom; + std::uint32_t Right; + std::uint32_t Plane; + std::uint32_t Planes; + std::uint32_t RowPitch; + std::uint32_t ColPitch; + std::uint32_t MapPointsV; + std::uint32_t MapPointsH; + double MapSpacingV; + double MapSpacingH; + double MapOriginV; + double MapOriginH; + std::uint32_t MapPlanes; + std::vector MapGain; +}; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 6cb279efc..a8ea8f851 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -137,6 +137,7 @@ public: virtual ImageMatrices* getImageMatrices () = 0; virtual bool isRAW () const = 0; + virtual bool isGainMapSupported () const = 0; virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) { return nullptr; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8d377d30c..df354bfd8 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -407,7 +407,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST if (imageTypeListener) { - imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono()); + imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported()); } if ((todo & M_RAW) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 04ece8bc3..c9c420b44 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -5633,6 +5633,7 @@ bool RAWParams::PreprocessWB::operator !=(const PreprocessWB& other) const RAWParams::RAWParams() : df_autoselect(false), ff_AutoSelect(false), + ff_FromMetaData(false), ff_BlurRadius(32), ff_BlurType(getFlatFieldBlurTypeString(FlatFieldBlurType::AREA)), ff_AutoClipControl(false), @@ -5658,6 +5659,7 @@ bool RAWParams::operator ==(const RAWParams& other) const && df_autoselect == other.df_autoselect && ff_file == other.ff_file && ff_AutoSelect == other.ff_AutoSelect + && ff_FromMetaData == other.ff_FromMetaData && ff_BlurRadius == other.ff_BlurRadius && ff_BlurType == other.ff_BlurType && ff_AutoClipControl == other.ff_AutoClipControl @@ -7484,6 +7486,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.df_autoselect, "RAW", "DarkFrameAuto", raw.df_autoselect, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file), keyFile); saveToKeyfile(!pedited || pedited->raw.ff_AutoSelect, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, keyFile); + saveToKeyfile(!pedited || pedited->raw.ff_FromMetaData, "RAW", "FlatFieldFromMetaData", raw.ff_FromMetaData, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurRadius, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurType, "RAW", "FlatFieldBlurType", raw.ff_BlurType, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_AutoClipControl, "RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl, keyFile); @@ -10130,6 +10133,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d730316e2..309bcb2ab 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -2440,6 +2440,7 @@ struct RAWParams { Glib::ustring ff_file; bool ff_AutoSelect; + bool ff_FromMetaData; int ff_BlurRadius; Glib::ustring ff_BlurType; bool ff_AutoClipControl; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 871267dac..2b1cd2156 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -245,11 +245,6 @@ public: return zero_is_bad == 1; } - bool isBayer() const - { - return (filters != 0 && filters != 9); - } - bool isXtrans() const { return filters == 9; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 48d7b0904..550c59e9c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -39,6 +39,7 @@ #include "rawimage.h" #include "rawimagesource_i.h" #include "rawimagesource.h" +#include "rescale.h" #include "rt_math.h" #include "rtengine.h" #include "rtlensfun.h" @@ -1347,7 +1348,6 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le rif = ffm.searchFlatField(idata->getMake(), idata->getModel(), idata->getLens(), idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS()); } - bool hasFlatField = (rif != nullptr); if (hasFlatField && settings->verbose) { @@ -1387,6 +1387,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } //FLATFIELD end + if (raw.ff_FromMetaData && isGainMapSupported()) { + applyDngGainMap(c_black, ri->getGainMaps()); + } // Always correct camera badpixels from .badpixels file const std::vector *bp = DFManager::getInstance().getBadPixels(ri->get_maker(), ri->get_model(), idata->getSerialNumber()); @@ -6259,6 +6262,36 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int } } +bool RawImageSource::isGainMapSupported() const { + return ri->isGainMapSupported(); +} + +void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) { + // now we can apply each gain map to raw_data + array2D mvals[2][2]; + for (auto &m : gainMaps) { + mvals[m.Top & 1][m.Left & 1](m.MapPointsH, m.MapPointsV, m.MapGain.data()); + } + + // now we assume, col_scale and row scale is the same for all maps + const float col_scale = float(gainMaps[0].MapPointsH-1) / float(W); + const float row_scale = float(gainMaps[0].MapPointsV-1) / float(H); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (std::size_t y = 0; y < static_cast(H); ++y) { + const float rowBlack[2] = {black[FC(y,0)], black[FC(y,1)]}; + const float ys = y * row_scale; + float xs = 0.f; + for (std::size_t x = 0; x < static_cast(W); ++x, xs += col_scale) { + const float f = getBilinearValue(mvals[y & 1][x & 1], xs, ys); + const float b = rowBlack[x & 1]; + rawData[y][x] = rtengine::max((rawData[y][x] - b) * f + b, 0.f); + } + } +} + void RawImageSource::cleanup () { delete phaseOneIccCurve; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 41a400dd9..d7549fe71 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -24,6 +24,7 @@ #include "array2D.h" #include "colortemp.h" +#include "dnggainmap.h" #include "iimage.h" #include "imagesource.h" #include "procparams.h" @@ -177,6 +178,8 @@ public: return true; } + bool isGainMapSupported() const override; + void setProgressListener (ProgressListener* pl) override { plistener = pl; @@ -304,6 +307,7 @@ protected: void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override; + void applyDngGainMap(const float black[4], const std::vector &gainMaps); }; } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index b9fc916f6..989ca3354 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -493,7 +493,7 @@ class ImageTypeListener { public: virtual ~ImageTypeListener() = default; - virtual void imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0; + virtual void imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false, bool isGainMapSupported = false) = 0; }; class AutoContrastListener diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 9b95fe34e..f83c58a04 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -100,6 +100,11 @@ public: return false; } + bool isGainMapSupported() const override + { + return false; + } + void setProgressListener (ProgressListener* pl) override { plistener = pl; diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 71fa0aab6..f493ba0b9 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -18,6 +18,7 @@ */ #include +#include "eventmapper.h" #include "flatfield.h" #include "guiutils.h" @@ -32,6 +33,9 @@ using namespace rtengine::procparams; FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL")) { + auto m = ProcEventMapper::getInstance(); + EvFlatFieldFromMetaData = m->newEvent(DARKFRAME, "HISTORY_MSG_FF_FROMMETADATA"); + hbff = Gtk::manage(new Gtk::Box()); flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); bindCurrentFolder (*flatFieldFile, options.lastFlatfieldDir); @@ -42,6 +46,8 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L hbff->pack_start(*flatFieldFile); hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK); flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_FLATFIELD_AUTOSELECT")))); + flatFieldFromMetaData = Gtk::manage(new CheckBox((M("TP_FLATFIELD_FROMMETADATA")), multiImage)); + flatFieldFromMetaData->setCheckBoxListener (this); ffInfo = Gtk::manage(new Gtk::Label("-")); setExpandAlignProperties(ffInfo, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); flatFieldBlurRadius = Gtk::manage(new Adjuster (M("TP_FLATFIELD_BLURRADIUS"), 0, 200, 2, 32)); @@ -70,8 +76,10 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L flatFieldClipControl->show(); flatFieldClipControl->set_tooltip_markup (M("TP_FLATFIELD_CLIPCONTROL_TOOLTIP")); - pack_start( *hbff, Gtk::PACK_SHRINK); + pack_start( *flatFieldFromMetaData, Gtk::PACK_SHRINK); + pack_start( *Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)), Gtk::PACK_SHRINK, 0 ); pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK); + pack_start( *hbff, Gtk::PACK_SHRINK); pack_start( *ffInfo, Gtk::PACK_SHRINK); pack_start( *hbffbt, Gtk::PACK_SHRINK); pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK); @@ -128,12 +136,14 @@ void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi } flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect); + flatFieldFromMetaData->set_active (pp->raw.ff_FromMetaData); flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); flatFieldClipControl->setValue (pp->raw.ff_clipControl); flatFieldClipControl->setAutoValue (pp->raw.ff_AutoClipControl); if(pedited ) { flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect); + flatFieldFromMetaData->set_inconsistent (!pedited->raw.ff_FromMetaData); flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited ); flatFieldClipControl->setEditedState( pedited->raw.ff_clipControl ? Edited : UnEdited ); flatFieldClipControl->setAutoInconsistent(multiImage && !pedited->raw.ff_AutoClipControl); @@ -214,6 +224,7 @@ void FlatField::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedit { pp->raw.ff_file = flatFieldFile->get_filename(); pp->raw.ff_AutoSelect = flatFieldAutoSelect->get_active(); + pp->raw.ff_FromMetaData = flatFieldFromMetaData->get_active(); pp->raw.ff_BlurRadius = flatFieldBlurRadius->getIntValue(); pp->raw.ff_clipControl = flatFieldClipControl->getIntValue(); pp->raw.ff_AutoClipControl = flatFieldClipControl->getAutoValue(); @@ -227,6 +238,7 @@ void FlatField::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedit if (pedited) { pedited->raw.ff_file = ffChanged; pedited->raw.ff_AutoSelect = !flatFieldAutoSelect->get_inconsistent(); + pedited->raw.ff_FromMetaData = !flatFieldFromMetaData->get_inconsistent(); pedited->raw.ff_BlurRadius = flatFieldBlurRadius->getEditedState (); pedited->raw.ff_clipControl = flatFieldClipControl->getEditedState (); pedited->raw.ff_AutoClipControl = !flatFieldClipControl->getAutoInconsistent(); @@ -352,6 +364,13 @@ void FlatField::flatFieldBlurTypeChanged () } } +void FlatField::checkBoxToggled (CheckBox* c, CheckValue newval) +{ + if (listener && c == flatFieldFromMetaData) { + listener->panelChanged (EvFlatFieldFromMetaData, flatFieldFromMetaData->getLastActive() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} + void FlatField::flatFieldAutoSelectChanged() { if (batchMode) { @@ -419,3 +438,18 @@ void FlatField::flatFieldAutoClipValueChanged(int n) } ); } + +void FlatField::setGainMap(bool enabled) { + flatFieldFromMetaData->set_sensitive(enabled); + if (!enabled) { + idle_register.add( + [this, enabled]() -> bool + { + disableListener(); + flatFieldFromMetaData->setValue(false); + enableListener(); + return false; + } + ); + } +} diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index 0d6f167e1..be46d5a1d 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -23,6 +23,7 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "guiutils.h" #include "toolpanel.h" @@ -42,7 +43,7 @@ public: // add other info here }; -class FlatField final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener +class FlatField final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener { protected: @@ -52,6 +53,7 @@ protected: Gtk::Label *ffInfo; Gtk::Button *flatFieldFileReset; Gtk::CheckButton* flatFieldAutoSelect; + CheckBox* flatFieldFromMetaData; Adjuster* flatFieldClipControl; Adjuster* flatFieldBlurRadius; MyComboBoxText* flatFieldBlurType; @@ -64,8 +66,10 @@ protected: Glib::ustring lastShortcutPath; bool b_filter_asCurrent; bool israw; + rtengine::ProcEvent EvFlatFieldFromMetaData; IdleRegister idle_register; + public: FlatField (); @@ -90,4 +94,6 @@ public: ffp = p; }; void flatFieldAutoClipValueChanged(int n = 0) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; + void setGainMap(bool enabled); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index a7963b7dc..9c7a92f39 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -519,6 +519,7 @@ void ParamsEdited::set(bool v) raw.df_autoselect = v; raw.ff_file = v; raw.ff_AutoSelect = v; + raw.ff_FromMetaData = v; raw.ff_BlurRadius = v; raw.ff_BlurType = v; raw.ff_AutoClipControl = v; @@ -1930,6 +1931,7 @@ void ParamsEdited::initFrom(const std::vector& raw.df_autoselect = raw.df_autoselect && p.raw.df_autoselect == other.raw.df_autoselect; raw.ff_file = raw.ff_file && p.raw.ff_file == other.raw.ff_file; raw.ff_AutoSelect = raw.ff_AutoSelect && p.raw.ff_AutoSelect == other.raw.ff_AutoSelect; + raw.ff_FromMetaData = raw.ff_FromMetaData && p.raw.ff_FromMetaData == other.raw.ff_FromMetaData; raw.ff_BlurRadius = raw.ff_BlurRadius && p.raw.ff_BlurRadius == other.raw.ff_BlurRadius; raw.ff_BlurType = raw.ff_BlurType && p.raw.ff_BlurType == other.raw.ff_BlurType; raw.ff_AutoClipControl = raw.ff_AutoClipControl && p.raw.ff_AutoClipControl == other.raw.ff_AutoClipControl; @@ -6644,6 +6646,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; } + if (raw.ff_FromMetaData) { + toEdit.raw.ff_FromMetaData = mods.raw.ff_FromMetaData; + } + if (raw.ff_BlurRadius) { toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; } @@ -7375,7 +7381,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const bool RAWParamsEdited::isUnchanged() const { return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && ca_autocorrect && ca_avoidcolourshift && caautoiterations && cared && cablue && hotPixelFilter && deadPixelFilter && hotdeadpix_thresh && darkFrame - && df_autoselect && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && ff_AutoClipControl && ff_clipControl; + && df_autoselect && ff_file && ff_AutoSelect && ff_FromMetaData && ff_BlurRadius && ff_BlurType && exPos && ff_AutoClipControl && ff_clipControl; } bool LensProfParamsEdited::isUnchanged() const diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0c0c79f7c..3c108f33d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1489,6 +1489,7 @@ struct RAWParamsEdited { bool df_autoselect; bool ff_file; bool ff_AutoSelect; + bool ff_FromMetaData; bool ff_BlurRadius; bool ff_BlurType; bool ff_AutoClipControl; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index a9f79d854..81847adc0 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -301,6 +301,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren //--- ff_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFILE"))); ff_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDAUTOSELECT"))); + ff_FromMetaData = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFROMMETADATA"))); ff_BlurType = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURTYPE"))); ff_BlurRadius = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURRADIUS"))); ff_ClipControl = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDCLIPCONTROL"))); @@ -423,6 +424,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[8]->pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)), Gtk::PACK_SHRINK, 0); vboxes[8]->pack_start (*ff_file, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_AutoSelect, Gtk::PACK_SHRINK, 2); + vboxes[8]->pack_start (*ff_FromMetaData, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_BlurType, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_BlurRadius, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_ClipControl, Gtk::PACK_SHRINK, 2); @@ -574,6 +576,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren //--- ff_fileConn = ff_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_AutoSelectConn = ff_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_FromMetaDataConn = ff_FromMetaData->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_BlurTypeConn = ff_BlurType->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_BlurRadiusConn = ff_BlurRadius->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_ClipControlConn = ff_ClipControl->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); @@ -655,6 +658,7 @@ void PartialPasteDlg::rawToggled () ConnectionBlocker df_AutoSelectBlocker(df_AutoSelectConn); ConnectionBlocker ff_fileBlocker(ff_fileConn); ConnectionBlocker ff_AutoSelectBlocker(ff_AutoSelectConn); + ConnectionBlocker ff_FromMetaDataBlocker(ff_FromMetaDataConn); ConnectionBlocker ff_BlurTypeBlocker(ff_BlurTypeConn); ConnectionBlocker ff_BlurRadiusBlocker(ff_BlurRadiusConn); ConnectionBlocker ff_ClipControlBlocker(ff_ClipControlConn); @@ -685,6 +689,7 @@ void PartialPasteDlg::rawToggled () df_AutoSelect->set_active (raw->get_active ()); ff_file->set_active (raw->get_active ()); ff_AutoSelect->set_active (raw->get_active ()); + ff_FromMetaData->set_active (raw->get_active ()); ff_BlurType->set_active (raw->get_active ()); ff_BlurRadius->set_active (raw->get_active ()); ff_ClipControl->set_active (raw->get_active ()); @@ -1173,6 +1178,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.ff_AutoSelect = falsePE.raw.ff_AutoSelect; } + if (!ff_FromMetaData->get_active ()) { + filterPE.raw.ff_FromMetaData = falsePE.raw.ff_FromMetaData; + } + if (!ff_BlurRadius->get_active ()) { filterPE.raw.ff_BlurRadius = falsePE.raw.ff_BlurRadius; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 19e1eb462..dcf44bb72 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -214,6 +214,7 @@ public: Gtk::CheckButton* df_AutoSelect; Gtk::CheckButton* ff_file; Gtk::CheckButton* ff_AutoSelect; + Gtk::CheckButton* ff_FromMetaData; Gtk::CheckButton* ff_BlurRadius; Gtk::CheckButton* ff_BlurType; Gtk::CheckButton* ff_ClipControl; @@ -230,7 +231,7 @@ public: sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn; sigc::connection metadataConn, exifchConn, iptcConn, icmConn; - sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; + sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_FromMetaDataConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; sigc::connection filmNegativeConn; sigc::connection captureSharpeningConn; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 9c14aeb6e..fe8b4f1bf 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -343,12 +343,12 @@ ToolPanelCoordinator::~ToolPanelCoordinator () delete toolBar; } -void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool isMono) +void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool isMono, bool isGainMapSupported) { if (isRaw) { if (isBayer) { idle_register.add( - [this]() -> bool + [this, isGainMapSupported]() -> bool { rawPanelSW->set_sensitive(true); sensorxtrans->FoldableToolPanel::hide(); @@ -362,6 +362,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr preprocessWB->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + flatfield->setGainMap(isGainMapSupported); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -369,7 +370,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr ); } else if (isXtrans) { idle_register.add( - [this]() -> bool + [this, isGainMapSupported]() -> bool { rawPanelSW->set_sensitive(true); sensorxtrans->FoldableToolPanel::show(); @@ -383,6 +384,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr preprocessWB->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + flatfield->setGainMap(isGainMapSupported); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -390,7 +392,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr ); } else if (isMono) { idle_register.add( - [this]() -> bool + [this, isGainMapSupported]() -> bool { rawPanelSW->set_sensitive(true); sensorbayer->FoldableToolPanel::hide(); @@ -403,6 +405,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr preprocessWB->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); + flatfield->setGainMap(isGainMapSupported); pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 65e2f1e8f..cd4131ff4 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -260,7 +260,7 @@ public: void unsetTweakOperator (rtengine::TweakOperator *tOperator) override; // FilmNegProvider interface - void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false) override; + void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false, bool isGainMapSupported = false) override; // profilechangelistener interface void profileChange( From 57c1822b2c60c42b9b38caab6ade1c7f50201b16 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:32:15 -0800 Subject: [PATCH 159/326] Strict temporary image file permissions (#6358) * Write temp images to private tmp directory (Linux) The directory is in /tmp with 700 permissions. * Reduce temp image file permissions in Linux Set temporary image file permissions to read/write for the user only. * Use private tmp directory for temp images in MacOS * Use private tmp directory for temp images Windows * Use GLib to create temporary directories * Reuse temp directory if possible --- rtengine/winutils.h | 124 +++++++++++++++++++++++ rtgui/editorpanel.cc | 235 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 rtengine/winutils.h diff --git a/rtengine/winutils.h b/rtengine/winutils.h new file mode 100644 index 000000000..757849dd1 --- /dev/null +++ b/rtengine/winutils.h @@ -0,0 +1,124 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2021 Lawrence Lee + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + +#ifdef WIN32 + +#include +#include + +#include "noncopyable.h" + + +/** + * Wrapper for pointers to memory allocated by HeapAlloc. + * + * Memory is automatically freed when the object goes out of scope. + */ +template +class WinHeapPtr : public rtengine::NonCopyable +{ +private: + const T ptr; + +public: + WinHeapPtr() = delete; + + /** Allocates the specified number of bytes in the process heap. */ + explicit WinHeapPtr(SIZE_T bytes): ptr(static_cast(HeapAlloc(GetProcessHeap(), 0, bytes))) {}; + + ~WinHeapPtr() + { + // HeapFree does a null check. + HeapFree(GetProcessHeap(), 0, static_cast(ptr)); + } + + T operator ->() const + { + return ptr; + } + + operator T() const + { + return ptr; + } +}; + +/** + * Wrapper for HLOCAL pointers to memory allocated by LocalAlloc. + * + * Memory is automatically freed when the object goes out of scope. + */ +template +class WinLocalPtr : public rtengine::NonCopyable +{ +private: + const T ptr; + +public: + WinLocalPtr() = delete; + + /** Wraps a raw pointer. */ + WinLocalPtr(T pointer): ptr(pointer) {}; + + ~WinLocalPtr() + { + // LocalFree does a null check. + LocalFree(static_cast(ptr)); + } + + T operator ->() const + { + return ptr; + } + + operator T() const + { + return ptr; + } +}; + +/** + * Wrapper for HANDLEs. + * + * Handles are automatically closed when the object goes out of scope. + */ +class WinHandle : public rtengine::NonCopyable +{ +private: + const HANDLE handle; + +public: + WinHandle() = delete; + + /** Wraps a HANDLE. */ + WinHandle(HANDLE handle): handle(handle) {}; + + ~WinHandle() + { + CloseHandle(handle); + } + + operator HANDLE() const + { + return handle; + } +}; + +#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 78a07ddd6..190897c89 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -44,6 +44,8 @@ #ifdef WIN32 #include "windows.h" + +#include "../rtengine/winutils.h" #endif using namespace rtengine::procparams; @@ -134,6 +136,235 @@ bool find_default_monitor_profile (GdkWindow *rootwin, Glib::ustring &defprof, G } #endif +bool hasUserOnlyPermission(const Glib::ustring &dirname) +{ +#if defined(__linux__) || defined(__APPLE__) + const Glib::RefPtr file = Gio::File::create_for_path(dirname); + const Glib::RefPtr file_info = file->query_info("owner::user,unix::mode"); + + if (!file_info) { + return false; + } + + const Glib::ustring owner = file_info->get_attribute_string("owner::user"); + const guint32 mode = file_info->get_attribute_uint32("unix::mode"); + + return (mode & 0777) == 0700 && owner == Glib::get_user_name(); +#elif defined(WIN32) + const Glib::RefPtr file = Gio::File::create_for_path(dirname); + const Glib::RefPtr file_info = file->query_info("owner::user"); + if (!file_info) { + return false; + } + + // Current user must be the owner. + const Glib::ustring user_name = Glib::get_user_name(); + const Glib::ustring owner = file_info->get_attribute_string("owner::user"); + if (user_name != owner) { + return false; + } + + // Get security descriptor and discretionary access control list. + PACL dacl = nullptr; + PSECURITY_DESCRIPTOR sec_desc_raw_ptr = nullptr; + auto win_error = GetNamedSecurityInfo( + dirname.c_str(), + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + nullptr, + nullptr, + &dacl, + nullptr, + &sec_desc_raw_ptr + ); + const WinLocalPtr sec_desc_ptr(sec_desc_raw_ptr); + if (win_error != ERROR_SUCCESS) { + return false; + } + + // Must not inherit permissions. + SECURITY_DESCRIPTOR_CONTROL sec_desc_control; + DWORD revision; + if (!( + GetSecurityDescriptorControl(sec_desc_ptr, &sec_desc_control, &revision) + && sec_desc_control & SE_DACL_PROTECTED + )) { + return false; + } + + // Check that there is one entry allowing full access. + ULONG acl_entry_count; + PEXPLICIT_ACCESS acl_entry_list_raw = nullptr; + win_error = GetExplicitEntriesFromAcl(dacl, &acl_entry_count, &acl_entry_list_raw); + const WinLocalPtr acl_entry_list(acl_entry_list_raw); + if (win_error != ERROR_SUCCESS || acl_entry_count != 1) { + return false; + } + const EXPLICIT_ACCESS &ace = acl_entry_list[0]; + if ( + ace.grfAccessMode != GRANT_ACCESS + || (ace.grfAccessPermissions & FILE_ALL_ACCESS) != FILE_ALL_ACCESS + || ace.Trustee.TrusteeForm != TRUSTEE_IS_SID // Should already be SID, but double check. + ) { + return false; + } + + // ACE must be for the current user. + HANDLE process_token_raw; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &process_token_raw)) { + return false; + } + const WinHandle process_token(process_token_raw); + DWORD actual_token_info_size = 0; + GetTokenInformation(process_token, TokenUser, nullptr, 0, &actual_token_info_size); + if (!actual_token_info_size) { + return false; + } + const WinHeapPtr user_token_ptr(actual_token_info_size); + if (!user_token_ptr || !GetTokenInformation( + process_token, + TokenUser, + user_token_ptr, + actual_token_info_size, + &actual_token_info_size + )) { + return false; + } + return EqualSid(ace.Trustee.ptstrName, user_token_ptr->User.Sid); +#endif + return false; +} + +/** + * Sets read and write permissions, and optionally the execute permission, for + * the user and no permissions for others. + */ +void setUserOnlyPermission(const Glib::RefPtr file, bool execute) +{ +#if defined(__linux__) || defined(__APPLE__) + const Glib::RefPtr file_info = file->query_info("unix::mode"); + if (!file_info) { + return; + } + + guint32 mode = file_info->get_attribute_uint32("unix::mode"); + mode = (mode & ~0777) | (execute ? 0700 : 0600); + try { + file->set_attribute_uint32("unix::mode", mode, Gio::FILE_QUERY_INFO_NONE); + } catch (Gio::Error &) { + } +#elif defined(WIN32) + // Get the current user's SID. + HANDLE process_token_raw; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &process_token_raw)) { + return; + } + const WinHandle process_token(process_token_raw); + DWORD actual_token_info_size = 0; + GetTokenInformation(process_token, TokenUser, nullptr, 0, &actual_token_info_size); + if (!actual_token_info_size) { + return; + } + const WinHeapPtr user_token_ptr(actual_token_info_size); + if (!user_token_ptr || !GetTokenInformation( + process_token, + TokenUser, + user_token_ptr, + actual_token_info_size, + &actual_token_info_size + )) { + return; + } + const PSID user_sid = user_token_ptr->User.Sid; + + // Get a handle to the file. + const Glib::ustring filename = file->get_path(); + const HANDLE file_handle_raw = CreateFile( + filename.c_str(), + READ_CONTROL | WRITE_DAC, + 0, + nullptr, + OPEN_EXISTING, + execute ? FILE_FLAG_BACKUP_SEMANTICS : FILE_ATTRIBUTE_NORMAL, + nullptr + ); + if (file_handle_raw == INVALID_HANDLE_VALUE) { + return; + } + const WinHandle file_handle(file_handle_raw); + + // Create the user-only permission and set it. + EXPLICIT_ACCESS ea = { + .grfAccessPermissions = FILE_ALL_ACCESS, + .grfAccessMode = GRANT_ACCESS, + .grfInheritance = NO_INHERITANCE, + }; + BuildTrusteeWithSid(&(ea.Trustee), user_sid); + PACL new_dacl_raw = nullptr; + auto win_error = SetEntriesInAcl(1, &ea, nullptr, &new_dacl_raw); + if (win_error != ERROR_SUCCESS) { + return; + } + const WinLocalPtr new_dacl(new_dacl_raw); + SetSecurityInfo( + file_handle, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, + nullptr, + nullptr, + new_dacl, + nullptr + ); +#endif +} + +/** + * Gets the path to the temp directory, creating it if necessary. + */ +Glib::ustring getTmpDirectory() +{ +#if defined(__linux__) || defined(__APPLE__) || defined(WIN32) + static Glib::ustring recent_dir = ""; + const Glib::ustring tmp_dir_root = Glib::get_tmp_dir(); + const Glib::ustring subdir_base = + Glib::ustring::compose("rawtherapee-%1", Glib::get_user_name()); + Glib::ustring dir = Glib::build_filename(tmp_dir_root, subdir_base); + + // Returns true if the directory doesn't exist or has the right permissions. + auto is_usable_dir = [](const Glib::ustring &dir_path) { + return !Glib::file_test(dir_path, Glib::FILE_TEST_EXISTS) || (Glib::file_test(dir_path, Glib::FILE_TEST_IS_DIR) && hasUserOnlyPermission(dir_path)); + }; + + if (!(is_usable_dir(dir) || recent_dir.empty())) { + // Try to reuse the random suffix directory. + dir = recent_dir; + } + + if (!is_usable_dir(dir)) { + // Create new directory with random suffix. + gchar *const rand_dir = g_dir_make_tmp((subdir_base + "-XXXXXX").c_str(), nullptr); + if (!rand_dir) { + return tmp_dir_root; + } + dir = recent_dir = rand_dir; + g_free(rand_dir); + Glib::RefPtr file = Gio::File::create_for_path(dir); + setUserOnlyPermission(file, true); + } else if (!Glib::file_test(dir, Glib::FILE_TEST_EXISTS)) { + // Create the directory. + Glib::RefPtr file = Gio::File::create_for_path(dir); + bool dir_created = file->make_directory(); + if (!dir_created) { + return tmp_dir_root; + } + setUserOnlyPermission(file, true); + } + + return dir; +#else + return Glib::get_tmp_dir(); +#endif +} } class EditorPanel::ColorManagementToolbar @@ -2058,7 +2289,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p dirname = options.editor_custom_out_dir; break; default: // Options::EDITOR_OUT_DIR_TEMP - dirname = Glib::get_tmp_dir(); + dirname = getTmpDirectory(); break; } Glib::ustring fullFileName = Glib::build_filename(dirname, shortname); @@ -2119,6 +2350,8 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef parent->setProgress (0.); bool success = false; + setUserOnlyPermission(Gio::File::create_for_path(filename), false); + if (options.editorToSendTo == 1) { success = ExtProgStore::openInGimp (filename); } else if (options.editorToSendTo == 2) { From 95cede9a1a20a53b3ae5842fed736898791dda60 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 3 Jan 2023 07:44:46 +0100 Subject: [PATCH 160/326] Color Appearance and lighting : Remove cat02preset and all dependencies issue 5664 (#6585) * Remove cat02preset and all dependencies issue 5664 * Normalize cmakelist --- rtengine/improccoordinator.cc | 10 +- rtengine/procparams.cc | 8 +- rtengine/procparams.h | 1 - rtgui/colorappearance.cc | 168 ---------------------------------- rtgui/colorappearance.h | 5 - rtgui/paramsedited.cc | 5 - rtgui/paramsedited.h | 1 - 7 files changed, 7 insertions(+), 191 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index df354bfd8..2a2f1079b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1936,20 +1936,20 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, scale, execsharp, d, dj, yb, 1); - if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { + if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) { acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); } - if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { + if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled) { acListener->adapCamChanged(adap); //real value of adapt scene } - if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { + if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) { acListener->ybCamChanged((int) yb); //real value Yb scene } - // if (params->colorappearance.enabled && params->colorappearance.presetcat02 && params->colorappearance.autotempout) { - // if (params->colorappearance.enabled && params->colorappearance.presetcat02) { + // if (params->colorappearance.enabled && params->colorappearance.autotempout) { + // if (params->colorappearance.enabled) { // acListener->wbCamChanged(params->wb.temperature, params->wb.green); //real temp and tint // acListener->wbCamChanged(params->wb.temperature, 1.f); //real temp and tint = 1. // } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index c9c420b44..3f30374f7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1461,8 +1461,7 @@ ColorAppearanceParams::ColorAppearanceParams() : ybout(18), greenout(1.0), tempsc(5003), - greensc(1.0), - presetcat02(false) + greensc(1.0) { } @@ -1512,8 +1511,7 @@ bool ColorAppearanceParams::operator ==(const ColorAppearanceParams& other) cons && ybout == other.ybout && greenout == other.greenout && tempsc == other.tempsc - && greensc == other.greensc - && presetcat02 == other.presetcat02; + && greensc == other.greensc; } bool ColorAppearanceParams::operator !=(const ColorAppearanceParams& other) const @@ -6146,7 +6144,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->colorappearance.ybout, "Color appearance", "Ybout", colorappearance.ybout, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.datacie, "Color appearance", "Datacie", colorappearance.datacie, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.tonecie, "Color appearance", "Tonecie", colorappearance.tonecie, keyFile); - saveToKeyfile(!pedited || pedited->colorappearance.presetcat02, "Color appearance", "Presetcat02", colorappearance.presetcat02, keyFile); const std::map ca_mapping = { {ColorAppearanceParams::TcMode::LIGHT, "Lightness"}, @@ -8107,7 +8104,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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", "Presetcat02", pedited, colorappearance.presetcat02, pedited->colorappearance.presetcat02); const std::map tc_mapping = { {"Lightness", ColorAppearanceParams::TcMode::LIGHT}, diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 309bcb2ab..df319ffcc 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -709,7 +709,6 @@ struct ColorAppearanceParams { double greenout; int tempsc; double greensc; - bool presetcat02; ColorAppearanceParams(); diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index a0d341cf2..5cae8cce8 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -220,7 +220,6 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" milestones.push_back ( GradientMilestone (1., 1., 1., 1.) ); auto m = ProcEventMapper::getInstance(); - Evcatpreset = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_CAT02PRESET"); EvCATAutotempout = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_TEMPOUT"); EvCATillum = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ILLUM"); EvCATcomplex = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_CATCOMPLEX"); @@ -269,10 +268,6 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" 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_TOOLTIP")); - presetcat02conn = presetcat02->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::presetcat02pressed)); -// genVBox->pack_start (*presetcat02, Gtk::PACK_SHRINK); genFrame->add (*genVBox); pack_start (*genFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -874,7 +869,6 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) tcmodeconn.block (true); tcmode2conn.block (true); tcmode3conn.block (true); - presetcat02conn.block (true); shape->setCurve (pp->colorappearance.curve); shape2->setCurve (pp->colorappearance.curve2); shape3->setCurve (pp->colorappearance.curve3); @@ -882,7 +876,6 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) toneCurveMode2->set_active (toUnderlying(pp->colorappearance.curveMode2)); toneCurveMode3->set_active (toUnderlying(pp->colorappearance.curveMode3)); curveMode3Changed(); // This will set the correct sensitive state of depending Adjusters - presetcat02->set_active(pp->colorappearance.presetcat02); nexttemp = pp->wb.temperature; nextgreen = 1.; //pp->wb.green; @@ -946,7 +939,6 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) if (!pedited->colorappearance.curveMode3) { toneCurveMode3->set_active (3); } - presetcat02->set_inconsistent(!pedited->colorappearance.presetcat02); } @@ -1134,10 +1126,6 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) ybout->setValue (pp->colorappearance.ybout); tempsc->setValue (pp->colorappearance.tempsc); greensc->setValue (pp->colorappearance.greensc); - presetcat02conn.block (true); - presetcat02->set_active (pp->colorappearance.presetcat02); - presetcat02conn.block (false); - lastpresetcat02 = pp->colorappearance.presetcat02; if (complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); @@ -1202,7 +1190,6 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pp->colorappearance.ybout = ybout->getValue (); pp->colorappearance.tempsc = tempsc->getValue (); pp->colorappearance.greensc = greensc->getValue (); - pp->colorappearance.presetcat02 = presetcat02->get_active(); int tcMode = toneCurveMode->get_active_row_number(); @@ -1276,7 +1263,6 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pedited->colorappearance.ybout = ybout->getEditedState (); pedited->colorappearance.tempsc = tempsc->getEditedState (); pedited->colorappearance.greensc = greensc->getEditedState (); - pedited->colorappearance.presetcat02 = presetcat02->get_inconsistent (); // pedited->colorappearance.autotempout = !tempout->getAutoInconsistent(); } @@ -1397,10 +1383,6 @@ void ColorAppearance::convertParamToNormal() shape2->reset(); shape3->reset(); wbmodel->set_active (0); - if (presetcat02->get_active ()) { - wbmodel->set_active (2); - illumChanged(); - } if (catmethod->get_active_row_number() == 1 || catmethod->get_active_row_number() == 2) { wbmodel->set_active (2); illumChanged(); @@ -1705,140 +1687,6 @@ void ColorAppearance::badpix_toggled () { } */ -void ColorAppearance::presetcat02pressed () //keep in case of... -{ - if (presetcat02->get_active ()) { - disableListener(); - jlight->resetValue (false); - qbright->resetValue (false); - chroma->resetValue (false); - schroma->resetValue (false); - mchroma->resetValue (false); - rstprotection->resetValue (false); - contrast->resetValue (false); - qcontrast->resetValue (false); - colorh->resetValue (false); - tempout->resetValue (false); - greenout->resetValue (false); - ybout->resetValue (false); - tempsc->resetValue (false); - greensc->resetValue (false); - badpixsl->resetValue (false); - wbmodel->set_active (0); - illum->set_active (2); - toneCurveMode->set_active (0); - toneCurveMode2->set_active (1); - toneCurveMode3->set_active (0); - shape->reset(); - shape2->reset(); - shape3->reset(); - gamutconn.block (true); - gamut->set_active (true); - gamutconn.block (false); - degree->setAutoValue (true); - degree->resetValue (false); - degree->setValue(90); - adapscen->resetValue (false); - adapscen->setAutoValue (true); - degreeout->resetValue (false); - degreeout->setAutoValue (true); - ybscen->resetValue (false); - ybscen->setAutoValue (true); - surrsrc->set_active (0); - wbmodel->set_active (2); - tempsc->resetValue (false); - greensc->resetValue (false); - adapscen->setValue(400.); - ybscen->setValue(18); - surround->set_active (0); - adaplum->setValue(400.); - degreeout->setValue(90); - ybout->setValue(18); - tempout->setValue (nexttemp); - -/* if(tempout->getAutoValue()) { - tempout->resetValue (false); - } else { - tempout->setValue (nexttemp); - tempout->setAutoValue (true); - } -*/ - greenout->setValue (nextgreen); - enableListener(); - } else { - disableListener(); -/* jlight->resetValue (false); - qbright->resetValue (false); - chroma->resetValue (false); - schroma->resetValue (false); - mchroma->resetValue (false); - rstprotection->resetValue (false); - contrast->resetValue (false); - qcontrast->resetValue (false); - colorh->resetValue (false); - tempout->resetValue (false); - greenout->resetValue (false); - ybout->resetValue (false); - tempsc->resetValue (false); - greensc->resetValue (false); - badpixsl->resetValue (false); - wbmodel->set_active (0); - toneCurveMode->set_active (0); - toneCurveMode2->set_active (0); - toneCurveMode3->set_active (0); - shape->reset(); - shape2->reset(); - shape3->reset(); - gamutconn.block (true); - gamut->set_active (true); - gamutconn.block (false); -*/ - degree->setAutoValue (true); - degree->resetValue (false); - adapscen->resetValue (false); - adapscen->setAutoValue (true); - degreeout->resetValue (false); - degreeout->setAutoValue (true); - ybscen->resetValue (false); - ybscen->setAutoValue (true); - surrsrc->set_active (0); - wbmodel->set_active (0); - illum->set_active (2); - tempsc->resetValue (false); - greensc->resetValue (false); - adapscen->resetValue (false); - ybscen->resetValue (false); - surround->set_active (0); - adaplum->resetValue (false); - degreeout->resetValue (false); - ybout->resetValue (false); - tempout->resetValue (false); - greenout->resetValue (false); - enableListener(); - - } - if (batchMode) { - if (presetcat02->get_inconsistent()) { - presetcat02->set_inconsistent (false); - presetcat02conn.block (true); - presetcat02->set_active (false); - presetcat02conn.block (false); - } else if (lastpresetcat02) { - presetcat02->set_inconsistent (true); - } - - lastpresetcat02 = presetcat02->get_active (); - } - - if (listener) { - if (presetcat02->get_active ()) { - listener->panelChanged (Evcatpreset, M ("GENERAL_ENABLED")); - } else { - listener->panelChanged (Evcatpreset, M ("GENERAL_DISABLED")); - } - } - -} void ColorAppearance::datacie_toggled () { @@ -2001,9 +1849,6 @@ void ColorAppearance::autoCamChanged (double ccam, double ccamout) void ColorAppearance::adapCamChanged (double cadap) { - if(presetcat02->get_active()){ - return; - } idle_register.add( [this, cadap]() -> bool @@ -2034,9 +1879,6 @@ void ColorAppearance::wbCamChanged (double temp, double tin) void ColorAppearance::ybCamChanged (int ybsc) { - if(presetcat02->get_active()){ - return; - } idle_register.add( [this, ybsc]() -> bool @@ -2122,16 +1964,6 @@ void ColorAppearance::adjusterChanged(Adjuster* a, double newval) void ColorAppearance::adjusterAutoToggled(Adjuster* a) { - /* - if(presetcat02->get_active ()){ - if(tempout->getAutoValue()) { - tempout->resetValue (false); - } else { - tempout->setValue (nexttemp); - tempout->setAutoValue (true); - } - } -*/ if (multiImage) { if (degree->getAutoInconsistent()) { degree->setAutoInconsistent (false); diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index ce1971e85..d3953c11f 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -68,7 +68,6 @@ public: bool adapCamComputed_ (); void ybCamChanged (int yb) override; bool ybCamComputed_ (); - void presetcat02pressed (); void curveChanged (CurveEditor* ce) override; void curveMode1Changed (); bool curveMode1Changed_ (); @@ -106,7 +105,6 @@ public: void writeOptions (std::vector &tpOpen); private: - rtengine::ProcEvent Evcatpreset; rtengine::ProcEvent EvCATAutotempout; rtengine::ProcEvent EvCATillum; rtengine::ProcEvent EvCATcomplex; @@ -159,8 +157,6 @@ private: Gtk::CheckButton* tonecie; // Gtk::CheckButton* sharpcie; Gtk::Button* neutral; - Gtk::CheckButton* presetcat02; - sigc::connection presetcat02conn; MyComboBoxText* surrsrc; sigc::connection surrsrcconn; @@ -198,7 +194,6 @@ private: bool lastgamut; bool lastdatacie; bool lasttonecie; - bool lastpresetcat02; double nexttemp; double nextgreen; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9c7a92f39..41b19edf2 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -254,7 +254,6 @@ void ParamsEdited::set(bool v) colorappearance.ybout = v; colorappearance.tempsc = v; colorappearance.greensc = v; - colorappearance.presetcat02 = v; //colorBoost.amount = v; //colorBoost.avoidclip = v; @@ -955,7 +954,6 @@ void ParamsEdited::initFrom(const std::vector& colorappearance.ybout = colorappearance.ybout && p.colorappearance.ybout == other.colorappearance.ybout; colorappearance.tempsc = colorappearance.tempsc && p.colorappearance.tempsc == other.colorappearance.tempsc; colorappearance.greensc = colorappearance.greensc && p.colorappearance.greensc == other.colorappearance.greensc; - colorappearance.presetcat02 = colorappearance.presetcat02 && p.colorappearance.presetcat02 == other.colorappearance.presetcat02; //colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount; //colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip; @@ -3034,9 +3032,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.colorappearance.tonecie = mods.colorappearance.tonecie; } - if (colorappearance.presetcat02) { - toEdit.colorappearance.presetcat02 = mods.colorappearance.presetcat02; - } // if (colorappearance.sharpcie) toEdit.colorappearance.sharpcie = mods.colorappearance.sharpcie; if (impulseDenoise.enabled) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3c108f33d..43b4e4e40 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -305,7 +305,6 @@ struct ColorAppearanceParamsEdited { bool ybout; bool tempsc; bool greensc; - bool presetcat02; }; struct DirPyrDenoiseParamsEdited { From 21afbaf90bfceaedf0d0e6f836284c4f3f29cbe3 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 6 Jan 2023 06:43:21 +0100 Subject: [PATCH 161/326] CIECAM - Changes such as symmetric works and temperature output makes sense - issue #6656 (#6658) * changes such as symmetric works and temperature output makes sense * Comment code * other Comment code and small change * Change tint in tooltip temperature * Improve GUI for tempout and greenout --- rtdata/languages/default | 1 + rtengine/improccoordinator.cc | 58 +++++++++++++++++++++++++------ rtgui/colorappearance.cc | 65 ++++++++++++++++++++--------------- 3 files changed, 87 insertions(+), 37 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2631278e5..894ca6963 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2259,6 +2259,7 @@ TP_COLORAPP_TCMODE_LIGHTNESS;Lightness TP_COLORAPP_TCMODE_SATUR;Saturation 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_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_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_TONECIE;Use CIECAM for tone mapping TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. TP_COLORAPP_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. diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 2a2f1079b..ec5ffc8ef 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1913,7 +1913,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) adap = pow(2.0, E_V - 3.0); // cd / m2 // end calculation adaptation scene luminosity } - + if(params->colorappearance.catmethod == "symg") {//force abolute luminance scenescene to 400 in symmetric + adap = 400.; + } float d, dj, yb; bool execsharp = false; @@ -1935,24 +1937,60 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) CAMBrightCurveQ.dirty = true; ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, scale, execsharp, d, dj, yb, 1); - + //call listener if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) { - acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); + if(params->colorappearance.catmethod == "symg") {//force chromatic adaptation to 90 in symmetric + d = 0.9; + dj = 0.9; + } + acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); } if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled) { - acListener->adapCamChanged(adap); //real value of adapt scene + acListener->adapCamChanged(adap); //real value of adapt scene, force to 400 in symmetric } if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) { + if(params->colorappearance.catmethod == "symg") {//force yb scene to 18 in symmetric + yb = 18; + } + acListener->ybCamChanged((int) yb); //real value Yb scene } - - // if (params->colorappearance.enabled && params->colorappearance.autotempout) { - // if (params->colorappearance.enabled) { - // acListener->wbCamChanged(params->wb.temperature, params->wb.green); //real temp and tint - // acListener->wbCamChanged(params->wb.temperature, 1.f); //real temp and tint = 1. - // } + double tempsym = 5003.; + int wmodel = 0;//wmodel allows - arbitrary - choice of illuminant and temp with choice + if (params->colorappearance.wbmodel == "RawT") { + wmodel = 0; + } else if (params->colorappearance.wbmodel == "RawTCAT02") { + wmodel = 1; + } else if (params->colorappearance.wbmodel == "free") { + wmodel = 2;//force white balance in symmetric + } + + if(params->colorappearance.catmethod == "symg" && wmodel == 2) { + tempsym = params->wb.temperature;//force white balance in symmetric + } else { + if (params->colorappearance.illum == "iA") {//otherwise force illuminant source + tempsym = 2856.; + } else if (params->colorappearance.illum == "i41") { + tempsym = 4100.; + } else if (params->colorappearance.illum == "i50") { + tempsym = 5003.; + } else if (params->colorappearance.illum == "i55") { + tempsym = 5503.; + } else if (params->colorappearance.illum == "i60") { + tempsym = 6000. ; + } else if (params->colorappearance.illum == "i65") { + tempsym = 6504.; + } else if (params->colorappearance.illum == "i75") { + tempsym = 7504.; + } else if (params->colorappearance.illum == "ifree") { + tempsym = params->wb.temperature;//force white balance in symmetric + } + } + if (params->colorappearance.enabled && params->colorappearance.autotempout) { + acListener->wbCamChanged(tempsym, 1.f); //real temp and tint = 1. + } } else { // CIECAM is disabled, we free up its image buffer to save some space diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index 5cae8cce8..89661a884 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -681,14 +681,22 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" ybout->set_tooltip_markup (M ("TP_COLORAPP_YBOUT_TOOLTIP")); tempout->set_tooltip_markup (M ("TP_COLORAPP_TEMP2_TOOLTIP")); - // tempout->throwOnButtonRelease(); - // tempout->addAutoButton (M ("TP_COLORAPP_TEMPOUT_TOOLTIP")); - + tempout->throwOnButtonRelease(); + tempout->addAutoButton (M ("TP_COLORAPP_TEMPOUT_TOOLTIP")); + // I renable tempout with addautobutton to work properly (and all code disabled). There are certainly some redundancies, but it doesn't matter tempout->show(); greenout->show(); ybout->show(); - p3VBox->pack_start (*tempout); - p3VBox->pack_start (*greenout); + Gtk::Frame *tempgreenFrame; + tempgreenFrame = Gtk::manage(new Gtk::Frame()); + tempgreenFrame->set_label_align (0.025, 0.5); + Gtk::Box* tempgreenVBox; + tempgreenVBox = Gtk::manage ( new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + tempgreenVBox->set_spacing (2); + tempgreenVBox->pack_start (*tempout); + tempgreenVBox->pack_start (*greenout); + tempgreenFrame->add(*tempgreenVBox); + p3VBox->pack_start(*tempgreenFrame); p3VBox->pack_start (*ybout); Gtk::Box* surrHBox = Gtk::manage (new Gtk::Box ()); @@ -822,7 +830,7 @@ void ColorAppearance::neutral_pressed () qcontrast->resetValue (false); colorh->resetValue (false); tempout->resetValue (false); -// tempout->setAutoValue (true); + tempout->setAutoValue (true); greenout->resetValue (false); ybout->resetValue (false); tempsc->resetValue (false); @@ -913,7 +921,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) adapscen->setAutoInconsistent (multiImage && !pedited->colorappearance.autoadapscen); ybscen->setAutoInconsistent (multiImage && !pedited->colorappearance.autoybscen); set_inconsistent (multiImage && !pedited->colorappearance.enabled); - // tempout->setAutoInconsistent (multiImage && !pedited->colorappearance.autotempout); + tempout->setAutoInconsistent (multiImage && !pedited->colorappearance.autotempout); shape->setUnChanged (!pedited->colorappearance.curve); shape2->setUnChanged (!pedited->colorappearance.curve2); @@ -1098,7 +1106,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) lastAutoAdapscen = pp->colorappearance.autoadapscen; lastAutoDegreeout = pp->colorappearance.autodegreeout; lastAutoybscen = pp->colorappearance.autoybscen; -// lastAutotempout = pp->colorappearance.autotempout; + lastAutotempout = pp->colorappearance.autotempout; degree->setValue (pp->colorappearance.degree); degree->setAutoValue (pp->colorappearance.autodegree); @@ -1121,7 +1129,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) qcontrast->setValue (pp->colorappearance.qcontrast); colorh->setValue (pp->colorappearance.colorh); tempout->setValue (pp->colorappearance.tempout); -// tempout->setAutoValue (pp->colorappearance.autotempout); + tempout->setAutoValue (pp->colorappearance.autotempout); greenout->setValue (pp->colorappearance.greenout); ybout->setValue (pp->colorappearance.ybout); tempsc->setValue (pp->colorappearance.tempsc); @@ -1185,7 +1193,7 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pp->colorappearance.curve2 = shape2->getCurve (); pp->colorappearance.curve3 = shape3->getCurve (); pp->colorappearance.tempout = tempout->getValue (); -// pp->colorappearance.autotempout = tempout->getAutoValue (); + pp->colorappearance.autotempout = tempout->getAutoValue (); pp->colorappearance.greenout = greenout->getValue (); pp->colorappearance.ybout = ybout->getValue (); pp->colorappearance.tempsc = tempsc->getValue (); @@ -1263,7 +1271,7 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pedited->colorappearance.ybout = ybout->getEditedState (); pedited->colorappearance.tempsc = tempsc->getEditedState (); pedited->colorappearance.greensc = greensc->getEditedState (); -// pedited->colorappearance.autotempout = !tempout->getAutoInconsistent(); + pedited->colorappearance.autotempout = !tempout->getAutoInconsistent(); } @@ -1355,7 +1363,9 @@ void ColorAppearance::updateGUIToMode(int mode) curveEditorG->hide(); curveEditorG2->hide(); curveEditorG3->hide(); - greenout->hide(); + //greenout->hide(); + greenout->set_sensitive(false); + badpixsl->hide(); datacie->hide(); } else { @@ -1364,7 +1374,8 @@ void ColorAppearance::updateGUIToMode(int mode) curveEditorG->show(); curveEditorG2->show(); curveEditorG3->show(); - greenout->show(); + // greenout->show(); + greenout->set_sensitive(true); badpixsl->show(); datacie->show(); } @@ -1470,13 +1481,13 @@ void ColorAppearance::catmethodChanged() ybout->setValue(18); tempout->setValue (nexttemp); -/* if(tempout->getAutoValue()) { - tempout->resetValue (false); - } else { - tempout->setValue (nexttemp); - tempout->setAutoValue (true); - } -*/ + if(tempout->getAutoValue()) { + tempout->resetValue (false); + } else { + tempout->setValue (nexttemp); + tempout->setAutoValue (true); + } + greenout->setValue (nextgreen); enableListener(); @@ -1525,7 +1536,7 @@ void ColorAppearance::catmethodChanged() adaplum->resetValue (false); degreeout->resetValue (false); ybout->resetValue (false); - // tempout->resetValue (false); + tempout->resetValue (false); tempout->setValue (nexttemp); greenout->resetValue (false); enableListener(); @@ -1863,14 +1874,14 @@ void ColorAppearance::adapCamChanged (double cadap) void ColorAppearance::wbCamChanged (double temp, double tin) -{ +{//reactivate this function idle_register.add( [this, temp, tin]() -> bool { disableListener(); tempout->setValue(temp); - greenout->setValue(tin); + greenout->setValue(tin); enableListener(); return false; } @@ -1999,7 +2010,7 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) ybscen->setAutoInconsistent (true); } -/* lastAutotempout = tempout->getAutoValue(); + lastAutotempout = tempout->getAutoValue(); if (tempout->getAutoInconsistent()) { tempout->setAutoInconsistent (false); @@ -2009,7 +2020,7 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) } lastAutotempout = tempout->getAutoValue(); -*/ + } if (listener && (multiImage || getEnabled()) ) { @@ -2053,7 +2064,7 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) listener->panelChanged (EvCATAutoyb, M ("GENERAL_DISABLED")); } } -/* + if (a == tempout) { if (tempout->getAutoInconsistent()) { listener->panelChanged (EvCATAutotempout, M ("GENERAL_UNCHANGED")); @@ -2063,7 +2074,7 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) listener->panelChanged (EvCATAutotempout, M ("GENERAL_DISABLED")); } } -*/ + } } void ColorAppearance::enabledChanged () From 5468e74e57aa79af32080be91b2317231694ad35 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 8 Jan 2023 17:20:42 -0800 Subject: [PATCH 162/326] Fall back to custom external editor launcher --- rtgui/extprog.cc | 33 +++++++++++++++++++++++++++------ rtgui/extprog.h | 2 +- rtgui/rtwindow.h | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index e4cf63733..9ec87c548 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -318,22 +318,26 @@ bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName) return spawnCommandAsync (cmdLine); } -bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) +bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName, const Glib::ustring* command) { + if (!command) { + command = &(options.customEditorProg); + } + #if defined WIN32 - const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\""); + const auto cmdLine = Glib::ustring("\"") + *command + Glib::ustring("\""); auto success = ShellExecute( NULL, "open", cmdLine.c_str(), ('"' + fileName + '"').c_str(), NULL, SW_SHOWNORMAL ); return (uintptr_t)success > 32; #elif defined __APPLE__ - const auto cmdLine = options.customEditorProg + Glib::ustring(" \"") + fileName + Glib::ustring("\""); + const auto cmdLine = *command + Glib::ustring(" \"") + fileName + Glib::ustring("\""); return spawnCommandAsync (cmdLine); #else - const auto cmdLine = options.customEditorProg + Glib::ustring(" ") + Glib::shell_quote(fileName); + const auto cmdLine = *command + Glib::ustring(" ") + Glib::shell_quote(fileName); return spawnCommandAsync (cmdLine); #endif @@ -342,13 +346,30 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo) { + bool success = false; + try { - return editorInfo->launch(Gio::File::create_for_path(fileName)); + success = editorInfo->launch(Gio::File::create_for_path(fileName)); } catch (const Glib::Error &e) { std::cerr << "Error launching external editor.\n" << "Error code #" << e.code() << ": " << e.what() << std::endl; - return false; + success = false; } + + if (success) { + return true; + } + + if (rtengine::settings->verbose) { + std::cout << "Unable to launch external editor with Gio. Trying custom launcher." << std::endl; + } + Glib::ustring command = editorInfo->get_commandline(); +#if defined WIN32 + if (command.length() > 2 && command[0] == '"' && command[command.length() - 1] == '"') { + command = command.substr(1, command.length() - 2); + } +#endif + return openInCustomEditor(fileName, &command); } diff --git a/rtgui/extprog.h b/rtgui/extprog.h index cdcf14e48..6547896ef 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -69,7 +69,7 @@ public: static bool openInGimp (const Glib::ustring& fileName); static bool openInPhotoshop (const Glib::ustring& fileName); - static bool openInCustomEditor (const Glib::ustring& fileName); + static bool openInCustomEditor (const Glib::ustring& fileName, const Glib::ustring* command = nullptr); static bool openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo); }; diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index f62430190..985cd3893 100755 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -33,7 +33,7 @@ class BatchQueueEntry; class BatchQueuePanel; class EditorPanel; -class ExternalEditor; +struct ExternalEditor; class FilePanel; class PLDBridge; class RTWindow final : From 194ef397a677eb1bdc435c376cfd075c14c51788 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 8 Jan 2023 22:17:21 -0800 Subject: [PATCH 163/326] Fix external editor file chooser filter (Windows) Look for files with the MIME type "application/x-msdownload", which are Windows executable files. The Gio function for determining if a file is executable does not work for Windows. --- rtgui/externaleditorpreferences.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 58a562725..79dac52d2 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -274,7 +274,11 @@ void ExternalEditorPreferences::openFileChooserDialog() const auto exe_filter = Gtk::FileFilter::create(); exe_filter->set_name(M("FILECHOOSER_FILTER_EXECUTABLE")); exe_filter->add_custom(Gtk::FILE_FILTER_MIME_TYPE, [](const Gtk::FileFilter::Info &info) { +#ifdef WIN32 + return info.mime_type == "application/x-msdownload"; +#else return Gio::content_type_can_be_executable(info.mime_type); +#endif }); const auto all_filter = Gtk::FileFilter::create(); all_filter->set_name(M("FILECHOOSER_FILTER_ANY")); From 22edf5f0697dbdafa51744b9c03dcc673e7de957 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:10:54 -0800 Subject: [PATCH 164/326] Add radio indicator to external editor selector Make it easier to see that the selector is for changing the current editor and not for immediately sending the image to the clicked-on editor. --- rtdata/themes/TooWaBlue-GTK3-20_.css | 5 ++ rtdata/themes/size - Legacy.css | 7 +- rtdata/themes/size.css | 5 ++ rtgui/editorpanel.cc | 16 ++-- rtgui/editorpanel.h | 1 + rtgui/guiutils.cc | 108 +++++++++++++++++++++------ rtgui/guiutils.h | 56 +++++++++++--- rtgui/popupcommon.cc | 35 ++++++--- rtgui/popupcommon.h | 9 ++- 9 files changed, 186 insertions(+), 56 deletions(-) diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index 4e7e192ad..d2a63dd2e 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -1278,6 +1278,11 @@ menuitem:hover > * { color: @text-hl-color; } +menu menuitem > radio + * image:not(.dummy), +#MyExpander menu menuitem > radio + * image:not(.dummy) { + margin-left: 1pt; +} + menu image:not(.dummy), #MyExpander menu image:not(.dummy) { min-height: 2em; diff --git a/rtdata/themes/size - Legacy.css b/rtdata/themes/size - Legacy.css index 08c39f973..089a909ee 100644 --- a/rtdata/themes/size - Legacy.css +++ b/rtdata/themes/size - Legacy.css @@ -383,6 +383,11 @@ menu arrow { margin: 0 -0.25em 0 0; } +menu menuitem > radio + * image:not(.dummy), +#MyExpander menu menuitem > radio + * image:not(.dummy) { + margin-left: 1pt; +} + menu image:not(.dummy), #MyExpander menu image:not(.dummy) { min-height: 2em; @@ -1029,4 +1034,4 @@ messagedialog headerbar button.titlebutton { min-height: 1.25em; margin: 0; } -/*** end ***************************************************************************************/ \ No newline at end of file +/*** end ***************************************************************************************/ diff --git a/rtdata/themes/size.css b/rtdata/themes/size.css index 2d23bf860..675ed51c2 100644 --- a/rtdata/themes/size.css +++ b/rtdata/themes/size.css @@ -351,6 +351,11 @@ menu arrow { margin: 0 -0.25em 0 0; } +menu menuitem > radio + * image:not(.dummy), +#MyExpander menu menuitem > radio + * image:not(.dummy) { + margin-left: 1pt; +} + menu image:not(.dummy), #MyExpander menu image:not(.dummy) { min-height: 2em; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 3a180cc58..ebcf221da 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -905,7 +905,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel) send_to_external = Gtk::manage(new PopUpButton("", false)); send_to_external->set_tooltip_text(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); setExpandAlignProperties(send_to_external->buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER")); updateExternalEditorWidget( options.externalEditorIndex >= 0 ? options.externalEditorIndex : options.externalEditors.size(), options.externalEditors @@ -2748,10 +2747,14 @@ void EditorPanel::tbShowHideSidePanels_managestate() void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vector &editors) { - // Remove the editors and leave the "Other" entry. - while (send_to_external->getEntryCount() > 1) { - send_to_external->removeEntry(0); + // Remove the editors. + while (send_to_external->getEntryCount()) { + send_to_external->removeEntry(send_to_external->getEntryCount() - 1); } + + // Create new radio button group because they cannot be reused: https://developer-old.gnome.org/gtkmm/3.16/classGtk_1_1RadioButtonGroup.html#details. + send_to_external_radio_group = Gtk::RadioButtonGroup(); + // Add the editors. for (unsigned i = 0; i < editors.size(); i++) { const auto & name = editors[i].name.empty() ? Glib::ustring(" ") : editors[i].name; @@ -2771,11 +2774,12 @@ void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vecto gioIcon = Gio::Icon::deserialize(Glib::VariantBase(icon_variant)); } - send_to_external->insertEntry(i, gioIcon, name); + send_to_external->insertEntry(i, gioIcon, name, &send_to_external_radio_group); } else { - send_to_external->insertEntry(i, "palette-brush.png", name); + send_to_external->insertEntry(i, "palette-brush.png", name, &send_to_external_radio_group); } } + send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER"), &send_to_external_radio_group); send_to_external->setSelected(selectedIndex); send_to_external->show(); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index e822f1677..fa7f7943b 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -246,6 +246,7 @@ private: Gtk::Button* queueimg; Gtk::Button* saveimgas; PopUpButton* send_to_external; + Gtk::RadioButtonGroup send_to_external_radio_group; Gtk::Button* navSync; Gtk::Button* navNext; Gtk::Button* navPrev; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 522ec9b7f..18b82fe36 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1506,48 +1506,110 @@ TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx } -MyImageMenuItem::MyImageMenuItem(Glib::ustring label, Glib::ustring imageFileName) +class ImageAndLabel::Impl { - RTImage* itemImage = nullptr; +public: + RTImage* image; + Gtk::Label* label; - if (!imageFileName.empty()) { - itemImage = Gtk::manage(new RTImage(imageFileName)); + Impl(RTImage* image, Gtk::Label* label) : image(image), label(label) {} + static std::unique_ptr createImage(const Glib::ustring& fileName); +}; + +std::unique_ptr ImageAndLabel::Impl::createImage(const Glib::ustring& fileName) +{ + if (fileName.empty()) { + return nullptr; } - - construct(label, itemImage); + return std::unique_ptr(new RTImage(fileName)); } -MyImageMenuItem::MyImageMenuItem(Glib::ustring label, RTImage* itemImage) { - construct(label, itemImage); +ImageAndLabel::ImageAndLabel(const Glib::ustring& label, const Glib::ustring& imageFileName) : + ImageAndLabel(label, Gtk::manage(Impl::createImage(imageFileName).release())) +{ } -void MyImageMenuItem::construct(Glib::ustring label, RTImage* itemImage) +ImageAndLabel::ImageAndLabel(const Glib::ustring& label, RTImage *image) : + pimpl(new Impl(image, Gtk::manage(new Gtk::Label(label)))) { - box = Gtk::manage (new Gtk::Grid()); - this->label = Gtk::manage( new Gtk::Label(label)); - box->set_orientation(Gtk::ORIENTATION_HORIZONTAL); + Gtk::Grid* grid = Gtk::manage(new Gtk::Grid()); + grid->set_orientation(Gtk::ORIENTATION_HORIZONTAL); - if (itemImage) { - image = itemImage; - box->attach_next_to(*image, Gtk::POS_LEFT, 1, 1); - } else { - image = nullptr; + if (image) { + grid->attach_next_to(*image, Gtk::POS_LEFT, 1, 1); } - box->attach_next_to(*this->label, Gtk::POS_RIGHT, 1, 1); - box->set_column_spacing(4); - box->set_row_spacing(0); - add(*box); + grid->attach_next_to(*(pimpl->label), Gtk::POS_RIGHT, 1, 1); + grid->set_column_spacing(4); + grid->set_row_spacing(0); + pack_start(*grid, Gtk::PACK_SHRINK, 0); +} + +const RTImage* ImageAndLabel::getImage() const +{ + return pimpl->image; +} + +const Gtk::Label* ImageAndLabel::getLabel() const +{ + return pimpl->label; +} + +class MyImageMenuItem::Impl +{ +private: + std::unique_ptr widget; + +public: + Impl(const Glib::ustring &label, const Glib::ustring &imageFileName) : + widget(new ImageAndLabel(label, imageFileName)) {} + Impl(const Glib::ustring &label, RTImage *itemImage) : + widget(new ImageAndLabel(label, itemImage)) {} + ImageAndLabel* getWidget() const { return widget.get(); } +}; + +MyImageMenuItem::MyImageMenuItem(const Glib::ustring& label, const Glib::ustring& imageFileName) : + pimpl(new Impl(label, imageFileName)) +{ + add(*(pimpl->getWidget())); +} + +MyImageMenuItem::MyImageMenuItem(const Glib::ustring& label, RTImage* itemImage) : + pimpl(new Impl(label, itemImage)) +{ + add(*(pimpl->getWidget())); } const RTImage *MyImageMenuItem::getImage () const { - return image; + return pimpl->getWidget()->getImage(); } const Gtk::Label* MyImageMenuItem::getLabel () const { - return label; + return pimpl->getWidget()->getLabel(); +} + +class MyRadioImageMenuItem::Impl +{ + std::unique_ptr widget; + +public: + Impl(const Glib::ustring &label, RTImage *image) : + widget(new ImageAndLabel(label, image)) {} + ImageAndLabel* getWidget() const { return widget.get(); } +}; + +MyRadioImageMenuItem::MyRadioImageMenuItem(const Glib::ustring& label, RTImage *image, Gtk::RadioButton::Group& group) : + Gtk::RadioMenuItem(group), + pimpl(new Impl(label, image)) +{ + add(*(pimpl->getWidget())); +} + +const Gtk::Label* MyRadioImageMenuItem::getLabel() const +{ + return pimpl->getWidget()->getLabel(); } MyProgressBar::MyProgressBar(int width) : w(rtengine::max(width, 10 * RTScalable::getScale())) {} diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index d133599f2..938c81c42 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -482,20 +482,56 @@ public: TextOrIcon (const Glib::ustring &filename, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx); }; -class MyImageMenuItem final : public Gtk::MenuItem +/** + * Widget with image and label placed horizontally. + */ +class ImageAndLabel final : public Gtk::Box { -private: - Gtk::Grid *box; - RTImage *image; - Gtk::Label *label; - - void construct(Glib::ustring label, RTImage* image); + class Impl; + std::unique_ptr pimpl; public: - MyImageMenuItem (Glib::ustring label, Glib::ustring imageFileName); - MyImageMenuItem (Glib::ustring label, RTImage* image); + ImageAndLabel(const Glib::ustring& label, const Glib::ustring& imageFileName); + ImageAndLabel(const Glib::ustring& label, RTImage* image); + const RTImage* getImage() const; + const Gtk::Label* getLabel() const; +}; + +/** + * Menu item with an image and label. + */ +class MyImageMenuItemInterface +{ +public: + virtual const Gtk::Label* getLabel() const = 0; +}; + +/** + * Basic image menu item. + */ +class MyImageMenuItem final : public Gtk::MenuItem, public MyImageMenuItemInterface +{ + class Impl; + std::unique_ptr pimpl; + +public: + MyImageMenuItem (const Glib::ustring& label, const Glib::ustring& imageFileName); + MyImageMenuItem (const Glib::ustring& label, RTImage* image); const RTImage *getImage () const; - const Gtk::Label* getLabel () const; + const Gtk::Label* getLabel() const override; +}; + +/** + * Image menu item with radio selector. + */ +class MyRadioImageMenuItem final : public Gtk::RadioMenuItem, public MyImageMenuItemInterface +{ + class Impl; + std::unique_ptr pimpl; + +public: + MyRadioImageMenuItem(const Glib::ustring& label, RTImage* image, Gtk::RadioButton::Group& group); + const Gtk::Label* getLabel() const override; }; class MyProgressBar final : public Gtk::ProgressBar diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 1dbde833e..a6d9b6046 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -73,44 +73,50 @@ PopUpCommon::~PopUpCommon () { } -bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) +bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup) { - return insertEntry(getEntryCount(), fileName, label); + return insertEntry(getEntryCount(), fileName, label, radioGroup); } -bool PopUpCommon::insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label) +bool PopUpCommon::insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label, Gtk::RadioButtonGroup *radioGroup) { RTImage* image = nullptr; if (!fileName.empty()) { image = Gtk::manage(new RTImage(fileName)); } - bool success = insertEntryImpl(position, fileName, Glib::RefPtr(), image, label); + bool success = insertEntryImpl(position, fileName, Glib::RefPtr(), image, label, radioGroup); if (!success && image) { delete image; } return success; } -bool PopUpCommon::insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label) +bool PopUpCommon::insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label, Gtk::RadioButtonGroup *radioGroup) { RTImage* image = Gtk::manage(new RTImage(gIcon, Gtk::ICON_SIZE_BUTTON)); - bool success = insertEntryImpl(position, "", gIcon, image, label); + bool success = insertEntryImpl(position, "", gIcon, image, label, radioGroup); if (!success) { delete image; } return success; } -bool PopUpCommon::insertEntryImpl(int position, const Glib::ustring& fileName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label) +bool PopUpCommon::insertEntryImpl(int position, const Glib::ustring& fileName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup) { if (label.empty() || position < 0 || position > getEntryCount()) return false; // Create the menu item and image - MyImageMenuItem *newItem = Gtk::manage(new MyImageMenuItem(label, image)); + Gtk::MenuItem *newItem; + if (radioGroup) { + newItem = Gtk::manage(new MyRadioImageMenuItem(label, image, *radioGroup)); + } + else { + newItem = Gtk::manage(new MyImageMenuItem(label, image)); + } imageIcons.insert(imageIcons.begin() + position, gIcon); imageFilenames.insert(imageFilenames.begin() + position, fileName); - images.insert(images.begin() + position, newItem->getImage()); + images.insert(images.begin() + position, image); // When there is at least 1 choice, we add the arrow button if (images.size() == 1) { @@ -154,9 +160,8 @@ void PopUpCommon::removeEntry(int position) setButtonHint(); } - MyImageMenuItem *menuItem = dynamic_cast(menu->get_children()[position]); + std::unique_ptr menuItem(menu->get_children()[position]); menu->remove(*menuItem); - delete menuItem; imageIcons.erase(imageIcons.begin() + position); imageFilenames.erase(imageFilenames.begin() + position); images.erase(images.begin() + position); @@ -222,6 +227,12 @@ bool PopUpCommon::setSelected (int entryNum) changeImage(entryNum); selected = entryNum; setButtonHint(); + + auto radioMenuItem = dynamic_cast(menu->get_children()[entryNum]); + if (radioMenuItem && menu->get_active() != radioMenuItem) { + radioMenuItem->set_active(); + } + return true; } } @@ -248,7 +259,7 @@ void PopUpCommon::setButtonHint() if (selected > -1) { auto widget = menu->get_children ()[selected]; - auto item = dynamic_cast(widget); + auto item = dynamic_cast(widget); if (item) { hint += escapeHtmlChars(item->getLabel()->get_text()); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 59a5b8d0e..9ca6b2030 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -40,6 +40,7 @@ class Grid; class Menu; class Button; class ImageMenuItem; +class RadioButtonGroup; class Widget; } @@ -60,9 +61,9 @@ public: explicit PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); - bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); - bool insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label); - bool insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label); + 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 insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); int getEntryCount () const; bool setSelected (int entryNum); int getSelected () const; @@ -91,7 +92,7 @@ private: void changeImage(int position); void changeImage(const Glib::ustring& fileName, 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); + bool insertEntryImpl(int position, const Glib::ustring& fileName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup); void showMenu(GdkEventButton* event); protected: From 48b1b6f9be55303046bda82edff70fc6c3bccad2 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 17 Jan 2023 22:06:58 -0800 Subject: [PATCH 165/326] Add OM-1 raw decoding and basic camconst entry --- rtengine/camconst.json | 10 ++++++++++ rtengine/dcraw.cc | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 7a143e850..d90cc169b 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2170,6 +2170,16 @@ Camera constants: "dcraw_matrix" : [8360, -2420, -880, -3928, 12353, 1739, -1381, 2416, 5173] // DNG }, + { // Quality C + "make_model": ["OM Digital Solutions OM-1"], + "ranges": { "white": 4095 }, + "raw_crop" : [ + { "frame" : [10400, 7792], "crop": [0, 0, 10390, 7792] }, + { "frame" : [8180, 6132], "crop": [0, 0, 8172, 6132] }, + { "frame" : [5220, 3912], "crop": [0, 0, 5220, 3912] } + ] + }, + { // Quality B "make_model": [ "Panasonic DC-LX100M2" ], "dcraw_matrix": [ 11577, -4230, -1106, -3967, 12211, 1957, -759, 1762, 5610 ], // DNG v13.2 diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 8eca727b4..7a2a5b4d5 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -5546,9 +5546,11 @@ void CLASS parse_makernote (int base, int uptag) offset = get4(); fseek (ifp, offset-8, SEEK_CUR); } else if (!strcmp (buf,"OLYMPUS") || - !strcmp (buf,"PENTAX ")) { + !strcmp (buf,"PENTAX ") || + !strncmp(buf,"OM SYS",6)) { // From LibRaw base = ftell(ifp)-10; fseek (ifp, -2, SEEK_CUR); + if (buf[1] == 'M') get4(); // From LibRaw order = get2(); if (buf[0] == 'O') get2(); } else if (!strncmp (buf,"SONY",4) || @@ -7172,7 +7174,7 @@ void CLASS apply_tiff() if (tiff_ifd[raw].bytes*4 == raw_width*raw_height*7) break; load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; - if (!strncmp(make,"OLYMPUS",7) && + if ((!strncmp(make,"OLYMPUS",7) || !strncmp(make, "OM Digi", 7)) && // OM Digi from LibRaw tiff_ifd[raw].bytes*7 > raw_width*raw_height) load_raw = &CLASS olympus_load_raw; // ------- RT ------- @@ -8704,6 +8706,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, { "Olympus XZ-2", 0, 0, { 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 { "OmniVision", 0, 0, /* DJC */ { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, { "Pentax *ist DL2", 0, 0, From 7afdfc1e2bc17b8c4268397651a344fe7fb9dc15 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 24 Jan 2023 14:29:50 +0100 Subject: [PATCH 166/326] Abstract profile - Gamut improvment (#6665) * Gamut control when the chosen primaries are different from working profile * Gamut control abstract * Gamut label and history * Change to Wx Wz * Fixed crash if y primaries are set to zero * Fomated with Astylert ImProcFunctions::workingtrc and Color::primaries_to_xyz * Fixed black becomes green wit gamt abstract profile * Harmonize types in color.cc * Try to fix Multiplication result converted to larger type --- rtdata/languages/default | 2 + rtengine/color.cc | 176 ++++++++++++++++++++++++++++++-- rtengine/color.h | 7 ++ rtengine/iplab2rgb.cc | 211 +++++++++++++++++++++++++++++++-------- rtengine/procparams.cc | 4 + rtengine/procparams.h | 1 + rtgui/icmpanel.cc | 53 ++++++++++ rtgui/icmpanel.h | 5 + rtgui/paramsedited.cc | 6 ++ rtgui/paramsedited.h | 1 + 10 files changed, 415 insertions(+), 51 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 894ca6963..8120419d2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1421,6 +1421,7 @@ 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 @@ -2529,6 +2530,7 @@ 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. 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_INPUTCAMERA;Camera standard TP_ICM_INPUTCAMERAICC;Auto-matched camera profile diff --git a/rtengine/color.cc b/rtengine/color.cc index d6c35208d..085fd41ce 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -24,6 +24,7 @@ #include "sleef.h" #include "opthelper.h" #include "iccstore.h" +#include using namespace std; @@ -1910,6 +1911,152 @@ 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) +{ + //calculate Xr, Xg, Xb, Yr, Yb, Tg, Zr,Zg Zb + double Wy = 1.0; + double Xr = p[0] / p[1]; + double Yr = 1.0; + double Zr = (1.0 - p[0] - p[1]) / p[1]; + double Xg = p[2] / p[3]; + double Yg = 1.0; + double Zg = (1.0 - p[2] - p[3]) / p[3]; + double Xb = p[4] / p[5]; + double Yb = 1.0; + double Zb = (1.0 - p[4] - p[5]) / p[5]; + + using Triple = std::array; + + using Matrix = std::array; + + Matrix input_prim; + Matrix inv_input_prim = {}; + input_prim[0][0] = Xr; + input_prim[0][1] = Yr; + input_prim[0][2] = Zr; + input_prim[1][0] = Xg; + input_prim[1][1] = Yg; + input_prim[1][2] = Zg; + input_prim[2][0] = Xb; + input_prim[2][1] = Yb; + input_prim[2][2] = Zb; + + //invert matrix + if (!rtengine::invertMatrix(input_prim, inv_input_prim)) { + std::cout << "Matrix is not invertible, skipping" << std::endl; + } + + //white point D50 used by LCMS + double Wdx = 0.96420; + double Wdy = 1.0; + double Wdz = 0.82490; + + double Sr = Wx * inv_input_prim [0][0] + Wy * inv_input_prim [1][0] + Wz * inv_input_prim [2][0]; + double Sg = Wx * inv_input_prim [0][1] + Wy * inv_input_prim [1][1] + Wz * inv_input_prim [2][1]; + double Sb = Wx * inv_input_prim [0][2] + Wy * inv_input_prim [1][2] + Wz * inv_input_prim [2][2]; + + //XYZ matrix for primaries and temp + Matrix mat_xyz = {}; + mat_xyz[0][0] = Sr * Xr; + mat_xyz[0][1] = Sr * Yr; + mat_xyz[0][2] = Sr * Zr; + mat_xyz[1][0] = Sg * Xg; + mat_xyz[1][1] = Sg * Yg; + mat_xyz[1][2] = Sg * Zg; + mat_xyz[2][0] = Sb * Xb; + mat_xyz[2][1] = Sb * Yb; + mat_xyz[2][2] = Sb * Zb; + + //chromatic adaptation Bradford + 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; + + 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; + + //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]; + double Bs = Wx * MaBradford[0][2] + Wy * MaBradford[1][2] + Wz * MaBradford[2][2]; + + // R G B destination + double Rd = Wdx * MaBradford[0][0] + Wdy * MaBradford[1][0] + Wdz * MaBradford[2][0]; + double Gd = Wdx * MaBradford[0][1] + Wdy * MaBradford[1][1] + Wdz * MaBradford[2][1]; + double Bd = Wdx * MaBradford[0][2] + Wdy * MaBradford[1][2] + Wdz * MaBradford[2][2]; + + //cone destination + Matrix cone_dest_sourc = {}; + cone_dest_sourc [0][0] = Rd / Rs; + cone_dest_sourc [0][1] = 0.; + cone_dest_sourc [0][2] = 0.; + cone_dest_sourc [1][0] = 0.; + cone_dest_sourc [1][1] = Gd / Gs; + cone_dest_sourc [1][2] = 0.; + cone_dest_sourc [2][0] = 0.; + cone_dest_sourc [2][1] = 0.; + cone_dest_sourc [2][2] = Bd / Bs; + + //cone dest + Matrix cone_ma_one = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + cone_ma_one[i][j] = 0; + + for (int k = 0; k < 3; ++k) { + cone_ma_one[i][j] += cone_dest_sourc [i][k] * Ma_oneBradford[k][j]; + } + } + } + + //generate adaptation bradford matrix + Matrix adapt_chroma = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + adapt_chroma [i][j] = 0; + + for (int k = 0; k < 3; ++k) { + adapt_chroma[i][j] += MaBradford[i][k] * cone_ma_one[k][j]; + } + } + } + + Matrix mat_xyz_brad = {}; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + mat_xyz_brad[i][j] = 0; + + for (int k = 0; k < 3; ++k) { + mat_xyz_brad[i][j] += mat_xyz[i][k] * adapt_chroma[k][j]; + } + } + } + + //push result in pxyz + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + pxyz[i * 3 + j] = mat_xyz_brad[i][j]; + } + } +} /* * Gamut mapping algorithm @@ -1931,13 +2078,19 @@ void Color::Lch2Luv(float c, float h, float &u, float &v) * columns of the matrix p=xyz_rgb are RGB tristimulus primaries in XYZ * c is the color fixed on the boundary; and m=0 for c=0, m=1 for c=255 */ + void Color::gamutmap(float &X, float Y, float &Z, const double p[3][3]) { - float u = 4 * X / (X + 15 * Y + 3 * Z) - u0; - float v = 9 * Y / (X + 15 * Y + 3 * Z) - v0; - + float 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.0; + float lam_min = 1.0f; for (int c = 0; c < 3; c++) for (int m = 0; m < 2; m++) { @@ -1955,17 +2108,24 @@ void Color::gamutmap(float &X, float Y, float &Z, const double p[3][3]) p[0][c] * (5 * Y * p[1][c1] + m * 65535 * p[1][c1] * p[2][c2] + Y * p[2][c1] - m * 65535 * p[1][c2] * p[2][c1]) + m * 65535 * p[0][c2] * (p[1][c1] * p[2][c] - p[1][c] * p[2][c1]))); - if (lam[c][m] < lam_min && lam[c][m] > 0) { + if (lam[c][m] < lam_min && lam[c][m] > 0.f) { lam_min = lam[c][m]; } } - u = u * lam_min + u0; - v = v * lam_min + v0; + u = u * (double) lam_min + u0; + v = v * (double) lam_min + v0; X = (9 * u * Y) / (4 * v); - Z = (12 - 3 * u - 20 * v) * Y / (4 * v); + 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 f602ade83..3622a9e36 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1847,6 +1847,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 Get HSV's hue from the Lab's hue diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index f48b2e52e..dd02b8f0f 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -416,6 +416,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, { const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + 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 @@ -440,57 +442,64 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, if (settings->verbose) { printf("profile not accepted\n"); } + return; } if (mul == -5 && gampos == 2.4 && slpos == 12.92310) {//must be change if we change settings RT sRGB //only in this case we can shortcut..all process..no gamut control..because we reduce...leads to very small differences, but big speedup #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 < 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; - } - return; + 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; + } + + 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 #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 < ch; ++y) { int x = 0; #ifdef __SSE2__ + for (; x < cw - 3; x += 4) { - STVFU(dst->r(y,x), F2V(65536.f) * gammalog(LVFU(src->r(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); - STVFU(dst->g(y,x), F2V(65536.f) * gammalog(LVFU(src->g(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); - STVFU(dst->b(y,x), F2V(65536.f) * gammalog(LVFU(src->b(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); - } + STVFU(dst->r(y, x), F2V(65536.f) * gammalog(LVFU(src->r(y, x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); + STVFU(dst->g(y, x), F2V(65536.f) * gammalog(LVFU(src->g(y, x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); + STVFU(dst->b(y, x), F2V(65536.f) * gammalog(LVFU(src->b(y, x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4]))); + } + #endif + for (; x < cw; ++x) { - dst->r(y,x) = 65536.f * gammalog(src->r(y,x), gampos, slpos, g_a[3], g_a[4]); - dst->g(y,x) = 65536.f * gammalog(src->g(y,x), gampos, slpos, g_a[3], g_a[4]); - dst->b(y,x) = 65536.f * gammalog(src->b(y,x), gampos, slpos, g_a[3], g_a[4]); + dst->r(y, x) = 65536.f * gammalog(src->r(y, x), gampos, slpos, g_a[3], g_a[4]); + dst->g(y, x) = 65536.f * gammalog(src->g(y, x), gampos, slpos, g_a[3], g_a[4]); + dst->b(y, x) = 65536.f * gammalog(src->b(y, x), gampos, slpos, g_a[3], g_a[4]); } } + return; } - + float redxx = params->icm.redx; float redyy = params->icm.redy; @@ -498,6 +507,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, float bluyy = params->icm.bluy; float grexx = params->icm.grex; float greyy = params->icm.grey; + float epsil = 0.0001f; if (prim == 12) {//convert datas area to xy float redgraphx = params->icm.labgridcieALow; @@ -519,11 +529,34 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, greyy = 0.55f * (gregraphy + 1.f) - 0.1f; greyy = rtengine::LIM(greyy, 0.5f, 1.f); } + //fixed crash when there is no space or too small..just a line...Possible if bx, by aligned with Gx,Gy Rx,Ry - float ac = (greyy - redyy) / (grexx - redxx); + //fix crash if user select 0 for redyy, bluyy, greyy + if (redyy == 0.f) { + redyy = epsil; + } + + if (bluyy == 0.f) { + bluyy = epsil; + } + + if (greyy == 0.f) { + greyy = epsil; + } + + //fix crash if grexx - redxx = 0 + float grered = 1.f; + grered = grexx - redxx; + + if (grered == 0.f) { + grered = epsil; + } + + float ac = (greyy - redyy) / grered; float bc = greyy - ac * grexx; float yc = ac * bluxx + bc; - if ((bluyy < yc + 0.0004f) && (bluyy > yc - 0.0004f)) {//under 0.0004 in some case crash because space too small + + if ((bluyy < yc + 0.0004f) && (bluyy > yc - 0.0004f)) { //under 0.0004 in some case crash because space too small return; } @@ -564,7 +597,6 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } case ColorManagementParams::Primaries::ACES_P0: { - profile = "ACESp0"; break; } @@ -593,11 +625,13 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, break; } } - - if (settings->verbose && prim != 0) { - printf("prim=%i Profile Destination=%s\n", prim, profile.c_str()); - } + + if (settings->verbose && prim != 0) { + printf("prim=%i Profile Destination=%s\n", prim, profile.c_str()); + } + cmsHTRANSFORM hTransform = nullptr; + if (transform) { hTransform = transform; } else { @@ -622,7 +656,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, }; double tempv4 = 5003.; - float p[6]; //primaries + double p[6]; //primaries + double Wx = 1.0; + double Wz = 1.0; //primaries for 10 working profiles ==> output profiles if (profile == "WideGamut") { @@ -633,6 +669,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -642,6 +681,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -651,6 +693,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -660,7 +705,10 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, p[5] = 0.0600; tempv4 = 6504.; illum = toUnderlying(ColorManagementParams::Illuminant::D65); - } else if (profile == "Beta RGB") { + 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; @@ -668,6 +716,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -676,6 +727,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -685,6 +739,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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; @@ -694,6 +751,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, p[5] = -0.0770; tempv4 = 6004.; illum = toUnderlying(ColorManagementParams::Illuminant::D60); + Wx = 0.952646075; + Wz = 1.008825184; + } else if (profile == "ACESp1") { p[0] = 0.713; // ACES P1 primaries p[1] = 0.293; @@ -703,6 +763,9 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, p[5] = 0.044; tempv4 = 6004.; illum = toUnderlying(ColorManagementParams::Illuminant::D60); + Wx = 0.952646075; + Wz = 1.008825184; + } else if (profile == "ProPhoto") { p[0] = 0.7347; //ProPhoto and default primaries p[1] = 0.2653; @@ -711,8 +774,11 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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[0] = redxx; p[1] = redyy; p[2] = grexx; p[3] = greyy; @@ -743,11 +809,13 @@ 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); + // printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0, ga1, ga2, ga3, ga4); // 7 parameters for smoother curves cmsCIExyY xyD; + Glib::ustring ills = "D50"; + switch (ColorManagementParams::Illuminant(illum)) { case ColorManagementParams::Illuminant::DEFAULT: case ColorManagementParams::Illuminant::STDA: @@ -802,55 +870,95 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, cmsWhitePointFromTemp(&xyD, tempv4); switch (ColorManagementParams::Illuminant(illum)) { - case ColorManagementParams::Illuminant::DEFAULT: - case ColorManagementParams::Illuminant::D55: + case ColorManagementParams::Illuminant::DEFAULT: { + break; + } + + 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 wprofpri[9]; + + if (gamutcontrol) { + //xyz in functiuon primaries and illuminant + Color::primaries_to_xyz(p, Wx, Wz, wprofpri); + + 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 + } + } + } + //D41 0.377984 0.381229 //D55 0.332424 0.347426 //D80 0.293755 0.309185 @@ -869,7 +977,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, cmsWriteTag(oprofdef, cmsSigGreenTRCTag, GammaTRC[1]); cmsWriteTag(oprofdef, cmsSigBlueTRCTag, GammaTRC[2]); - //to read XYZ values and illuminant + //to read XYZ values and illuminant if (rtengine::settings->verbose) { cmsCIEXYZ *redT = static_cast(cmsReadTag(oprofdef, cmsSigRedMatrixColumnTag)); cmsCIEXYZ *greenT = static_cast(cmsReadTag(oprofdef, cmsSigGreenMatrixColumnTag)); @@ -881,6 +989,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } cmsFreeToneCurve(GammaTRC[0]); + if (oprofdef) { constexpr cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_GAMUTCHECK; const cmsHPROFILE iprof = ICCStore::getInstance()->getXYZProfile(); @@ -889,7 +998,10 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, lcmsMutex->unlock(); } } + if (hTransform) { + + #ifdef _OPENMP #pragma omp parallel if (multiThread) #endif @@ -901,19 +1013,30 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, #pragma omp for schedule(dynamic, 16) nowait #endif - for (int i = 0; i < ch; ++i) { + for (int i = 0; i < ch; ++i) + { float *p = pBuf.data; + for (int j = 0; j < cw; ++j) { const float r = src->r(i, j); const float g = src->g(i, j); const float b = src->b(i, j); + float X = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float Y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float Z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - *(p++) = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; - *(p++) = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; - *(p++) = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; + if (gamutcontrol) { + Color::gamutmap(X, Y, Z, wprofprim);//gamut control + } + + *(p++) = X; + *(p++) = Y; + *(p++) = Z; } + p = pBuf.data; cmsDoTransform(hTransform, p, p, cw); + for (int j = 0; j < cw; ++j) { dst->r(i, j) = *(p++) * normalize; dst->g(i, j) = *(p++) * normalize; @@ -921,10 +1044,12 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } } } + if (!keepTransForm) { cmsDeleteTransform(hTransform); hTransform = nullptr; } + transform = hTransform; } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 3f30374f7..371731b93 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2276,6 +2276,7 @@ ColorManagementParams::ColorManagementParams() : bluy(0.0001), preser(0.), fbw(false), + gamut(false), labgridcieALow(0.51763),//Prophoto red = (0.7347+0.1) * 1.81818 - 1 labgridcieBLow(-0.33582), labgridcieAHigh(-0.75163),//Prophoto blue @@ -2322,6 +2323,7 @@ bool ColorManagementParams::operator ==(const ColorManagementParams& other) cons && labgridcieWy == other.labgridcieWy && preser == other.preser && fbw == other.fbw + && gamut == other.gamut && aRendIntent == other.aRendIntent && outputProfile == other.outputProfile && outputIntent == other.outputIntent @@ -7190,6 +7192,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->icm.labgridcieWy, "Color Management", "LabGridcieWy", icm.labgridcieWy, 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.gamut, "Color Management", "Gamut", icm.gamut, keyFile); saveToKeyfile(!pedited || pedited->icm.outputProfile, "Color Management", "OutputProfile", icm.outputProfile, keyFile); saveToKeyfile( !pedited || pedited->icm.aRendIntent, @@ -9455,6 +9458,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index df319ffcc..24e1ca036 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1936,6 +1936,7 @@ struct ColorManagementParams { double bluy; double preser; bool fbw; + bool gamut; double labgridcieALow; double labgridcieBLow; double labgridcieAHigh; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 95a890443..3140fbea3 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -62,6 +62,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha EvICMpreser = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_PRESER"); EvICMLabGridciexy = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICL_LABGRIDCIEXY"); EvICMfbw = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_FBW"); + EvICMgamut = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_GAMUT"); isBatchMode = lastToneCurve = lastApplyLookTable = lastApplyBaselineExposureOffset = lastApplyHueSatMap = false; ipDialog = Gtk::manage(new MyFileChooserButton(M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); @@ -263,8 +264,12 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha wprimBox->pack_start(*wprim, Gtk::PACK_EXPAND_WIDGET); 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); + trcProfVBox->pack_start(*wprimBox, Gtk::PACK_EXPAND_WIDGET); trcProfVBox->pack_start(*fbw, 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); @@ -468,6 +473,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha wprimconn = wprim->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wprimChanged)); fbwconn = fbw->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::fbwChanged)); + gamutconn = gamut->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::gamutChanged)); obpcconn = obpc->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::oBPCChanged)); tcurveconn = ckbToneCurve->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::toneCurveChanged)); ltableconn = ckbApplyLookTable->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged)); @@ -513,6 +519,7 @@ void ICMPanel::neutral_pressed () wSlope->setValue(defPar.workingTRCSlope);//12.92 preser->setValue(defPar.preser); fbw->set_active(defPar.fbw); + gamut->set_active(defPar.gamut); wTRC->set_active(toUnderlying(ColorManagementParams::WorkingTrc::NONE));//reset to none will->set_active(toUnderlying(ColorManagementParams::Illuminant::DEFAULT));//reset to default - after wprim } @@ -765,6 +772,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker obpcconn_(obpcconn); ConnectionBlocker fbwconn_(fbwconn); + ConnectionBlocker gamutconn_(gamutconn); ConnectionBlocker ipc_(ipc); ConnectionBlocker tcurveconn_(tcurveconn); ConnectionBlocker ltableconn_(ltableconn); @@ -838,6 +846,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) obpc->set_active(pp->icm.outputBPC); fbw->set_active(pp->icm.fbw); + gamut->set_active(pp->icm.gamut); ckbToneCurve->set_active(pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; ckbApplyLookTable->set_active(pp->icm.applyLookTable); @@ -862,6 +871,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) iunchanged->set_active(!pedited->icm.inputProfile); obpc->set_inconsistent(!pedited->icm.outputBPC); fbw->set_inconsistent(!pedited->icm.fbw); + gamut->set_inconsistent(!pedited->icm.gamut); ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve); ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable); ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset); @@ -920,6 +930,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(false); wprim->set_sensitive(false); fbw->set_sensitive(false); + gamut->set_sensitive(false); wprimlab->set_sensitive(false); riaHBox->set_sensitive(false); redFrame->hide(); @@ -931,6 +942,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); @@ -973,6 +985,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -990,6 +1003,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1007,6 +1021,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); redFrame->show(); wGamma->set_sensitive(false); @@ -1025,6 +1040,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); riaHBox->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { @@ -1042,6 +1058,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1143,6 +1160,7 @@ 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.gamut = gamut->get_active(); pp->icm.workingTRCGamma = wGamma->getValue(); pp->icm.workingTRCSlope = wSlope->getValue(); pp->icm.redx = redx->getValue(); @@ -1162,6 +1180,7 @@ 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.gamut = !gamut->get_inconsistent(); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent(); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent(); @@ -1268,6 +1287,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(false); wprim->set_sensitive(false); fbw->set_sensitive(false); + gamut->set_sensitive(false); wprimlab->set_sensitive(false); redFrame->hide(); riaHBox->set_sensitive(false); @@ -1278,6 +1298,7 @@ void ICMPanel::wtrcinChanged() will->set_sensitive(false); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); willulab->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { @@ -1311,6 +1332,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1336,6 +1358,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); riaHBox->set_sensitive(true); @@ -1362,6 +1385,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1389,6 +1413,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1416,6 +1441,7 @@ void ICMPanel::wtrcinChanged() willulab->set_sensitive(true); wprim->set_sensitive(true); fbw->set_sensitive(true); + gamut->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -2023,6 +2049,33 @@ void ICMPanel::fbwChanged() } } +void ICMPanel::gamutChanged() +{ + if (multiImage) { + if (gamut->get_inconsistent()) { + gamut->set_inconsistent(false); + gamutconn.block(true); + gamut->set_active(false); + gamutconn.block(false); + } else if (lastgamut) { + gamut->set_inconsistent(true); + } + + lastgamut = gamut->get_active(); + } + + if (listener) { + if (gamut->get_inconsistent()) { + listener->panelChanged(EvICMgamut, M("GENERAL_UNCHANGED")); + } else if (fbw->get_active()) { + listener->panelChanged(EvICMgamut, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvICMgamut, M("GENERAL_DISABLED")); + } + } +} + + void ICMPanel::setRawMeta(bool raw, const rtengine::FramesData* pMeta) { diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 8d52fb25f..31ae6b664 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -81,6 +81,8 @@ protected: bool lastfbw; sigc::connection fbwconn; bool isBatchMode; + bool lastgamut; + sigc::connection gamutconn; private: rtengine::ProcEvent EvICMprimariMethod; @@ -107,6 +109,7 @@ private: rtengine::ProcEvent EvICMpreser; rtengine::ProcEvent EvICMLabGridciexy; rtengine::ProcEvent EvICMfbw; + rtengine::ProcEvent EvICMgamut; LabGrid *labgridcie; IdleRegister idle_register; @@ -121,6 +124,7 @@ private: Gtk::Box* iVBox; Gtk::Box* wTRCBox; Gtk::CheckButton* fbw; + Gtk::CheckButton* gamut; Gtk::CheckButton* obpc; Gtk::RadioButton* inone; @@ -196,6 +200,7 @@ public: void aiChanged(int n); void oBPCChanged(); void fbwChanged(); + void gamutChanged(); void ipChanged(); void ipSelectionChanged(); void dcpIlluminantChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 41b19edf2..acdda4e8a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -452,6 +452,7 @@ void ParamsEdited::set(bool v) icm.bluy = v; icm.preser = v; icm.fbw = v; + icm.gamut = v; icm.labgridcieALow = v; icm.labgridcieBLow = v; icm.labgridcieAHigh = v; @@ -1871,6 +1872,7 @@ void ParamsEdited::initFrom(const std::vector& icm.labgridcieWy = icm.labgridcieWy && p.icm.labgridcieWy == other.icm.labgridcieWy; icm.preser = icm.preser && p.icm.preser == other.icm.preser; icm.fbw = icm.fbw && p.icm.fbw == other.icm.fbw; + 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; @@ -6377,6 +6379,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.fbw = mods.icm.fbw; } + if (icm.gamut) { + toEdit.icm.gamut = mods.icm.gamut; + } + if (icm.labgridcieALow) { toEdit.icm.labgridcieALow = mods.icm.labgridcieALow; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 43b4e4e40..56d71cfa3 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1230,6 +1230,7 @@ struct ColorManagementParamsEdited { bool bluy; bool preser; bool fbw; + bool gamut; bool labgridcieALow; bool labgridcieBLow; bool labgridcieAHigh; From 311f3422fd25b8306a11186d866d902057fbccb2 Mon Sep 17 00:00:00 2001 From: Mattia Verga Date: Wed, 25 Jan 2023 14:16:19 +0100 Subject: [PATCH 167/326] Add missing include for GCC13 compatibility Signed-off-by: Mattia Verga --- rtengine/dcraw.h | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index e0a6cda92..aadc0b969 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -19,6 +19,7 @@ #pragma once +#include #include #include "myfile.h" From b1490e24c73dc06d3cb343fc910b75aa47bab35e Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 26 Jan 2023 05:03:37 -0800 Subject: [PATCH 168/326] Fix Windows build libsharpyuv-0.dll error (#6672) --- .github/workflows/windows.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f6f83f567..ab81edec6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -155,6 +155,7 @@ jobs: "libpixman-1-0.dll" \ "libpng16-16.dll" \ "librsvg-2-2.dll" \ + "libsharpyuv-0.dll" \ "libsigc-2.0-0.dll" \ "libstdc++-6.dll" \ "libsystre-0.dll" \ From 9a245c1acb9bbbe5dd82ee3a4da4dcddc8903f35 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 31 Jan 2023 12:32:31 +0100 Subject: [PATCH 169/326] Avoid Color shift - Gamut and Munsell Review in RT - branch Munsellgamut (#6673) * Fixed numerous problems with gamut and Munsell in Local adjustments * change gamut-munsell in lab adjustmnts - gamut in ciecam * Improve XYZ colorimetry and tooltip * Change event - format code - change labels tooltips * Removed avoid_ and avoidmun_ * Removed avoidcolorshift in labcurve * Push change proposed by Lawrence37 - compatibility with old pp3 --- rtdata/languages/default | 11 +- rtengine/improcfun.cc | 482 ++++++++++++++++++++++---------------- rtengine/improcfun.h | 2 +- rtengine/iplocallab.cc | 150 +++++++++--- rtengine/procevents.h | 6 +- rtengine/procparams.cc | 51 ++-- rtengine/procparams.h | 6 +- rtengine/refreshmap.cc | 3 +- rtgui/blackwhite.cc | 3 +- rtgui/controlspotpanel.cc | 145 ++++++------ rtgui/controlspotpanel.h | 19 +- rtgui/labcurve.cc | 465 ++++++++++++++++++++---------------- rtgui/labcurve.h | 9 +- rtgui/locallab.cc | 56 ++++- rtgui/paramsedited.cc | 30 +-- rtgui/paramsedited.h | 5 +- 16 files changed, 855 insertions(+), 588 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 8120419d2..0396b9d8d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1414,6 +1414,7 @@ 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_ICL_LABGRIDCIEXY;Cie xy @@ -1441,6 +1442,7 @@ 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_LOCAL_GAMUTMUNSEL;Local - Gamut-Munsell HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2608,8 +2610,6 @@ TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 TP_ICM_WORKING_TRC_TOOLTIP;Only for built-in profiles. TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction TP_IMPULSEDENOISE_THRESH;Threshold -TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). TP_LABCURVE_BRIGHTNESS;Lightness TP_LABCURVE_CHROMATICITY;Chromaticity TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. @@ -2674,7 +2674,7 @@ TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE 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 is used. +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 @@ -2904,6 +2904,11 @@ 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_GAMUTNON;None +TP_LOCALLAB_GAMUTLABRELA;Lab +TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute +TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative +TP_LOCALLAB_GAMUTMUNSELL;Munsell only TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) TP_LOCALLAB_GRADANG;Gradient angle TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 15ebcc2e6..0e08a28eb 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -54,7 +54,8 @@ #pragma GCC diagnostic warning "-Wextra" #pragma GCC diagnostic warning "-Wdouble-promotion" -namespace { +namespace +{ using namespace rtengine; @@ -218,32 +219,37 @@ void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH, } } -void customToneCurve(const ToneCurve &customToneCurve, ToneCurveMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState) { +void customToneCurve(const ToneCurve &customToneCurve, ToneCurveMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState) +{ if (curveMode == ToneCurveMode::STD) { // Standard - const StandardToneCurve& userToneCurve = static_cast (customToneCurve); + const StandardToneCurve& userToneCurve = static_cast(customToneCurve); + for (int i = istart, ti = 0; i < tH; i++, ti++) { userToneCurve.BatchApply(0, tW - jstart, &rtemp[ti * tileSize], >emp[ti * tileSize], &btemp[ti * tileSize]); } } else if (curveMode == ToneCurveMode::FILMLIKE) { // Adobe like - const AdobeToneCurve& userToneCurve = static_cast (customToneCurve); + const AdobeToneCurve& userToneCurve = static_cast(customToneCurve); + for (int i = istart, ti = 0; i < tH; i++, ti++) { userToneCurve.BatchApply(0, tW - jstart, &rtemp[ti * tileSize], >emp[ti * tileSize], &btemp[ti * tileSize]); } } else if (curveMode == ToneCurveMode::SATANDVALBLENDING) { // apply the curve on the saturation and value channels - const SatAndValueBlendingToneCurve& userToneCurve = static_cast (customToneCurve); + const SatAndValueBlendingToneCurve& userToneCurve = static_cast(customToneCurve); + for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]); } } } else if (curveMode == ToneCurveMode::WEIGHTEDSTD) { // apply the curve to the rgb channels, weighted - const WeightedStdToneCurve& userToneCurve = static_cast (customToneCurve); + const WeightedStdToneCurve& userToneCurve = static_cast(customToneCurve); + for (int i = istart, ti = 0; i < tH; i++, ti++) { userToneCurve.BatchApply(0, tW - jstart, &rtemp[ti * tileSize], >emp[ti * tileSize], &btemp[ti * tileSize]); } } else if (curveMode == ToneCurveMode::LUMINANCE) { // apply the curve to the luminance channel - const LuminanceToneCurve& userToneCurve = static_cast (customToneCurve); + const LuminanceToneCurve& userToneCurve = static_cast(customToneCurve); for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { @@ -251,7 +257,8 @@ void customToneCurve(const ToneCurve &customToneCurve, ToneCurveMode curveMode, } } } else if (curveMode == ToneCurveMode::PERCEPTUAL) { // apply curve while keeping color appearance constant - const PerceptualToneCurve& userToneCurve = static_cast (customToneCurve); + const PerceptualToneCurve& userToneCurve = static_cast(customToneCurve); + for (int i = istart, ti = 0; i < tH; i++, ti++) { userToneCurve.BatchApply(0, tW - jstart, &rtemp[ti * tileSize], >emp[ti * tileSize], &btemp[ti * tileSize], ptcApplyState); } @@ -277,7 +284,7 @@ namespace rtengine using namespace procparams; -ImProcFunctions::~ImProcFunctions () +ImProcFunctions::~ImProcFunctions() { if (monitorTransform) { cmsDeleteTransform(monitorTransform); @@ -307,7 +314,7 @@ void ImProcFunctions::updateColorProfiles(const Glib::ustring& monitorProfile, R #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB monitor = ICCStore::getInstance()->getProfile(monitorProfile); #else - monitor = ICCStore::getInstance()->getProfile (settings->srgb); + monitor = ICCStore::getInstance()->getProfile(settings->srgb); #endif } @@ -325,7 +332,7 @@ void ImProcFunctions::updateColorProfiles(const Glib::ustring& monitorProfile, R if (softProof) { cmsHPROFILE oprof = nullptr; RenderingIntent outIntent; - + flags = cmsFLAGS_SOFTPROOFING | cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE; if (!settings->printerProfile.empty()) { @@ -334,9 +341,11 @@ void ImProcFunctions::updateColorProfiles(const Glib::ustring& monitorProfile, R if (settings->printerBPC) { flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } + outIntent = RenderingIntent(settings->printerIntent); } else { oprof = ICCStore::getInstance()->getProfile(params->icm.outputProfile); + if (params->icm.outputBPC) { flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } @@ -352,20 +361,23 @@ void ImProcFunctions::updateColorProfiles(const Glib::ustring& monitorProfile, R // } const auto make_gamma_table = - [](cmsHPROFILE prof, cmsTagSignature tag) -> void + [](cmsHPROFILE prof, cmsTagSignature tag) -> void { + cmsToneCurve *tc = static_cast(cmsReadTag(prof, tag)); + + if (tc) { - cmsToneCurve *tc = static_cast(cmsReadTag(prof, tag)); - if (tc) { - const cmsUInt16Number *table = cmsGetToneCurveEstimatedTable(tc); - cmsToneCurve *tc16 = cmsBuildTabulatedToneCurve16(nullptr, cmsGetToneCurveEstimatedTableEntries(tc), table); - if (tc16) { - cmsWriteTag(prof, tag, tc16); - cmsFreeToneCurve(tc16); - } + const cmsUInt16Number *table = cmsGetToneCurveEstimatedTable(tc); + cmsToneCurve *tc16 = cmsBuildTabulatedToneCurve16(nullptr, cmsGetToneCurveEstimatedTableEntries(tc), table); + + if (tc16) { + cmsWriteTag(prof, tag, tc16); + cmsFreeToneCurve(tc16); } - }; + } + }; cmsHPROFILE softproof = ProfileContent(oprof).toProfile(); + if (softproof) { make_gamma_table(softproof, cmsSigRedTRCTag); make_gamma_table(softproof, cmsSigGreenTRCTag); @@ -439,7 +451,7 @@ void ImProcFunctions::updateColorProfiles(const Glib::ustring& monitorProfile, R void ImProcFunctions::firstAnalysis(const Imagefloat* const original, const ProcParams ¶ms, LUTu & histogram) { - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (params.icm.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params.icm.workingProfile); lumimul[0] = wprof[1][0]; lumimul[1] = wprof[1][1]; @@ -956,18 +968,20 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb float cz, wh, pfl; int c16 = 1; + if (params->colorappearance.modelmethod == "02") { c16 = 1; - }else if (params->colorappearance.modelmethod == "16") { + } else if (params->colorappearance.modelmethod == "16") { c16 = 16; - } //I don't use PQ here...hence no 21 + } //I don't use PQ here...hence no 21 + float plum = 100.f; - Ciecam02::initcam1float (yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c, c16, plum); + Ciecam02::initcam1float(yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c, c16, plum); //printf ("wh=%f \n", wh); const float pow1 = pow_F(1.64f - pow_F(0.29f, n), 0.73f); float nj, nbbj, ncbj, czj, awj, flj; - Ciecam02::initcam2float (yb2, pilotout, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj, czj, awj, flj, c16, plum); + Ciecam02::initcam2float(yb2, pilotout, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj, czj, awj, flj, c16, plum); #ifdef __SSE2__ const float reccmcz = 1.f / (c2 * czj); #endif @@ -1011,7 +1025,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb //matrix for current working space - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); const float wip[3][3] = { { (float)wiprof[0][0], (float)wiprof[0][1], (float)wiprof[0][2]}, { (float)wiprof[1][0], (float)wiprof[1][1], (float)wiprof[1][2]}, @@ -1084,7 +1098,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb Q, M, s, aw, fl, wh, x, y, z, xw1, yw1, zw1, - c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); + c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); Jbuffer[k] = J; Cbuffer[k] = C; hbuffer[k] = h; @@ -1122,7 +1136,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb Q, M, s, aw, fl, wh, x, y, z, xw1, yw1, zw1, - c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); + c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); #endif float Jpro, Cpro, hpro, Qpro, Mpro, spro; Jpro = J; @@ -1132,6 +1146,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb Mpro = M; spro = s; bool jp = false; + if ((hasColCurve1) && (curveMode == ColorAppearanceParams::TcMode::BRIGHT)) { jp = true; float Qq = Qpro * coefQ; @@ -1141,6 +1156,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb Qq = Qq / coefQ; Qpro = 0.2f * (Qq - Qold) + Qold; } + if ((hasColCurve2) && (curveMode2 == ColorAppearanceParams::TcMode::BRIGHT)) { jp = true; float Qq2 = Qpro * coefQ; @@ -1149,10 +1165,12 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb userColCurveB2.Apply(Qq2); Qq2 = Qq2 / coefQ; Qpro = 0.2f * (Qq2 - Qold2) + Qold2; - } - if(jp) { + } + + if (jp) { Jpro = SQR((10.f * Qpro) / wh); } + // we cannot have all algorithms with all chroma curves if (alg == 0) { Jpro = CAMBrightCurveJ[Jpro * 327.68f]; //lightness CIECAM02 + contrast @@ -1240,73 +1258,73 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb } if (hasColCurve1 && (curveMode == ColorAppearanceParams::TcMode::LIGHT)) { - float Jj = (float) Jpro * 327.68f; - float Jold = Jj; - float Jold100 = (float) Jpro; - float redu = 25.f; - float reduc = 1.f; - const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); - userColCurveJ1.Apply(Jj); + float Jj = (float) Jpro * 327.68f; + float Jold = Jj; + float Jold100 = (float) Jpro; + float redu = 25.f; + float reduc = 1.f; + const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); + userColCurveJ1.Apply(Jj); - if (Jj > Jold) { - if (Jj < 65535.f) { - if (Jold < 327.68f * redu) { - Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility - } else { - reduc = LIM((100.f - Jold100) / (100.f - redu), 0.f, 1.f); - Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights - } + if (Jj > Jold) { + if (Jj < 65535.f) { + if (Jold < 327.68f * redu) { + Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility + } else { + reduc = LIM((100.f - Jold100) / (100.f - redu), 0.f, 1.f); + Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights } - } else if (Jj > 10.f) { - Jj = 0.8f * (Jj - Jold) + Jold; - } else if (Jj >= 0.f) { - Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts } + } else if (Jj > 10.f) { + Jj = 0.8f * (Jj - Jold) + Jold; + } else if (Jj >= 0.f) { + Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts + } - Jpro = (float)(Jj / 327.68f); + Jpro = (float)(Jj / 327.68f); - if (Jpro < 1.f) { - Jpro = 1.f; - } + if (Jpro < 1.f) { + Jpro = 1.f; + } } - if (hasColCurve2 && (curveMode2 == ColorAppearanceParams::TcMode::LIGHT)) { - float Jj = (float) Jpro * 327.68f; - float Jold = Jj; - float Jold100 = (float) Jpro; - float redu = 25.f; - float reduc = 1.f; - const Lightcurve& userColCurveJ2 = static_cast(customColCurve2); - userColCurveJ2.Apply(Jj); + if (hasColCurve2 && (curveMode2 == ColorAppearanceParams::TcMode::LIGHT)) { + float Jj = (float) Jpro * 327.68f; + float Jold = Jj; + float Jold100 = (float) Jpro; + float redu = 25.f; + float reduc = 1.f; + const Lightcurve& userColCurveJ2 = static_cast(customColCurve2); + userColCurveJ2.Apply(Jj); - if (Jj > Jold) { - if (Jj < 65535.f) { - if (Jold < 327.68f * redu) { - Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility - } else { - reduc = LIM((100.f - Jold100) / (100.f - redu), 0.f, 1.f); - Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights - } - } - } else if (Jj > 10.f) { - if (!t1L) { - Jj = 0.8f * (Jj - Jold) + Jold; - } else { - Jj = 0.4f * (Jj - Jold) + Jold; - } - } else if (Jj >= 0.f) { - if (!t1L) { - Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts - } else { - Jj = 0.5f * (Jj - Jold) + Jold; + if (Jj > Jold) { + if (Jj < 65535.f) { + if (Jold < 327.68f * redu) { + Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility + } else { + reduc = LIM((100.f - Jold100) / (100.f - redu), 0.f, 1.f); + Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights } } - - Jpro = (float)(Jj / 327.68f); - - if (Jpro < 1.f) { - Jpro = 1.f; + } else if (Jj > 10.f) { + if (!t1L) { + Jj = 0.8f * (Jj - Jold) + Jold; + } else { + Jj = 0.4f * (Jj - Jold) + Jold; } + } else if (Jj >= 0.f) { + if (!t1L) { + Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts + } else { + Jj = 0.5f * (Jj - Jold) + Jold; + } + } + + Jpro = (float)(Jj / 327.68f); + + if (Jpro < 1.f) { + Jpro = 1.f; + } } if (hasColCurve3) {//curve 3 with chroma saturation colorfullness @@ -1456,47 +1474,33 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb #else float xx, yy, zz; //process normal==> viewing + TMatrix wprofc = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const double wpc[3][3] = {//improve precision with double + {wprofc[0][0], wprofc[0][1], wprofc[0][2]}, + {wprofc[1][0], wprofc[1][1], wprofc[1][2]}, + {wprofc[2][0], wprofc[2][1], wprofc[2][2]} + }; Ciecam02::jch2xyz_ciecam02float(xx, yy, zz, J, C, h, xw2, yw2, zw2, - c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); + c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); float x, y, z; x = xx * 655.35f; y = yy * 655.35f; z = zz * 655.35f; float Ll, aa, bb; + //convert xyz=>lab - Color::XYZ2Lab(x, y, z, Ll, aa, bb); - - // gamut control in Lab mode; I must study how to do with cIECAM only if (gamu == 1) { - float Lprov1, Chprov1; - Lprov1 = Ll / 327.68f; - Chprov1 = sqrtf(SQR(aa) + SQR(bb)) / 327.68f; - float2 sincosval; - - if (Chprov1 == 0.0f) { - sincosval.y = 1.f; - sincosval.x = 0.0f; - } else { - sincosval.y = aa / (Chprov1 * 327.68f); - sincosval.x = bb / (Chprov1 * 327.68f); - } - - - //gamut control : Lab values are in gamut - Color::gamutLchonly(sincosval, Lprov1, Chprov1, wip, highlight, 0.15f, 0.96f); - lab->L[i][j] = Lprov1 * 327.68f; - lab->a[i][j] = 327.68f * Chprov1 * sincosval.y; - lab->b[i][j] = 327.68f * Chprov1 * sincosval.x; - - } else { - lab->L[i][j] = Ll; - lab->a[i][j] = aa; - lab->b[i][j] = bb; + Color::gamutmap(x, y, z, wpc); } + Color::XYZ2Lab(x, y, z, Ll, aa, bb); + lab->L[i][j] = Ll; + lab->a[i][j] = aa; + lab->b[i][j] = bb; + #endif } } @@ -1592,7 +1596,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb if (params->defringe.enabled) if (execsharp) { lab->deleteLab(); - defringecam (ncie);//defringe adapted to CIECAM + defringecam(ncie); //defringe adapted to CIECAM lab->reallocLab(); } @@ -1603,7 +1607,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb const bool hotbad = params->dirpyrequalizer.skinprotect != 0.0; lab->deleteLab(); - badpixcam (ncie, artifact / scale, 5, 2, chrom, hotbad); //enabled remove artifacts for cbDL + badpixcam(ncie, artifact / scale, 5, 2, chrom, hotbad); //enabled remove artifacts for cbDL lab->reallocLab(); } @@ -1611,7 +1615,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb if (params->colorappearance.badpixsl > 0 && execsharp) { int mode = params->colorappearance.badpixsl; lab->deleteLab(); - badpixcam (ncie, 3.0, 10, mode, 0, true);//for bad pixels CIECAM + badpixcam(ncie, 3.0, 10, mode, 0, true); //for bad pixels CIECAM lab->reallocLab(); } @@ -1620,17 +1624,17 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb buffers[0] = lab->L; buffers[1] = lab->a; buffers[2] = lab->b; - impulsedenoisecam (ncie, buffers); //impulse adapted to CIECAM + impulsedenoisecam(ncie, buffers); //impulse adapted to CIECAM } if (params->sharpenMicro.enabled)if (execsharp) { - MLmicrocontrastcam (ncie); + MLmicrocontrastcam(ncie); } if (params->sharpening.enabled) if (execsharp) { float **buffer = lab->L; // We can use the L-buffer from lab as buffer to save some memory - sharpeningcam (ncie, buffer, showSharpMask); // sharpening adapted to CIECAM + sharpeningcam(ncie, buffer, showSharpMask); // sharpening adapted to CIECAM } //if(params->dirpyrequalizer.enabled) if(execsharp) { @@ -1643,7 +1647,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb float t_l = static_cast(params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f; float t_r = static_cast(params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f; lab->deleteLab(); - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM lab->reallocLab(); } @@ -1666,6 +1670,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb #ifdef _OPENMP #pragma omp for schedule(dynamic, 10) #endif + for (int i = 0; i < height; i++) // update CieImages with new values after sharpening, defringe, contrast by detail level for (int j = 0; j < width; j++) { float interm = fabsf(ncie->sh_p[i][j] / (32768.f)); @@ -1685,7 +1690,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb if (epdEnabled && params->colorappearance.tonecie && algepd) { lab->deleteLab(); - EPDToneMapCIE (ncie, a_w, c_, width, height, minQ, maxQ, Iterates, scale ); + EPDToneMapCIE(ncie, a_w, c_, width, height, minQ, maxQ, Iterates, scale); lab->reallocLab(); } @@ -1769,7 +1774,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb Ciecam02::jch2xyz_ciecam02float(xx, yy, zz, ncie->J_p[i][j], ncie_C_p, ncie->h_p[i][j], xw2, yw2, zw2, - c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); + c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); float x = (float)xx * 655.35f; float y = (float)yy * 655.35f; float z = (float)zz * 655.35f; @@ -1894,7 +1899,7 @@ void ImProcFunctions::moyeqt(Imagefloat* working, float &moyS, float &eqty) for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { - const double s = Color::rgb2s(CLIP(working->r (i, j)), CLIP(working->g (i, j)), CLIP(working->b (i, j))); + const double s = Color::rgb2s(CLIP(working->r(i, j)), CLIP(working->g(i, j)), CLIP(working->b(i, j))); moy += s; sqrs += SQR(s); } @@ -1946,12 +1951,12 @@ filmlike_clip(float *r, float *g, float *b) } } -void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, - int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, - const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, - const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, - double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, - LUTu& histToneCurve, size_t chunkSize, bool measure) +void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, + const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, + const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, + LUTu& histToneCurve, size_t chunkSize, bool measure) { rgbProc(working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, @@ -1959,12 +1964,12 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } // Process RGB image and convert to LAB space -void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, - int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, - const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, - const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, - double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, - DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) +void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, + int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, + const ColorGradientCurve& ctColorCurve, const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clToningcurve, const LUTf& cl2Toningcurve, + const ToneCurve& customToneCurve1, const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, + double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, + DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize, bool measure) { std::unique_ptr stop; @@ -1995,8 +2000,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } } - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (params->icm.workingProfile); - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); float toxyz[3][3] = { { @@ -2150,13 +2155,13 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer PerceptualToneCurveState ptc1ApplyState, ptc2ApplyState; if (hasToneCurve1 && curveMode == ToneCurveMode::PERCEPTUAL) { - const PerceptualToneCurve& userToneCurve = static_cast (customToneCurve1); - userToneCurve.initApplyState (ptc1ApplyState, params->icm.workingProfile); + const PerceptualToneCurve& userToneCurve = static_cast(customToneCurve1); + userToneCurve.initApplyState(ptc1ApplyState, params->icm.workingProfile); } if (hasToneCurve2 && curveMode2 == ToneCurveMode::PERCEPTUAL) { - const PerceptualToneCurve& userToneCurve = static_cast (customToneCurve2); - userToneCurve.initApplyState (ptc2ApplyState, params->icm.workingProfile); + const PerceptualToneCurve& userToneCurve = static_cast(customToneCurve2); + userToneCurve.initApplyState(ptc2ApplyState, params->icm.workingProfile); } bool hasColorToning = params->colorToning.enabled && bool (ctOpacityCurve) && bool (ctColorCurve) && params->colorToning.method != "LabGrid"; @@ -2351,6 +2356,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } highlightToneCurve(hltonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS, exp_scale, comp, hlrange); + if (params->toneCurve.black != 0.0) { shadowToneCurve(shtonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS); } @@ -2402,7 +2408,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float tmpg[4] ALIGNED16; float tmpb[4] ALIGNED16; - for (; j < tW - 3; j+=4, tj+=4) { + for (; j < tW - 3; j += 4, tj += 4) { //brightness/contrast STVF(tmpr[0], tonecurve(LVF(rtemp[ti * TS + tj]))); STVF(tmpg[0], tonecurve(LVF(gtemp[ti * TS + tj]))); @@ -2683,6 +2689,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer else if (params->colorToning.method == "Splitco") { constexpr float reducac = 0.3f; constexpr int mode = 0; + for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { const float r = rtemp[ti * TS + tj]; @@ -3113,9 +3120,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer Color::RGB2Lab(&rtemp[ti * TS], >emp[ti * TS], &btemp[ti * TS], &(lab->L[i][jstart]), &(lab->a[i][jstart]), &(lab->b[i][jstart]), toxyz, tW - jstart); } - // if (hasColorToningLabGrid) { - // colorToningLabGrid(lab, jstart, tW, istart, tH, false); - // } + // if (hasColorToningLabGrid) { + // colorToningLabGrid(lab, jstart, tW, istart, tH, false); + // } } else { // black & white // Auto channel mixer needs whole image, so we now copy to tmpImage and close the tiled processing for (int i = istart, ti = 0; i < tH; i++, ti++) { @@ -3494,9 +3501,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { Color::RGB2Lab(tmpImage->r(i), tmpImage->g(i), tmpImage->b(i), lab->L[i], lab->a[i], lab->b[i], toxyz, tW); - // if (hasColorToningLabGrid) { - // colorToningLabGrid(lab, 0, tW, i, i + 1, false); - // } + // if (hasColorToningLabGrid) { + // colorToningLabGrid(lab, 0, tW, i, i + 1, false); + // } } @@ -3511,7 +3518,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } if (sCurveEnabled) { - delete sCurve; + delete sCurve; } if (vCurveEnabled) { @@ -3955,7 +3962,7 @@ void ImProcFunctions::toning2col(float r, float g, float b, float &ro, float &go * @param iplow iphigh [0..1] luminance * @param wp wip 3x3 matrix and inverse conversion rgb XYZ **/ -void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3] ) +void ImProcFunctions::labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]) { ro = CLIP(r); go = CLIP(g); @@ -4014,7 +4021,7 @@ void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go } -void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, const LUTf& curve) +void ImProcFunctions::luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf& curve) { int W = lold->W; @@ -4034,7 +4041,7 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, const LUTf -void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, const LUTf& acurve, const LUTf& bcurve, const LUTf& satcurve, const LUTf& lhskcurve, const LUTf& clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve) +void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, const LUTf& acurve, const LUTf& bcurve, const LUTf& satcurve, const LUTf& lhskcurve, const LUTf& clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve) { int W = lold->W; int H = lold->H; @@ -4069,7 +4076,8 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW // !params->labCurve.enabled. It is ugly, but it's the smallest code // change that I could find //------------------------------------------------------------------------- - class TempParams { + class TempParams + { const ProcParams **p_; const ProcParams *old_; ProcParams tmp_; @@ -4091,11 +4099,13 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW bool pipette_for_colortoning_labregions = editPipette && params->colorToning.enabled && params->colorToning.method == "LabRegions"; + if (!params->labCurve.enabled && pipette_for_colortoning_labregions) { utili = autili = butili = ccutili = cclutili = clcutili = false; tempparams.reset(new TempParams(¶ms)); curve.makeIdentity(); } + //------------------------------------------------------------------------- @@ -4104,6 +4114,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW // fill pipette buffer with zeros to avoid crashes editWhatever->fill(0.f); } + if (params->blackwhite.enabled && !params->colorToning.enabled) { for (int i = 0; i < lnew->H; ++i) { for (int j = 0; j < lnew->W; ++j) { @@ -4111,6 +4122,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW } } } + return; } @@ -4172,7 +4184,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW // if(params->labCurve.avoidclip ){ // parameter to adapt curve C=f(C) to gamut - if (params->icm.workingProfile == "ProPhoto") { + if (params->icm.workingProfile == "ProPhoto") { adjustr = 1.2f; // 1.2 instead 1.0 because it's very rare to have C>170.. } else if (params->icm.workingProfile == "Adobe RGB") { adjustr = 1.8f; @@ -4203,7 +4215,22 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW const bool clut = clcutili; const double rstprotection = 100. - params->labCurve.rstprotection; // Red and Skin Tones Protection // avoid color shift is disabled when bwToning is activated and enabled if gamut is true in colorappearanace - const bool avoidColorShift = (params->labCurve.avoidcolorshift || (params->colorappearance.gamut && params->colorappearance.enabled)) && !bwToning ; + // const bool avoidColorShift = (params->labCurve.avoidcolorshift || (params->colorappearance.gamut && params->colorappearance.enabled)) && !bwToning ; + //const bool avoidColorS = params->labCurve.avoidcolorshift; + int gamutmuns = 0; + + if (params->labCurve.gamutmunselmethod == "NONE") { + gamutmuns = 0; + } else if (params->labCurve.gamutmunselmethod == "LAB") { + gamutmuns = 1; + } else if (params->labCurve.gamutmunselmethod == "XYZ") { + gamutmuns = 2; + } else if (params->labCurve.gamutmunselmethod == "XYZREL") { + gamutmuns = 3; + } else if (params->labCurve.gamutmunselmethod == "MUN") { + gamutmuns = 4; + } + const float protectRed = (float)settings->protectred; const double protectRedH = settings->protectredh; const float protect_red = rtengine::LIM(protectRed, 20.f, 180.f); //default=60 chroma: one can put more or less if necessary...in 'option' 40...160 @@ -4228,17 +4255,17 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW const float scaleConst = 100.0f / 100.1f; - const bool gamutLch = settings->gamutLch; + //const bool gamutLch = settings->gamutLch; const float amountchroma = (float) settings->amchroma; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); const double wip[3][3] = { {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, {wiprof[2][0], wiprof[2][1], wiprof[2][2]} }; - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (params->icm.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); const double wp[3][3] = { {wprof[0][0], wprof[0][1], wprof[0][2]}, {wprof[1][0], wprof[1][1], wprof[1][2]}, @@ -4258,12 +4285,12 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW #endif for (int i = 0; i < H; i++) { - if (avoidColorShift) + // if (avoidColorShift) - // only if user activate Lab adjustments - if (autili || butili || ccutili || cclutili || chutili || lhutili || hhutili || clcutili || utili || chromaticity) { - Color::LabGamutMunsell(lold->L[i], lold->a[i], lold->b[i], W, /*corMunsell*/true, /*lumaMuns*/false, params->toneCurve.hrenabled, /*gamut*/true, wip); - } + // only if user activate Lab adjustments + // if (autili || butili || ccutili || cclutili || chutili || lhutili || hhutili || clcutili || utili || chromaticity) { + // Color::LabGamutMunsell(lold->L[i], lold->a[i], lold->b[i], W, /*corMunsell*/true, /*lumaMuns*/false, params->toneCurve.hrenabled, /*gamut*/true, wip); + // } #ifdef __SSE2__ @@ -4277,7 +4304,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW av = LVFU(lold->a[i][k]); bv = LVFU(lold->b[i][k]); STVF(HHBuffer[k], xatan2f(bv, av)); - STVF (CCBuffer[k], vsqrtf (SQRV (av) + SQRV (bv)) / c327d68v); + STVF(CCBuffer[k], vsqrtf(SQRV(av) + SQRV(bv)) / c327d68v); } for (; k < W; k++) { @@ -4431,8 +4458,8 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW float fx = (0.002f * aprov1) + fy; float fz = fy - (0.005f * bprov1); - float x_ = 65535.f * Color::f2xyz (fx) * Color::D50x; - float z_ = 65535.f * Color::f2xyz (fz) * Color::D50z; + float x_ = 65535.f * Color::f2xyz(fx) * Color::D50x; + float z_ = 65535.f * Color::f2xyz(fz) * Color::D50z; float y_ = Lprov1 > Color::epskapf ? 65535.f * fy * fy * fy : 65535.f * Lprov1 / Color::kappaf; float R, G, B; Color::xyz2rgb(x_, y_, z_, R, G, B, wip); @@ -4704,24 +4731,57 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW btmp -= lold->b[i][j]; } - if (avoidColorShift) { - //gamutmap Lch ==> preserve Hue,but a little slower than gamutbdy for high values...and little faster for low values - if (gamutLch) { - float R, G, B; - //gamut control : Lab values are in gamut - Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); - lnew->L[i][j] = Lprov1 * 327.68f; - lnew->a[i][j] = 327.68f * Chprov1 * sincosval.y; - lnew->b[i][j] = 327.68f * Chprov1 * sincosval.x; - } else { - //use gamutbdy - //Luv limiter - float Y, u, v; - Color::Lab2Yuv(lnew->L[i][j], atmp, btmp, Y, u, v); - //Yuv2Lab includes gamut restriction map - Color::Yuv2Lab(Y, u, v, lnew->L[i][j], lnew->a[i][j], lnew->b[i][j], wp); + lnew->L[i][j] = Lprov1 * 327.68f; + lnew->a[i][j] = 327.68f * Chprov1 * sincosval.y; + lnew->b[i][j] = 327.68f * Chprov1 * sincosval.x; + + //gamutmap Lch ==> preserve Hue,but a little slower than gamutbdy for high values...and little faster for low values + if (gamutmuns == 1) { + float R, G, B; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); + lnew->L[i][j] = Lprov1 * 327.68f; + lnew->a[i][j] = 327.68f * Chprov1 * sincosval.y; + lnew->b[i][j] = 327.68f * Chprov1 * sincosval.x; + } + + if (gamutmuns == 2 || gamutmuns == 3) { + + float xg, yg, zg; + Color::Lab2XYZ(lnew->L[i][j], atmp, btmp, xg, yg, zg); + float x0 = xg; + float y0 = yg; + float z0 = zg; + + Color::gamutmap(xg, yg, zg, wp); + + if (gamutmuns == 3) {//0.5f arbitrary coeff + xg = xg + 0.5f * (x0 - xg); + yg = yg + 0.5f * (y0 - yg); + zg = zg + 0.5f * (z0 - zg); } + float Lag, aag2, bbg2; + Color::XYZ2Lab(xg, yg, zg, Lag, aag2, bbg2); + Lprov1 = Lag / 327.68f; + HH = xatan2f(bbg2, aag2); + Chprov1 = std::sqrt(SQR(aag2) + SQR(bbg2)) / 327.68f; + + if (Chprov1 == 0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aag2 / (Chprov1 * 327.68f); + sincosval.x = bbg2 / (Chprov1 * 327.68f); + } + + lnew->L[i][j] = Lprov1 * 327.68f; + lnew->a[i][j] = 327.68f * Chprov1 * sincosval.y; + lnew->b[i][j] = 327.68f * Chprov1 * sincosval.x; + + } + + if (gamutmuns > 0) { if (utili || autili || butili || ccut || clut || cclutili || chutili || lhutili || hhutili || clcutili || chromaticity) { float correctionHue = 0.f; // Munsell's correction float correctlum = 0.f; @@ -4747,7 +4807,10 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW lnew->a[i][j] = 327.68f * Chprov * sincosval.y; // apply Munsell lnew->b[i][j] = 327.68f * Chprov * sincosval.x; } - } else { + } + + if (gamutmuns == 0) { + // if(Lprov1 > maxlp) maxlp=Lprov1; // if(Lprov1 < minlp) minlp=Lprov1; if (!bwToning) { @@ -4940,11 +5003,12 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid if (!params->epd.enabled) { return; } -/* - if (params->wavelet.enabled && params->wavelet.tmrs != 0) { - return; - } -*/ + + /* + if (params->wavelet.enabled && params->wavelet.tmrs != 0) { + return; + } + */ float stren = params->epd.strength; const float edgest = std::min(params->epd.edgeStopping, params->localContrast.enabled ? 3.0 : 4.0); float sca = params->epd.scale; @@ -4954,7 +5018,7 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid float *Qpr = ncie->Q_p[0]; if (settings->verbose) { - printf ("minQ=%f maxQ=%f Qpro=%f\n", static_cast(minQ), static_cast(maxQ), static_cast(Qpro)); + printf("minQ=%f maxQ=%f Qpro=%f\n", static_cast(minQ), static_cast(maxQ), static_cast(Qpro)); } if (maxQ > Qpro) { @@ -4993,6 +5057,7 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,10) #endif + for (int i = 0; i < Hei; i++) for (int j = 0; j < Wid; j++) { ncie->Q_p[i][j] = (ncie->Q_p[i][j] * Qpro) / gamm; @@ -5043,7 +5108,7 @@ void ImProcFunctions::EPDToneMaplocal(int sp, LabImage *lab, LabImage *tmp1, uns float stren = ((float)params->locallab.spots.at(sp).stren); const float edgest = std::min(params->locallab.spots.at(sp).estop, params->localContrast.enabled ? 3.0 : 4.0); - + float sca = ((float)params->locallab.spots.at(sp).scaltm); float gamm = ((float)params->locallab.spots.at(sp).gamma); float satur = ((float)params->locallab.spots.at(sp).satur) / 100.f; @@ -5064,6 +5129,7 @@ void ImProcFunctions::EPDToneMaplocal(int sp, LabImage *lab, LabImage *tmp1, uns #ifdef _OPENMP #pragma omp parallel for reduction(max:maxL) reduction(min:minL) schedule(dynamic,16) #endif + for (std::size_t i = 0; i < N; i++) { minL = rtengine::min(minL, L[i]); maxL = rtengine::max(maxL, L[i]); @@ -5081,8 +5147,8 @@ void ImProcFunctions::EPDToneMaplocal(int sp, LabImage *lab, LabImage *tmp1, uns #ifdef _OPENMP #pragma omp parallel for #endif - for (std::size_t i = 0; i < N; i++) - { + + for (std::size_t i = 0; i < N; i++) { L[i] = (L[i] - minL) * mult; } @@ -5111,8 +5177,12 @@ void ImProcFunctions::EPDToneMaplocal(int sp, LabImage *lab, LabImage *tmp1, uns //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. float s = (1.0f + 38.7889f) * powf(Compression, 1.5856f) / (1.0f + 38.7889f * powf(Compression, 1.5856f)); float sat = s + 0.3f * s * satur; + //printf("s=%f sat=%f \n", s, sat); - if(sat == 1.f) sat = 1.001f; + if (sat == 1.f) { + sat = 1.001f; + } + #ifdef _OPENMP #pragma omp parallel for // removed schedule(dynamic,10) #endif @@ -5159,6 +5229,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) #ifdef _OPENMP #pragma omp parallel for reduction(min:minL) reduction(max:maxL) #endif + for (size_t i = 1; i < N; i++) { minL = std::min(minL, L[i]); maxL = std::max(maxL, L[i]); @@ -5173,6 +5244,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) #ifdef _OPENMP #pragma omp parallel for #endif + for (size_t i = 0; i < N; ++i) { L[i] = (L[i] - minL) * (gamm / maxL); } @@ -5186,7 +5258,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) Iterates = edgest * 15.f; } - epd.CompressDynamicRange (L, sca / skip, edgest, Compression, DetailBoost, Iterates, rew); + epd.CompressDynamicRange(L, sca / skip, edgest, Compression, DetailBoost, Iterates, rew); //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. const float s = (1.f + 38.7889f) * std::pow(Compression, 1.5856f) / (1.f + 38.7889f * std::pow(Compression, 1.5856f)); @@ -5195,6 +5267,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) #ifdef _OPENMP #pragma omp parallel for #endif + for (size_t ii = 0; ii < N; ++ii) { a[ii] *= s; b[ii] *= s; @@ -5242,7 +5315,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl int j = 0; - for (; j < min ((int)ave, imax); ++j) { + for (; j < min((int)ave, imax); ++j) { if (count < 8) { octile[count] += histogram[j]; @@ -5335,7 +5408,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl } //compute clipped white point - unsigned int clippable = (int) (static_cast(sum) * clip / 100.0 ); + unsigned int clippable = (int)(static_cast(sum) * clip / 100.0); clipped = 0; int whiteclip = (imax) - 1; @@ -5414,7 +5487,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl contr = (int) 50.0f * (1.1f - ospread); contr = max(0, min(100, contr)); //take gamma into account - double whiteclipg = (int) (CurveFactory::gamma2(whiteclip * static_cast(corr) / 65536.0) * 65536.0); + double whiteclipg = (int)(CurveFactory::gamma2(whiteclip * static_cast(corr) / 65536.0) * 65536.0); float gavg = 0.; @@ -5594,7 +5667,8 @@ void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib:: } void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings) const -{ // Adapted from ImProcFunctions::lab2rgb +{ + // Adapted from ImProcFunctions::lab2rgb const int src_width = src.getWidth(); const int src_height = src.getHeight(); @@ -5626,6 +5700,7 @@ void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, flo if (icm.outputProfile.empty() || icm.outputProfile == ColorManagementParams::NoICMString) { profile = "sRGB"; } + oprof = ICCStore::getInstance()->getProfile(profile); } @@ -5638,7 +5713,7 @@ void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, flo lcmsMutex->lock(); cmsHPROFILE LabIProf = cmsCreateLab4Profile(nullptr); - cmsHTRANSFORM hTransform = cmsCreateTransform (oprof, TYPE_RGB_8, LabIProf, TYPE_Lab_FLT, icm.outputIntent, flags); + cmsHTRANSFORM hTransform = cmsCreateTransform(oprof, TYPE_RGB_8, LabIProf, TYPE_Lab_FLT, icm.outputIntent, flags); cmsCloseProfile(LabIProf); lcmsMutex->unlock(); @@ -5662,7 +5737,7 @@ void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, flo float* ra = a + (i - y) * w; float* rb = b + (i - y) * w; - cmsDoTransform (hTransform, src.data + ix, outbuffer, w); + cmsDoTransform(hTransform, src.data + ix, outbuffer, w); for (int j = 0; j < w; j++) { rL[j] = outbuffer[iy++] * 327.68f; @@ -5691,6 +5766,7 @@ void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, flo for (int i = y; i < y2; i++) { int offset = (i - y) * w; + for (int j = x; j < x2; j++) { float X, Y, Z; // lab2rgb uses gamma2curve, which is gammatab_srgb. @@ -5782,7 +5858,7 @@ void ImProcFunctions::colorToningLabGrid(LabImage *lab, int xstart, int xend, in float b_scale = (params->colorToning.labgridBHigh - params->colorToning.labgridBLow) / factor / scaling; float b_base = params->colorToning.labgridBLow / scaling; - #ifdef _OPENMP +#ifdef _OPENMP #pragma omp parallel for if (MultiThread) #endif diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 1be1d0371..36c571291 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -257,7 +257,7 @@ enum class BlurType { int shortcu, bool delt, const float hueref, const float chromaref, const float lumaref, float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, bool fftt, float blu_ma, float cont_ma, int indic, float &fab); - void avoidcolshi(const struct local_params& lp, int sp, LabImage * original, LabImage *transformed, int cy, int cx, int sk); + void avoidcolshi(const struct local_params& lp, int sp, LabImage *transformed, LabImage *reserved, int cy, int cx, int sk); void deltaEforMask(float **rdE, int bfw, int bfh, LabImage* bufcolorig, const float hueref, const float chromaref, const float lumaref, float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, float balance, float balanceh); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 62f211ae6..bdc1b6db1 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -12540,12 +12540,31 @@ void ImProcFunctions::clarimerge(const struct local_params& lp, float &mL, float } } -void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImage * original, LabImage *transformed, int cy, int cx, int sk) +void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImage *transformed, LabImage *reserved, int cy, int cx, int sk) { - if (params->locallab.spots.at(sp).avoid && lp.islocal) { + int avoidgamut = 0; + + if (params->locallab.spots.at(sp).avoidgamutMethod == "NONE") { + avoidgamut = 0; + } else if (params->locallab.spots.at(sp).avoidgamutMethod == "LAB") { + avoidgamut = 1; + } else if (params->locallab.spots.at(sp).avoidgamutMethod == "XYZ") { + avoidgamut = 2; + } else if (params->locallab.spots.at(sp).avoidgamutMethod == "XYZREL") { + avoidgamut = 3; + } else if (params->locallab.spots.at(sp).avoidgamutMethod == "MUNS") { + avoidgamut = 4; + } + + if (avoidgamut == 0) { + return; + } + + if (avoidgamut > 0 && lp.islocal) { 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 == "all" || params->locallab.spots.at(sp).modecam == "jz" || params->locallab.spots.at(sp).modecam == "cam16")) { execmunsell = false; } @@ -12556,11 +12575,18 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag {wiprof[2][0], wiprof[2][1], wiprof[2][2]} }; + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const double wp[3][3] = {//improve precision with double + {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]} + }; + const float softr = params->locallab.spots.at(sp).avoidrad;//max softr = 30 - const bool muns = params->locallab.spots.at(sp).avoidmun;//Munsell control with 200 LUT + // const bool muns = params->locallab.spots.at(sp).avoidmun;//Munsell control with 200 LUT //improve precision with mint and maxt const float tr = std::min(2.f, softr); - const float mint = 0.15f - 0.06f * tr;//between 0.15f and 0.03f + const float mint = 0.15f - 0.06f * tr;//between 0.15f and 0.03f const float maxt = 0.98f + 0.008f * tr;//between 0.98f and 0.996f const bool highlight = params->toneCurve.hrenabled; @@ -12581,6 +12607,7 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag #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 @@ -12640,7 +12667,7 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag 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); } @@ -12675,42 +12702,103 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag sincosval.y = aa / (Chprov1 * 327.68f); sincosval.x = bb / (Chprov1 * 327.68f); } + #endif + float lnew = transformed->L[y][x]; + float anew = transformed->a[y][x]; + float bnew = transformed->b[y][x]; + Lprov1 = lnew / 327.68f; + //HH = xatan2f(bnew, anew); - Color::pregamutlab(Lprov1, HH, chr); - Chprov1 = rtengine::min(Chprov1, chr); - if(!muns) { - float R, G, B; + if (avoidgamut == 1) { //Lab correction + + Color::pregamutlab(Lprov1, HH, chr); + Chprov1 = rtengine::min(Chprov1, chr); + + float R, G, B; Color::gamutLchonly(HH, sincosval, Lprov1, Chprov1, R, G, B, wip, highlight, mint, maxt);//replace for best results - } - transformed->L[y][x] = Lprov1 * 327.68f; - transformed->a[y][x] = 327.68f * Chprov1 * sincosval.y; - transformed->b[y][x] = 327.68f * Chprov1 * sincosval.x; + lnew = Lprov1 * 327.68f; + anew = 327.68f * Chprov1 * sincosval.y; + bnew = 327.68f * Chprov1 * sincosval.x; + //HH = xatan2f(bnew, anew); + transformed->a[y][x] = anew; + transformed->b[y][x] = bnew; - if (needHH) { - const float Lprov2 = original->L[y][x] / 327.68f; + } else if (avoidgamut == 2 || avoidgamut == 3) { //XYZ correction + float xg, yg, zg; + const float aag = transformed->a[y][x];//anew + const float bbg = transformed->b[y][x];//bnew + float Lag = transformed->L[y][x]; + + Color::Lab2XYZ(Lag, aag, bbg, xg, yg, zg); + float x0 = xg; + float y0 = yg; + float z0 = zg; + + 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); + } + + //Color::gamutmap(xg, yg, zg, wp);//Put XYZ in gamut wp + float aag2, bbg2; + Color::XYZ2Lab(xg, yg, zg, Lag, aag2, bbg2); + Lprov1 = Lag / 327.68f; + HH = xatan2f(bbg2, aag2);//rebuild HH in case of...absolute colorimetry + Chprov1 = std::sqrt(SQR(aag2) + SQR(bbg2)) / 327.68f; + + if (Chprov1 == 0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aag2 / (Chprov1 * 327.68f); + sincosval.x = bbg2 / (Chprov1 * 327.68f); + } + + lnew = Lprov1 * 327.68f; + anew = 327.68f * Chprov1 * sincosval.y; + bnew = 327.68f * Chprov1 * sincosval.x; + transformed->a[y][x] = anew; + transformed->b[y][x] = bnew; + + } + + if (needHH && avoidgamut <= 4) {//Munsell + Lprov1 = lnew / 327.68f; + float Chprov = sqrt(SQR(anew) + SQR(bnew)) / 327.68f; + + const float Lprov2 = reserved->L[y][x] / 327.68f; float correctionHue = 0.f; // Munsell's correction float correctlum = 0.f; - const float memChprov = std::sqrt(SQR(original->a[y][x]) + SQR(original->b[y][x])) / 327.68f; - float Chprov = std::sqrt(SQR(transformed->a[y][x]) + SQR(transformed->b[y][x])) / 327.68f; - if(execmunsell) { + 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); } - if (std::fabs(correctionHue) < 0.015f) { - HH += correctlum; // correct only if correct Munsell chroma very small. + if (correctionHue != 0.f || correctlum != 0.f) { + + if (std::fabs(correctionHue) < 0.015f) { + HH += correctlum; // correct only if correct Munsell chroma very small. + } + + sincosval = xsincosf(HH + correctionHue); } - sincosval = xsincosf(HH + correctionHue); - transformed->a[y][x] = 327.68f * Chprov * sincosval.y; // apply Munsell - transformed->b[y][x] = 327.68f * Chprov * sincosval.x; + anew = 327.68f * Chprov * sincosval.y; // apply Munsell + bnew = 327.68f * Chprov * sincosval.x; + transformed->a[y][x] = anew; // apply Munsell + transformed->b[y][x] = bnew; } } } } - //Guidedfilter to reduce artifacts in transitions - if (softr != 0.f) {//soft for L a b because we change color... + //Guidedfilter to reduce artifacts in transitions : case Lab + if (softr != 0.f && avoidgamut == 1) {//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(6 / sk * tmpblur + 0.5f, 1); const int r2 = rtengine::max(10 / sk * tmpblur + 0.5f, 1); @@ -12734,13 +12822,15 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag for (int y = 0; y < bh ; y++) { for (int x = 0; x < bw; x++) { ble[y][x] = transformed->L[y][x] / 32768.f; - guid[y][x] = original->L[y][x] / 32768.f; + guid[y][x] = reserved->L[y][x] / 32768.f; } } + rtengine::guidedFilter(guid, ble, ble, r2, 0.2f * epsil, multiThread); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bh; y++) { for (int x = 0; x < bw; x++) { transformed->L[y][x] = 32768.f * ble[y][x]; @@ -12757,11 +12847,13 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag blechro[y][x] = std::sqrt(SQR(transformed->b[y][x]) + SQR(transformed->a[y][x])) / 32768.f; } } + rtengine::guidedFilter(guid, blechro, blechro, r1, epsil, multiThread); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bh; y++) { for (int x = 0; x < bw; x++) { const float Chprov1 = std::sqrt(SQR(transformed->a[y][x]) + SQR(transformed->b[y][x])); @@ -13286,7 +13378,7 @@ void ImProcFunctions::Lab_Local( struct local_params lp; calcLocalParams(sp, oW, oH, params->locallab, lp, prevDeltaE, llColorMask, llColorMaskinv, llExpMask, llExpMaskinv, llSHMask, llSHMaskinv, llvibMask, lllcMask, llsharMask, llcbMask, llretiMask, llsoftMask, lltmMask, llblMask, lllogMask, ll_Mask, llcieMask, locwavCurveden, locwavdenutili); - avoidcolshi(lp, sp, original, transformed, cy, cx, sk); + //avoidcolshi(lp, sp, transformed, reserved, cy, cx, sk); const float radius = lp.rad / (sk * 1.4); //0 to 70 ==> see skip int levred; @@ -19188,7 +19280,7 @@ void ImProcFunctions::Lab_Local( // Gamut and Munsell control - very important do not deactivated to avoid crash - avoidcolshi(lp, sp, original, transformed, cy, cx, sk); + avoidcolshi(lp, sp, transformed, reserved, cy, cx, sk); } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index a83419559..13df614dc 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -137,7 +137,7 @@ enum ProcEventCode { EvHLComprThreshold = 107, EvResizeBoundingBox = 108, EvResizeAppliesTo = 109, - EvLAvoidColorShift = 110, + //EvLAvoidColorShift = 110, obsolete_111 = 111, // obsolete EvLRSTProtection = 112, EvDemosaicDCBIter = 113, @@ -617,7 +617,7 @@ enum ProcEventCode { Evlocallabadjblur = 587, Evlocallabbilateral = 588, Evlocallabsensiden = 589, - Evlocallabavoid = 590, + // Evlocallabavoid = 590, Evlocallabsharcontrast = 591, EvLocenacontrast = 592, Evlocallablcradius = 593, @@ -1067,7 +1067,7 @@ enum ProcEventCode { Evlocallabnlgam = 1037, Evlocallabdivgr = 1038, EvLocallabSpotavoidrad = 1039, - EvLocallabSpotavoidmun = 1040, + //EvLocallabSpotavoidmun = 1040, Evlocallabcontthres = 1041, Evlocallabnorm = 1042, Evlocallabreparw = 1043, diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 371731b93..e6bdc9619 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -608,7 +608,7 @@ LCurveParams::LCurveParams() : brightness(0), contrast(0), chromaticity(0), - avoidcolorshift(false), + gamutmunselmethod("MUN"), rstprotection(0), lcredsk(true) { @@ -630,7 +630,7 @@ bool LCurveParams::operator ==(const LCurveParams& other) const && brightness == other.brightness && contrast == other.contrast && chromaticity == other.chromaticity - && avoidcolorshift == other.avoidcolorshift + && gamutmunselmethod == other.gamutmunselmethod && rstprotection == other.rstprotection && lcredsk == other.lcredsk; } @@ -2848,6 +2848,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : structexclu(0), struc(4.0), shapeMethod("IND"), + avoidgamutMethod("MUNS"), loc{150, 150, 150, 150}, centerX(0), centerY(0), @@ -2862,13 +2863,11 @@ LocallabParams::LocallabSpot::LocallabSpot() : balanh(1.0), colorde(5.0), colorscope(30.0), - avoidrad(0.7), + avoidrad(0.), transitweak(1.0), transitgrad(0.0), hishow(false), activ(true), - avoid(false), - avoidmun(false), blwh(false), recurs(false), laplac(true), @@ -4560,6 +4559,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && structexclu == other.structexclu && struc == other.struc && shapeMethod == other.shapeMethod + && avoidgamutMethod == other.avoidgamutMethod && loc == other.loc && centerX == other.centerX && centerY == other.centerY @@ -4579,8 +4579,6 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && transitgrad == other.transitgrad && hishow == other.hishow && activ == other.activ - && avoid == other.avoid - && avoidmun == other.avoidmun && blwh == other.blwh && recurs == other.recurs && laplac == other.laplac @@ -6045,7 +6043,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->labCurve.brightness, "Luminance Curve", "Brightness", labCurve.brightness, keyFile); saveToKeyfile(!pedited || pedited->labCurve.contrast, "Luminance Curve", "Contrast", labCurve.contrast, keyFile); saveToKeyfile(!pedited || pedited->labCurve.chromaticity, "Luminance Curve", "Chromaticity", labCurve.chromaticity, keyFile); - saveToKeyfile(!pedited || pedited->labCurve.avoidcolorshift, "Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift, keyFile); + saveToKeyfile(!pedited || pedited->labCurve.gamutmunselmethod, "Luminance Curve", "Gamutmunse", labCurve.gamutmunselmethod, keyFile); saveToKeyfile(!pedited || pedited->labCurve.rstprotection, "Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection, keyFile); saveToKeyfile(!pedited || pedited->labCurve.lcredsk, "Luminance Curve", "LCredsk", labCurve.lcredsk, keyFile); saveToKeyfile(!pedited || pedited->labCurve.lcurve, "Luminance Curve", "LCurve", labCurve.lcurve, keyFile); @@ -6347,6 +6345,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->structexclu, "Locallab", "StructExclu_" + index_str, spot.structexclu, keyFile); saveToKeyfile(!pedited || spot_edited->struc, "Locallab", "Struc_" + index_str, spot.struc, keyFile); saveToKeyfile(!pedited || spot_edited->shapeMethod, "Locallab", "ShapeMethod_" + index_str, spot.shapeMethod, keyFile); + saveToKeyfile(!pedited || spot_edited->avoidgamutMethod, "Locallab", "AvoidgamutMethod_" + index_str, spot.avoidgamutMethod, keyFile); saveToKeyfile(!pedited || spot_edited->loc, "Locallab", "Loc_" + index_str, spot.loc, keyFile); saveToKeyfile(!pedited || spot_edited->centerX, "Locallab", "CenterX_" + index_str, spot.centerX, keyFile); saveToKeyfile(!pedited || spot_edited->centerY, "Locallab", "CenterY_" + index_str, spot.centerY, keyFile); @@ -6366,8 +6365,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->transitgrad, "Locallab", "Transitgrad_" + index_str, spot.transitgrad, keyFile); saveToKeyfile(!pedited || spot_edited->hishow, "Locallab", "Hishow_" + index_str, spot.hishow, keyFile); saveToKeyfile(!pedited || spot_edited->activ, "Locallab", "Activ_" + index_str, spot.activ, keyFile); - saveToKeyfile(!pedited || spot_edited->avoid, "Locallab", "Avoid_" + index_str, spot.avoid, keyFile); - saveToKeyfile(!pedited || spot_edited->avoidmun, "Locallab", "Avoidmun_" + index_str, spot.avoidmun, keyFile); saveToKeyfile(!pedited || spot_edited->blwh, "Locallab", "Blwh_" + index_str, spot.blwh, keyFile); saveToKeyfile(!pedited || spot_edited->recurs, "Locallab", "Recurs_" + index_str, spot.recurs, keyFile); saveToKeyfile(!pedited || spot_edited->laplac, "Locallab", "Laplac_" + index_str, spot.laplac, keyFile); @@ -7871,7 +7868,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) // if Saturation == 0, should we set BWToning on? assignFromKeyfile(keyFile, "Luminance Curve", "Saturation", pedited, 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", pedited, labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift); } else { if (keyFile.has_key("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer("Luminance Curve", "Chromaticity"); @@ -7885,7 +7882,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Luminance Curve", "AvoidColorShift", pedited, labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift); assignFromKeyfile(keyFile, "Luminance Curve", "RedAndSkinTonesProtection", pedited, labCurve.rstprotection, pedited->labCurve.rstprotection); } @@ -7914,6 +7910,25 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); + if (keyFile.has_key("Luminance Curve", "Gamutmunse")) { + assignFromKeyfile(keyFile, "Luminance Curve", "Gamutmunse", pedited, labCurve.gamutmunselmethod, pedited->labCurve.gamutmunselmethod); + } else { + if (ppVersion < 303) { + if (keyFile.has_key("Luminance Curve", "AvoidColorClipping")) { + labCurve.gamutmunselmethod = + keyFile.get_boolean("Luminance Curve", "AvoidColorClipping") ? "LAB" : "NONE"; + if (pedited) { + pedited->labCurve.gamutmunselmethod = true; + } + } + } else if (keyFile.has_key("Luminance Curve", "AvoidColorShift")) { + labCurve.gamutmunselmethod = + keyFile.get_boolean("Luminance Curve", "AvoidColorShift") ? "LAB" : "NONE"; + if (pedited) { + pedited->labCurve.gamutmunselmethod = true; + } + } + } } if (keyFile.has_group("Sharpening")) { @@ -8423,6 +8438,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); + if (keyFile.has_key("Locallab", "AvoidgamutMethod_" + index_str)) { + assignFromKeyfile(keyFile, "Locallab", "AvoidgamutMethod_" + index_str, pedited, 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); + spot.avoidgamutMethod = avoid ? (munsell ? "MUNS" : "LAB") : "NONE"; + if (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); @@ -8442,8 +8467,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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", "Avoid_" + index_str, pedited, spot.avoid, spotEdited.avoid); - assignFromKeyfile(keyFile, "Locallab", "Avoidmun_" + index_str, pedited, spot.avoidmun, spotEdited.avoidmun); 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 24e1ca036..e86272b0a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -376,7 +376,7 @@ struct LCurveParams { int brightness; int contrast; int chromaticity; - bool avoidcolorshift; + Glib::ustring gamutmunselmethod; double rstprotection; bool lcredsk; @@ -1019,6 +1019,8 @@ struct LocallabParams { int structexclu; double struc; Glib::ustring shapeMethod; // IND, SYM, INDSL, SYMSL + Glib::ustring avoidgamutMethod; // NONE, LAB, XYZ + std::vector loc; // For ellipse/rectangle: {locX, locXL, locY, locYT} int centerX; int centerY; @@ -1038,8 +1040,6 @@ struct LocallabParams { double transitgrad; bool hishow; bool activ; - bool avoid; - bool avoidmun; bool blwh; bool recurs; bool laplac; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index d45283c38..3916adfbe 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -1185,8 +1185,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { AUTOEXP, //Evlocallabforcebw AUTOEXP, //Evlocallabsigjz AUTOEXP, //Evlocallabsigq - AUTOEXP //Evlocallablogcie - + AUTOEXP //Evlocallablogcie }; diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index 7fcc45312..d869903b5 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -49,7 +49,8 @@ BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LAB metHBox->set_spacing (2); Gtk::Label* metLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_MET") + ":")); metHBox->pack_start (*metLabel, Gtk::PACK_SHRINK); - method = Gtk::manage (new MyComboBoxText ()); + + method = Gtk::manage (new MyComboBoxText ()); method->append (M("TP_BWMIX_MET_DESAT")); method->append (M("TP_BWMIX_MET_LUMEQUAL")); method->append (M("TP_BWMIX_MET_CHANMIX")); diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 0d57d98bb..60fde12a6 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -24,6 +24,7 @@ #include "options.h" #include "../rtengine/procparams.h" #include "rtimage.h" +#include "eventmapper.h" using namespace rtengine; using namespace procparams; @@ -55,6 +56,7 @@ ControlSpotPanel::ControlSpotPanel(): qualityMethod_(Gtk::manage(new MyComboBoxText())), //complexMethod_(Gtk::manage(new MyComboBoxText())), wavMethod_(Gtk::manage(new MyComboBoxText())), + avoidgamutMethod_(Gtk::manage(new MyComboBoxText())), sensiexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 12))), structexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), @@ -76,15 +78,13 @@ ControlSpotPanel::ControlSpotPanel(): 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"))))), 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))), + avoidrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_AVOIDRAD"), 0., 30.0, 0.1, 0.))), 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")) ))), hishow_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_PREVSHOW")))), activ_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIVSPOT")))), - avoid_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AVOID")))), - avoidmun_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AVOIDMUN")))), blwh_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_BLWH")))), recurs_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_RECURS")))), laplac_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LAPLACC")))), @@ -100,6 +100,7 @@ ControlSpotPanel::ControlSpotPanel(): preview_(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), ctboxshape(Gtk::manage(new Gtk::Box())), ctboxshapemethod(Gtk::manage(new Gtk::Box())), + ctboxgamut(Gtk::manage(new Gtk::Box())), controlPanelListener(nullptr), lastObject_(-1), @@ -111,6 +112,8 @@ ControlSpotPanel::ControlSpotPanel(): excluFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_EXCLUF")))), maskPrevActive(false) { + auto m = ProcEventMapper::getInstance(); + EvLocallabavoidgamutMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GAMUTMUNSEL"); const bool showtooltip = options.showtooltip; pack_start(*hishow_); @@ -397,23 +400,30 @@ ControlSpotPanel::ControlSpotPanel(): activConn_ = activ_->signal_toggled().connect( sigc::mem_fun(*this, &ControlSpotPanel::activChanged)); - avoidConn_ = avoid_->signal_toggled().connect( - 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()); + Gtk::Label* const labelgamut = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_AVOID") + ":")); + ctboxgamut->pack_start(*labelgamut, Gtk::PACK_SHRINK, 4); + avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTNON")); + avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTLABRELA")); + avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZABSO")); + avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZRELA")); + avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTMUNSELL")); + avoidgamutMethod_->set_active(4); + avoidgamutconn_ = avoidgamutMethod_->signal_changed().connect( + sigc::mem_fun( + *this, &ControlSpotPanel::avoidgamutMethodChanged)); + ctboxgamut->pack_start(*avoidgamutMethod_); + if (showtooltip) { + ctboxgamut->set_tooltip_text(M("TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP")); + } + + Gtk::Frame* const avFrame = Gtk::manage(new Gtk::Frame()); ToolParamBlock* const avbox = Gtk::manage(new ToolParamBlock()); avFrame->set_label_align(0.025, 0.5); - avFrame->set_label_widget(*avoid_); + avbox->pack_start(*ctboxgamut); avbox->pack_start(*avoidrad_); - avbox->pack_start(*avoidmun_); avFrame->add(*avbox); specCaseBox->pack_start(*avFrame); - if (showtooltip) { - avoidmun_->set_tooltip_text(M("TP_LOCALLAB_AVOIDMUN_TOOLTIP")); - } blwhConn_ = blwh_->signal_toggled().connect( sigc::mem_fun(*this, &ControlSpotPanel::blwhChanged)); @@ -429,7 +439,6 @@ ControlSpotPanel::ControlSpotPanel(): if (showtooltip) { recurs_->set_tooltip_text(M("TP_LOCALLAB_RECURS_TOOLTIP")); - avoid_->set_tooltip_text(M("TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP")); } specCaseBox->pack_start(*recurs_); @@ -854,8 +863,6 @@ void ControlSpotPanel::load_ControlSpot_param() avoidrad_->setValue((double)row[spots_.avoidrad]); hishow_->set_active(row[spots_.hishow]); activ_->set_active(row[spots_.activ]); - avoid_->set_active(row[spots_.avoid]); - avoidmun_->set_active(row[spots_.avoidmun]); blwh_->set_active(row[spots_.blwh]); recurs_->set_active(row[spots_.recurs]); // laplac_->set_active(row[spots_.laplac]); @@ -868,6 +875,8 @@ void ControlSpotPanel::load_ControlSpot_param() //savrest_->set_active(row[spots_.savrest]); //complexMethod_->set_active(row[spots_.complexMethod]); wavMethod_->set_active(row[spots_.wavMethod]); + avoidgamutMethod_->set_active(row[spots_.avoidgamutMethod]); + } void ControlSpotPanel::controlspotChanged() @@ -1055,6 +1064,34 @@ void ControlSpotPanel::spotMethodChanged() } } +void ControlSpotPanel::avoidgamutMethodChanged() +{ + + // Get selected control spot + const auto s = treeview_->get_selection(); + + if (!s->count_selected_rows()) { + return; + } + const int meth = avoidgamutMethod_->get_active_row_number(); + avoidrad_->show(); + + if(meth == 2 || meth == 3 || meth == 4) { + avoidrad_->hide(); + } + + const auto iter = s->get_selected(); + Gtk::TreeModel::Row row = *iter; + + row[spots_.avoidgamutMethod] = avoidgamutMethod_->get_active_row_number(); + + // Raise event + if (listener) { + listener->panelChanged(EvLocallabavoidgamutMethod, avoidgamutMethod_->get_active_text()); + } + +} + void ControlSpotPanel::shapeMethodChanged() { // printf("shapeMethodChanged\n"); @@ -1217,6 +1254,7 @@ void ControlSpotPanel::updateParamVisibility() // Update Control Spot GUI according to shapeMethod_ combobox state (to be compliant with shapeMethodChanged function) const int method = shapeMethod_->get_active_row_number(); + const int meth = avoidgamutMethod_->get_active_row_number(); if (!batchMode) { if (method == 1 || method == 3) { // Symmetrical cases @@ -1260,6 +1298,12 @@ void ControlSpotPanel::updateParamVisibility() centerY_->show(); } + if(meth == 1) { + avoidrad_->show(); + } else { + avoidrad_->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(); @@ -1588,57 +1632,6 @@ void ControlSpotPanel::hishowChanged() } - -void ControlSpotPanel::avoidChanged() -{ - // printf("avoidChanged\n"); - - // Get selected control spot - const auto s = treeview_->get_selection(); - - if (!s->count_selected_rows()) { - return; - } - - const auto iter = s->get_selected(); - Gtk::TreeModel::Row row = *iter; - row[spots_.avoid] = avoid_->get_active(); - - // Raise event - if (listener) { - if (avoid_->get_active()) { - listener->panelChanged(Evlocallabavoid, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(Evlocallabavoid, M("GENERAL_DISABLED")); - } - } -} - -void ControlSpotPanel::avoidmunChanged() -{ - // printf("avoidmunChanged\n"); - - // Get selected control spot - const auto s = treeview_->get_selection(); - - if (!s->count_selected_rows()) { - return; - } - - const auto iter = s->get_selected(); - Gtk::TreeModel::Row row = *iter; - row[spots_.avoidmun] = avoidmun_->get_active(); - - // Raise event - if (listener) { - if (avoidmun_->get_active()) { - listener->panelChanged(EvLocallabSpotavoidmun, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvLocallabSpotavoidmun, M("GENERAL_DISABLED")); - } - } -} - void ControlSpotPanel::activChanged() { // printf("activChanged\n"); @@ -1859,8 +1852,6 @@ void ControlSpotPanel::disableParamlistener(bool cond) avoidrad_->block(cond); hishowconn_.block(cond); activConn_.block(cond); - avoidConn_.block(cond); - avoidmunConn_.block(cond); blwhConn_.block(cond); recursConn_.block(cond); laplacConn_.block(cond); @@ -1872,6 +1863,8 @@ void ControlSpotPanel::disableParamlistener(bool cond) //savrestConn_.block(cond); //complexMethodconn_.block(cond); wavMethodconn_.block(cond); + avoidgamutconn_.block(cond); + } void ControlSpotPanel::setParamEditable(bool cond) @@ -1906,8 +1899,6 @@ void ControlSpotPanel::setParamEditable(bool cond) avoidrad_->set_sensitive(cond); hishow_->set_sensitive(cond); activ_->set_sensitive(cond); - avoid_->set_sensitive(cond); - avoidmun_->set_sensitive(cond); blwh_->set_sensitive(cond); recurs_->set_sensitive(cond); laplac_->set_sensitive(cond); @@ -1920,6 +1911,7 @@ void ControlSpotPanel::setParamEditable(bool cond) //complexMethod_->set_sensitive(cond); wavMethod_->set_sensitive(cond); preview_->set_sensitive(cond); + avoidgamutMethod_->set_sensitive(cond); if (!cond) { // Reset complex parameters visibility to default state @@ -2592,8 +2584,6 @@ ControlSpotPanel::SpotRow* ControlSpotPanel::getSpot(const int index) r->lumask = row[spots_.lumask]; r->hishow = row[spots_.hishow]; r->activ = row[spots_.activ]; - r->avoid = row[spots_.avoid]; - r->avoidmun = row[spots_.avoidmun]; r->blwh = row[spots_.blwh]; r->recurs = row[spots_.recurs]; r->laplac = row[spots_.laplac]; @@ -2601,6 +2591,7 @@ ControlSpotPanel::SpotRow* ControlSpotPanel::getSpot(const int index) r->shortc = row[spots_.shortc]; //r->savrest = row[spots_.savrest]; r->wavMethod = row[spots_.wavMethod]; + r->avoidgamutMethod = row[spots_.avoidgamutMethod]; return r; } @@ -2725,8 +2716,6 @@ void ControlSpotPanel::addControlSpot(SpotRow* newSpot) row[spots_.avoidrad] = newSpot->avoidrad; row[spots_.hishow] = newSpot->hishow; row[spots_.activ] = newSpot->activ; - row[spots_.avoid] = newSpot->avoid; - row[spots_.avoidmun] = newSpot->avoidmun; row[spots_.blwh] = newSpot->blwh; row[spots_.recurs] = newSpot->recurs; row[spots_.laplac] = newSpot->laplac; @@ -2738,6 +2727,7 @@ void ControlSpotPanel::addControlSpot(SpotRow* newSpot) //row[spots_.savrest] = newSpot->savrest; row[spots_.complexMethod] = newSpot->complexMethod; row[spots_.wavMethod] = newSpot->wavMethod; + row[spots_.avoidgamutMethod] = newSpot->avoidgamutMethod; updateParamVisibility(); disableParamlistener(false); @@ -2845,8 +2835,6 @@ ControlSpotPanel::ControlSpots::ControlSpots() add(avoidrad); add(hishow); add(activ); - add(avoid); - add(avoidmun); add(blwh); add(recurs); add(laplac); @@ -2858,6 +2846,7 @@ ControlSpotPanel::ControlSpots::ControlSpots() //add(savrest); add(complexMethod); add(wavMethod); + add(avoidgamutMethod); } //----------------------------------------------------------------------------- diff --git a/rtgui/controlspotpanel.h b/rtgui/controlspotpanel.h index 92406c690..b1e191b0e 100644 --- a/rtgui/controlspotpanel.h +++ b/rtgui/controlspotpanel.h @@ -57,6 +57,7 @@ public: int sensiexclu; int structexclu; int shapeMethod; // 0 = Independent (mouse), 1 = Symmetrical (mouse), 2 = Independent (mouse + sliders), 3 = Symmetrical (mouse + sliders) + int avoidgamutMethod; int locX; int locXL; int locY; @@ -79,8 +80,6 @@ public: double avoidrad; bool hishow; bool activ; - bool avoid; - bool avoidmun; bool blwh; bool recurs; bool laplac; @@ -243,7 +242,8 @@ private: void spotMethodChanged(); void shapeMethodChanged(); void qualityMethodChanged(); - //void complexMethodChanged(); + void avoidgamutMethodChanged(); + //void complexMethodChanged(); void wavMethodChanged(); void updateParamVisibility(); @@ -252,8 +252,6 @@ private: void hishowChanged(); void activChanged(); - void avoidChanged(); - void avoidmunChanged(); void blwhChanged(); void recursChanged(); void laplacChanged(); @@ -293,6 +291,7 @@ private: Gtk::TreeModelColumn sensiexclu; Gtk::TreeModelColumn structexclu; Gtk::TreeModelColumn shapeMethod; // 0 = Independent (mouse), 1 = Symmetrical (mouse), 2 = Independent (mouse + sliders), 3 = Symmetrical (mouse + sliders) + Gtk::TreeModelColumn avoidgamutMethod; Gtk::TreeModelColumn locX; Gtk::TreeModelColumn locXL; Gtk::TreeModelColumn locY; @@ -315,8 +314,6 @@ private: Gtk::TreeModelColumn avoidrad; Gtk::TreeModelColumn hishow; Gtk::TreeModelColumn activ; - Gtk::TreeModelColumn avoid; - Gtk::TreeModelColumn avoidmun; Gtk::TreeModelColumn blwh; Gtk::TreeModelColumn recurs; Gtk::TreeModelColumn laplac; @@ -347,6 +344,7 @@ private: }; ControlSpots spots_; + rtengine::ProcEvent EvLocallabavoidgamutMethod; // Child widgets Gtk::ScrolledWindow* const scrolledwindow_; @@ -381,6 +379,8 @@ private: //sigc::connection complexMethodconn_; MyComboBoxText* const wavMethod_; sigc::connection wavMethodconn_; + MyComboBoxText* const avoidgamutMethod_; + sigc::connection avoidgamutconn_; Adjuster* const sensiexclu_; Adjuster* const structexclu_; @@ -411,10 +411,6 @@ private: sigc::connection hishowconn_; Gtk::CheckButton* const activ_; sigc::connection activConn_; - Gtk::CheckButton* const avoid_; - sigc::connection avoidConn_; - Gtk::CheckButton* const avoidmun_; - sigc::connection avoidmunConn_; Gtk::CheckButton* const blwh_; sigc::connection blwhConn_; Gtk::CheckButton* const recurs_; @@ -438,6 +434,7 @@ private: Gtk::Box* const ctboxshape; Gtk::Box* const ctboxshapemethod; + Gtk::Box* const ctboxgamut; // Internal variables ControlPanelListener* controlPanelListener; diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index d2279f586..e0e0bfb01 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -19,6 +19,7 @@ #include #include "labcurve.h" +#include "eventmapper.h" #include "curveeditor.h" #include "curveeditorgroup.h" @@ -32,61 +33,80 @@ using namespace rtengine; using namespace rtengine::procparams; -LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), false, true) +LCurve::LCurve() : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), false, true) { - brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); - contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); - chromaticity = Gtk::manage (new Adjuster (M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.)); + auto m = ProcEventMapper::getInstance(); + Evgamutmunsell = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_GAMUTMUNSEL"); + CurveListener::setMulti(true); + brightness = Gtk::manage(new Adjuster(M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); + contrast = Gtk::manage(new Adjuster(M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); + chromaticity = Gtk::manage(new Adjuster(M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.)); chromaticity->set_tooltip_markup(M("TP_LABCURVE_CHROMA_TOOLTIP")); - pack_start (*brightness); - brightness->show (); + pack_start(*brightness); + brightness->show(); - pack_start (*contrast); - contrast->show (); + pack_start(*contrast); + contrast->show(); - pack_start (*chromaticity); - chromaticity->show (); + pack_start(*chromaticity); + chromaticity->show(); - brightness->setAdjusterListener (this); - contrast->setAdjusterListener (this); - chromaticity->setAdjusterListener (this); + brightness->setAdjusterListener(this); + contrast->setAdjusterListener(this); + chromaticity->setAdjusterListener(this); brightness->setLogScale(2, 0, true); contrast->setLogScale(2, 0, true); chromaticity->setLogScale(2, 0, true); //%%%%%%%%%%%%%%%%%% - Gtk::Separator* hsep2 = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - hsep2->show (); - pack_start (*hsep2, Gtk::PACK_EXPAND_WIDGET, 4); + Gtk::Separator* hsep2 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); + hsep2->show(); + pack_start(*hsep2, Gtk::PACK_EXPAND_WIDGET, 4); - avoidcolorshift = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORSHIFT"))); - avoidcolorshift->set_tooltip_text (M("TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP")); - pack_start (*avoidcolorshift, Gtk::PACK_SHRINK, 4); - lcredsk = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_LCREDSK"))); - lcredsk->set_tooltip_markup (M("TP_LABCURVE_LCREDSK_TOOLTIP")); - pack_start (*lcredsk); - rstprotection = Gtk::manage ( new Adjuster (M("TP_LABCURVE_RSTPROTECTION"), 0., 100., 0.1, 0.) ); - pack_start (*rstprotection); - rstprotection->show (); - rstprotection->setAdjusterListener (this); - rstprotection->set_tooltip_text (M("TP_LABCURVE_RSTPRO_TOOLTIP")); + Gtk::Box* metHBox = Gtk::manage(new Gtk::Box()); + metHBox->set_spacing(2); + Gtk::Label* metLabel = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_AVOID") + ":")); + metHBox->pack_start(*metLabel, Gtk::PACK_SHRINK); - acconn = avoidcolorshift->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidcolorshift_toggled) ); - lcconn = lcredsk->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::lcredsk_toggled) ); + gamutmunselmethod = Gtk::manage(new MyComboBoxText()); + gamutmunselmethod->append(M("TP_LOCALLAB_GAMUTNON")); + gamutmunselmethod->append(M("TP_LOCALLAB_GAMUTLABRELA")); + gamutmunselmethod->append(M("TP_LOCALLAB_GAMUTXYZABSO")); + gamutmunselmethod->append(M("TP_LOCALLAB_GAMUTXYZRELA")); + gamutmunselmethod->append(M("TP_LOCALLAB_GAMUTMUNSELL")); + gamutmunselmethod->set_active(4); + gamutmunselmethod->set_tooltip_text(M("TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP")); + metHBox->pack_start(*gamutmunselmethod); + pack_start(*metHBox); + gamutmunselmethodconn = gamutmunselmethod->signal_changed().connect(sigc::mem_fun(*this, &LCurve::gamutmunselChanged)); + + + lcredsk = Gtk::manage(new Gtk::CheckButton(M("TP_LABCURVE_LCREDSK"))); + lcredsk->set_tooltip_markup(M("TP_LABCURVE_LCREDSK_TOOLTIP")); + pack_start(*lcredsk); + + rstprotection = Gtk::manage(new Adjuster(M("TP_LABCURVE_RSTPROTECTION"), 0., 100., 0.1, 0.)); + pack_start(*rstprotection); + rstprotection->show(); + + rstprotection->setAdjusterListener(this); + rstprotection->set_tooltip_text(M("TP_LABCURVE_RSTPRO_TOOLTIP")); + + lcconn = lcredsk->signal_toggled().connect(sigc::mem_fun(*this, &LCurve::lcredsk_toggled)); //%%%%%%%%%%%%%%%%%%% - Gtk::Separator* hsep3 = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - hsep3->show (); - pack_start (*hsep3, Gtk::PACK_EXPAND_WIDGET, 4); + Gtk::Separator* hsep3 = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); + hsep3->show(); + pack_start(*hsep3, Gtk::PACK_EXPAND_WIDGET, 4); - curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); - curveEditorG->setCurveListener (this); + curveEditorG = new CurveEditorGroup(options.lastLabCurvesDir); + curveEditorG->setCurveListener(this); lshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "L*")); lshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP")); @@ -216,88 +236,111 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); - pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); - Gtk::Separator* hsepdh = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - hsepdh->show (); - pack_start (*hsepdh, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); + Gtk::Separator* hsepdh = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); + hsepdh->show(); + pack_start(*hsepdh, Gtk::PACK_EXPAND_WIDGET, 4); + show_all_children(); } -LCurve::~LCurve () +LCurve::~LCurve() { delete curveEditorG; } -void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) +void LCurve::read(const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); + disableListener(); + gamutmunselmethodconn.block(true); + + + brightness->setValue(pp->labCurve.brightness); + contrast->setValue(pp->labCurve.contrast); + chromaticity->setValue(pp->labCurve.chromaticity); + adjusterChanged(chromaticity, pp->labCurve.chromaticity); // To update the GUI sensitiveness + //%%%%%%%%%%%%%%%%%%%%%% + rstprotection->setValue(pp->labCurve.rstprotection); + + + bwtconn.block(true); + lcconn.block(true); + lcredsk->set_active(pp->labCurve.lcredsk); + + bwtconn.block(false); + lcconn.block(false); + + lastLCVal = pp->labCurve.lcredsk; + //%%%%%%%%%%%%%%%%%%%%%% + + lshape->setCurve(pp->labCurve.lcurve); + ashape->setCurve(pp->labCurve.acurve); + bshape->setCurve(pp->labCurve.bcurve); + ccshape->setCurve(pp->labCurve.cccurve); + chshape->setCurve(pp->labCurve.chcurve); + lhshape->setCurve(pp->labCurve.lhcurve); + hhshape->setCurve(pp->labCurve.hhcurve); + lcshape->setCurve(pp->labCurve.lccurve); + clshape->setCurve(pp->labCurve.clcurve); + + if (pedited && !pedited->labCurve.gamutmunselmethod) { + gamutmunselmethod->set_active(4); // "Unchanged" + } else if (pp->labCurve.gamutmunselmethod == "NONE") { + gamutmunselmethod->set_active(0); + } else if (pp->labCurve.gamutmunselmethod == "LAB") { + gamutmunselmethod->set_active(1); + } else if (pp->labCurve.gamutmunselmethod == "XYZ") { + gamutmunselmethod->set_active(2); + } else if (pp->labCurve.gamutmunselmethod == "XYZREL") { + gamutmunselmethod->set_active(3); + } else if (pp->labCurve.gamutmunselmethod == "MUN") { + gamutmunselmethod->set_active(4); + } + + gamutmunselChanged(); if (pedited) { - brightness->setEditedState (pedited->labCurve.brightness ? Edited : UnEdited); - contrast->setEditedState (pedited->labCurve.contrast ? Edited : UnEdited); - chromaticity->setEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); + brightness->setEditedState(pedited->labCurve.brightness ? Edited : UnEdited); + contrast->setEditedState(pedited->labCurve.contrast ? Edited : UnEdited); + chromaticity->setEditedState(pedited->labCurve.chromaticity ? Edited : UnEdited); //%%%%%%%%%%%%%%%%%%%%%% - rstprotection->setEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); - avoidcolorshift->set_inconsistent (!pedited->labCurve.avoidcolorshift); - lcredsk->set_inconsistent (!pedited->labCurve.lcredsk); + rstprotection->setEditedState(pedited->labCurve.rstprotection ? Edited : UnEdited); + lcredsk->set_inconsistent(!pedited->labCurve.lcredsk); //%%%%%%%%%%%%%%%%%%%%%% - lshape->setUnChanged (!pedited->labCurve.lcurve); - ashape->setUnChanged (!pedited->labCurve.acurve); - bshape->setUnChanged (!pedited->labCurve.bcurve); - ccshape->setUnChanged (!pedited->labCurve.cccurve); - chshape->setUnChanged (!pedited->labCurve.chcurve); - lhshape->setUnChanged (!pedited->labCurve.lhcurve); - hhshape->setUnChanged (!pedited->labCurve.hhcurve); - lcshape->setUnChanged (!pedited->labCurve.lccurve); - clshape->setUnChanged (!pedited->labCurve.clcurve); + lshape->setUnChanged(!pedited->labCurve.lcurve); + ashape->setUnChanged(!pedited->labCurve.acurve); + bshape->setUnChanged(!pedited->labCurve.bcurve); + ccshape->setUnChanged(!pedited->labCurve.cccurve); + chshape->setUnChanged(!pedited->labCurve.chcurve); + lhshape->setUnChanged(!pedited->labCurve.lhcurve); + hhshape->setUnChanged(!pedited->labCurve.hhcurve); + lcshape->setUnChanged(!pedited->labCurve.lccurve); + clshape->setUnChanged(!pedited->labCurve.clcurve); + + if (!pedited->labCurve.gamutmunselmethod) { + gamutmunselmethod->set_active_text(M("GENERAL_UNCHANGED")); + } set_inconsistent(multiImage && !pedited->labCurve.enabled); } - brightness->setValue (pp->labCurve.brightness); - contrast->setValue (pp->labCurve.contrast); - chromaticity->setValue (pp->labCurve.chromaticity); - adjusterChanged(chromaticity, pp->labCurve.chromaticity); // To update the GUI sensitiveness - //%%%%%%%%%%%%%%%%%%%%%% - rstprotection->setValue (pp->labCurve.rstprotection); + gamutmunselmethodconn.block(false); - bwtconn.block (true); - acconn.block (true); - lcconn.block (true); - avoidcolorshift->set_active (pp->labCurve.avoidcolorshift); - lcredsk->set_active (pp->labCurve.lcredsk); - - bwtconn.block (false); - acconn.block (false); - lcconn.block (false); - - lastACVal = pp->labCurve.avoidcolorshift; - lastLCVal = pp->labCurve.lcredsk; - //%%%%%%%%%%%%%%%%%%%%%% - - lshape->setCurve (pp->labCurve.lcurve); - ashape->setCurve (pp->labCurve.acurve); - bshape->setCurve (pp->labCurve.bcurve); - ccshape->setCurve (pp->labCurve.cccurve); - chshape->setCurve (pp->labCurve.chcurve); - lhshape->setCurve (pp->labCurve.lhcurve); - hhshape->setCurve (pp->labCurve.hhcurve); - lcshape->setCurve (pp->labCurve.lccurve); - clshape->setCurve (pp->labCurve.clcurve); setEnabled(pp->labCurve.enabled); - + queue_draw(); - enableListener (); + enableListener(); } -void LCurve::autoOpenCurve () + +void LCurve::autoOpenCurve() { // Open up the first curve if selected bool active = lshape->openIfNonlinear(); @@ -336,7 +379,7 @@ void LCurve::autoOpenCurve () } -void LCurve::setEditProvider (EditDataProvider *provider) +void LCurve::setEditProvider(EditDataProvider *provider) { lshape->setEditProvider(provider); ccshape->setEditProvider(provider); @@ -351,127 +394,128 @@ void LCurve::setEditProvider (EditDataProvider *provider) } -void LCurve::write (ProcParams* pp, ParamsEdited* pedited) +void LCurve::write(ProcParams* pp, ParamsEdited* pedited) { pp->labCurve.enabled = getEnabled(); - - pp->labCurve.brightness = brightness->getValue (); - pp->labCurve.contrast = (int)contrast->getValue (); - pp->labCurve.chromaticity = (int)chromaticity->getValue (); - //%%%%%%%%%%%%%%%%%%%%%% - pp->labCurve.avoidcolorshift = avoidcolorshift->get_active (); - pp->labCurve.lcredsk = lcredsk->get_active (); - pp->labCurve.rstprotection = rstprotection->getValue (); + pp->labCurve.brightness = brightness->getValue(); + pp->labCurve.contrast = (int)contrast->getValue(); + pp->labCurve.chromaticity = (int)chromaticity->getValue(); + //%%%%%%%%%%%%%%%%%%%%%% + pp->labCurve.lcredsk = lcredsk->get_active(); + + pp->labCurve.rstprotection = rstprotection->getValue(); //%%%%%%%%%%%%%%%%%%%%%% - pp->labCurve.lcurve = lshape->getCurve (); - pp->labCurve.acurve = ashape->getCurve (); - pp->labCurve.bcurve = bshape->getCurve (); - pp->labCurve.cccurve = ccshape->getCurve (); - pp->labCurve.chcurve = chshape->getCurve (); - pp->labCurve.lhcurve = lhshape->getCurve (); - pp->labCurve.hhcurve = hhshape->getCurve (); - pp->labCurve.lccurve = lcshape->getCurve (); - pp->labCurve.clcurve = clshape->getCurve (); + pp->labCurve.lcurve = lshape->getCurve(); + pp->labCurve.acurve = ashape->getCurve(); + pp->labCurve.bcurve = bshape->getCurve(); + pp->labCurve.cccurve = ccshape->getCurve(); + pp->labCurve.chcurve = chshape->getCurve(); + pp->labCurve.lhcurve = lhshape->getCurve(); + pp->labCurve.hhcurve = hhshape->getCurve(); + pp->labCurve.lccurve = lcshape->getCurve(); + pp->labCurve.clcurve = clshape->getCurve(); + + if (pedited) { - pedited->labCurve.brightness = brightness->getEditedState (); - pedited->labCurve.contrast = contrast->getEditedState (); - pedited->labCurve.chromaticity = chromaticity->getEditedState (); + pedited->labCurve.brightness = brightness->getEditedState(); + pedited->labCurve.contrast = contrast->getEditedState(); + pedited->labCurve.chromaticity = chromaticity->getEditedState(); //%%%%%%%%%%%%%%%%%%%%%% - pedited->labCurve.avoidcolorshift = !avoidcolorshift->get_inconsistent(); pedited->labCurve.lcredsk = !lcredsk->get_inconsistent(); - pedited->labCurve.rstprotection = rstprotection->getEditedState (); + pedited->labCurve.rstprotection = rstprotection->getEditedState(); + pedited->labCurve.gamutmunselmethod = gamutmunselmethod->get_active_text() != M("GENERAL_UNCHANGED"); - pedited->labCurve.lcurve = !lshape->isUnChanged (); - pedited->labCurve.acurve = !ashape->isUnChanged (); - pedited->labCurve.bcurve = !bshape->isUnChanged (); - pedited->labCurve.cccurve = !ccshape->isUnChanged (); - pedited->labCurve.chcurve = !chshape->isUnChanged (); - pedited->labCurve.lhcurve = !lhshape->isUnChanged (); - pedited->labCurve.hhcurve = !hhshape->isUnChanged (); - pedited->labCurve.lccurve = !lcshape->isUnChanged (); - pedited->labCurve.clcurve = !clshape->isUnChanged (); + pedited->labCurve.lcurve = !lshape->isUnChanged(); + pedited->labCurve.acurve = !ashape->isUnChanged(); + pedited->labCurve.bcurve = !bshape->isUnChanged(); + pedited->labCurve.cccurve = !ccshape->isUnChanged(); + pedited->labCurve.chcurve = !chshape->isUnChanged(); + pedited->labCurve.lhcurve = !lhshape->isUnChanged(); + pedited->labCurve.hhcurve = !hhshape->isUnChanged(); + pedited->labCurve.lccurve = !lcshape->isUnChanged(); + pedited->labCurve.clcurve = !clshape->isUnChanged(); pedited->labCurve.enabled = !get_inconsistent(); + } + if (gamutmunselmethod->get_active_row_number() == 0) { + pp->labCurve.gamutmunselmethod = "NONE"; + } else if (gamutmunselmethod->get_active_row_number() == 1) { + pp->labCurve.gamutmunselmethod = "LAB"; + } else if (gamutmunselmethod->get_active_row_number() == 2) { + pp->labCurve.gamutmunselmethod = "XYZ"; + } else if (gamutmunselmethod->get_active_row_number() == 3) { + pp->labCurve.gamutmunselmethod = "XYZREL"; + } else if (gamutmunselmethod->get_active_row_number() == 4) { + pp->labCurve.gamutmunselmethod = "MUN"; + } + + + } -void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +void LCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { - brightness->setDefault (defParams->labCurve.brightness); - contrast->setDefault (defParams->labCurve.contrast); - chromaticity->setDefault (defParams->labCurve.chromaticity); - rstprotection->setDefault (defParams->labCurve.rstprotection); + brightness->setDefault(defParams->labCurve.brightness); + contrast->setDefault(defParams->labCurve.contrast); + chromaticity->setDefault(defParams->labCurve.chromaticity); + rstprotection->setDefault(defParams->labCurve.rstprotection); if (pedited) { - brightness->setDefaultEditedState (pedited->labCurve.brightness ? Edited : UnEdited); - contrast->setDefaultEditedState (pedited->labCurve.contrast ? Edited : UnEdited); - chromaticity->setDefaultEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); - rstprotection->setDefaultEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); + brightness->setDefaultEditedState(pedited->labCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState(pedited->labCurve.contrast ? Edited : UnEdited); + chromaticity->setDefaultEditedState(pedited->labCurve.chromaticity ? Edited : UnEdited); + rstprotection->setDefaultEditedState(pedited->labCurve.rstprotection ? Edited : UnEdited); } else { - brightness->setDefaultEditedState (Irrelevant); - contrast->setDefaultEditedState (Irrelevant); - chromaticity->setDefaultEditedState (Irrelevant); - rstprotection->setDefaultEditedState (Irrelevant); + brightness->setDefaultEditedState(Irrelevant); + contrast->setDefaultEditedState(Irrelevant); + chromaticity->setDefaultEditedState(Irrelevant); + rstprotection->setDefaultEditedState(Irrelevant); } } //%%%%%%%%%%%%%%%%%%%%%% -//Color shift control changed -void LCurve::avoidcolorshift_toggled () + +void LCurve::gamutmunselChanged() { - if (batchMode) { - if (avoidcolorshift->get_inconsistent()) { - avoidcolorshift->set_inconsistent (false); - acconn.block (true); - avoidcolorshift->set_active (false); - acconn.block (false); - } else if (lastACVal) { - avoidcolorshift->set_inconsistent (true); - } - - lastACVal = avoidcolorshift->get_active (); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(Evgamutmunsell, gamutmunselmethod->get_active_text()); } - if (listener && getEnabled()) { - if (avoidcolorshift->get_active ()) { - listener->panelChanged (EvLAvoidColorShift, M("GENERAL_ENABLED")); - } else { - listener->panelChanged (EvLAvoidColorShift, M("GENERAL_DISABLED")); - } - } } -void LCurve::lcredsk_toggled () + +void LCurve::lcredsk_toggled() { if (batchMode) { if (lcredsk->get_inconsistent()) { - lcredsk->set_inconsistent (false); - lcconn.block (true); - lcredsk->set_active (false); - lcconn.block (false); + lcredsk->set_inconsistent(false); + lcconn.block(true); + lcredsk->set_active(false); + lcconn.block(false); } else if (lastLCVal) { - lcredsk->set_inconsistent (true); + lcredsk->set_inconsistent(true); } - lastLCVal = lcredsk->get_active (); + lastLCVal = lcredsk->get_active(); } else { lcshape->refresh(); } if (listener && getEnabled()) { - if (lcredsk->get_active ()) { - listener->panelChanged (EvLLCredsk, M("GENERAL_ENABLED")); + if (lcredsk->get_active()) { + listener->panelChanged(EvLLCredsk, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvLLCredsk, M("GENERAL_DISABLED")); + listener->panelChanged(EvLLCredsk, M("GENERAL_DISABLED")); } } } @@ -484,44 +528,44 @@ void LCurve::lcredsk_toggled () * If more than one curve has been added, the curve listener is automatically * set to 'multi=true', and send a pointer of the modified curve in a parameter */ -void LCurve::curveChanged (CurveEditor* ce) +void LCurve::curveChanged(CurveEditor* ce) { if (listener && getEnabled()) { if (ce == lshape) { - listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLLCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == ashape) { - listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLaCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == bshape) { - listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLbCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == ccshape) { - listener->panelChanged (EvLCCCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLCCCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == chshape) { - listener->panelChanged (EvLCHCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLCHCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == lhshape) { - listener->panelChanged (EvLLHCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLLHCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == hhshape) { - listener->panelChanged (EvLHHCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLHHCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == lcshape) { - listener->panelChanged (EvLLCCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLLCCurve, M("HISTORY_CUSTOMCURVE")); } if (ce == clshape) { - listener->panelChanged (EvLCLCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvLCLCurve, M("HISTORY_CUSTOMCURVE")); } @@ -533,45 +577,43 @@ void LCurve::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; if (a == brightness) { - costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else if (a == rstprotection) { - costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(1), a->getValue()); + costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(1), a->getValue()); } else { - costr = Glib::ustring::format ((int)a->getValue()); + costr = Glib::ustring::format((int)a->getValue()); } if (a == brightness) { if (listener && getEnabled()) { - listener->panelChanged (EvLBrightness, costr); + listener->panelChanged(EvLBrightness, costr); } } else if (a == contrast) { if (listener && getEnabled()) { - listener->panelChanged (EvLContrast, costr); + listener->panelChanged(EvLContrast, costr); } } else if (a == rstprotection) { if (listener && getEnabled()) { - listener->panelChanged (EvLRSTProtection, costr); + listener->panelChanged(EvLRSTProtection, costr); } } else if (a == chromaticity) { if (multiImage) { //if chromaticity==-100 (lowest value), we enter the B&W mode and avoid color shift and rstprotection has no effect - rstprotection->set_sensitive( true ); - avoidcolorshift->set_sensitive( true ); - lcredsk->set_sensitive( true ); + rstprotection->set_sensitive(true); + lcredsk->set_sensitive(true); } else { //if chromaticity==-100 (lowest value), we enter the B&W mode and avoid color shift and rstprotection has no effect - rstprotection->set_sensitive( int(newval) > -100 ); //no reason for grey rstprotection - avoidcolorshift->set_sensitive( int(newval) > -100 ); - lcredsk->set_sensitive( int(newval) > -100 ); + rstprotection->set_sensitive(int(newval) > -100); //no reason for grey rstprotection + lcredsk->set_sensitive(int(newval) > -100); } if (listener && getEnabled()) { - listener->panelChanged (EvLSaturation, costr); + listener->panelChanged(EvLSaturation, costr); } } } -void LCurve::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) +void LCurve::colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { float R = 0.f, G = 0.f, B = 0.f; @@ -586,47 +628,54 @@ void LCurve::colorForValue (double valX, double valY, enum ColorCaller::ElemType float value = (1.f - 0.7f) * float(valX) + 0.7f; // whole hue range // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) - Color::hsv2rgb01(float(valY*0.8), float(valX), value, R, G, B); + Color::hsv2rgb01(float(valY * 0.8), float(valX), value, R, G, B); } else if (callerId == 6) { // cc - left bar float value = (1.f - 0.7f) * float(valX) + 0.7f; float hue = (1.14056f - 0.92f) * float(valY) + 0.92f; + if (hue > 1.0f) { hue -= 1.0f; } + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) Color::hsv2rgb01(hue, float(valX), value, R, G, B); } else if (callerId == 3) { // lc - bottom bar float value = (1.f - 0.7f) * float(valX) + 0.7f; + if (lcredsk->get_active()) { // skin range // -0.1 rad < Hue < 1.6 rad // Y axis / from 0.92 up to 0.14056 float hue = (1.14056f - 0.92f) * float(valY) + 0.92f; + if (hue > 1.0f) { hue -= 1.0f; } + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) Color::hsv2rgb01(hue, float(valX), value, R, G, B); } else { // whole hue range // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) - Color::hsv2rgb01(float(valY*0.8), float(valX), value, R, G, B); + Color::hsv2rgb01(float(valY * 0.8), float(valX), value, R, G, B); } } else if (callerId == 4) { // LH - bottom bar Color::hsv2rgb01(float(valX), 0.5f, float(valY), R, G, B); } else if (callerId == 5) { // HH - bottom bar float h = float((valY - 0.5) * 0.3 + valX); + if (h > 1.0f) { h -= 1.0f; } else if (h < 0.0f) { h += 1.0f; } + Color::hsv2rgb01(h, 0.5f, 0.5f, R, G, B); } else if (callerId == 7) { // cc and cl - left bar float value = (1.f - 0.7f) * float(valX) + 0.7f; // whole hue range // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) - Color::hsv2rgb01(float(valY*0.8), 1.f - float(valX), value, R, G, B); + Color::hsv2rgb01(float(valY * 0.8), 1.f - float(valX), value, R, G, B); } caller->ccRed = double(R); @@ -634,17 +683,19 @@ void LCurve::colorForValue (double valX, double valY, enum ColorCaller::ElemType caller->ccBlue = double(B); } -void LCurve::setBatchMode (bool batchMode) +void LCurve::setBatchMode(bool batchMode) { - ToolPanel::setBatchMode (batchMode); - brightness->showEditedCB (); - contrast->showEditedCB (); - chromaticity->showEditedCB (); - rstprotection->showEditedCB (); - curveEditorG->setBatchMode (batchMode); + ToolPanel::setBatchMode(batchMode); + brightness->showEditedCB(); + contrast->showEditedCB(); + chromaticity->showEditedCB(); + rstprotection->showEditedCB(); + curveEditorG->setBatchMode(batchMode); lcshape->setBottomBarColorProvider(nullptr, -1); lcshape->setLeftBarColorProvider(nullptr, -1); + gamutmunselmethod->append(M("GENERAL_UNCHANGED")); + } @@ -661,13 +712,13 @@ void LCurve::updateCurveBackgroundHistogram( const LUTu& histLRETI ) { - lshape->updateBackgroundHistogram (histLCurve); - ccshape->updateBackgroundHistogram (histCCurve); - lcshape->updateBackgroundHistogram (histCCurve); - clshape->updateBackgroundHistogram (histLCurve); + lshape->updateBackgroundHistogram(histLCurve); + ccshape->updateBackgroundHistogram(histCCurve); + lcshape->updateBackgroundHistogram(histCCurve); + clshape->updateBackgroundHistogram(histLCurve); } -void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) +void LCurve::setAdjusterBehavior(bool bradd, bool contradd, bool satadd) { brightness->setAddMode(bradd); @@ -675,7 +726,7 @@ void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) chromaticity->setAddMode(satadd); } -void LCurve::trimValues (rtengine::procparams::ProcParams* pp) +void LCurve::trimValues(rtengine::procparams::ProcParams* pp) { brightness->trimValue(pp->labCurve.brightness); @@ -687,11 +738,11 @@ void LCurve::enabledChanged() { if (listener) { if (get_inconsistent()) { - listener->panelChanged (EvLEnabled, M("GENERAL_UNCHANGED")); + listener->panelChanged(EvLEnabled, M("GENERAL_UNCHANGED")); } else if (getEnabled()) { - listener->panelChanged (EvLEnabled, M("GENERAL_ENABLED")); + listener->panelChanged(EvLEnabled, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvLEnabled, M("GENERAL_DISABLED")); + listener->panelChanged(EvLEnabled, M("GENERAL_DISABLED")); } } } diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index dfb79ae7a..5d762ea9e 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -59,11 +59,14 @@ protected: DiagonalCurveEditor* cdshape; //%%%%%%%%%%%%%%%% - Gtk::CheckButton* avoidcolorshift; Gtk::CheckButton* lcredsk; + MyComboBoxText* gamutmunselmethod; + sigc::connection gamutmunselmethodconn; + rtengine::ProcEvent Evgamutmunsell; + Adjuster* rstprotection; - sigc::connection bwtconn, acconn, lcconn; + sigc::connection bwtconn, lcconn; bool lastACVal, lastLCVal; //%%%%%%%%%%%%%%%% @@ -84,8 +87,8 @@ public: void curveChanged (CurveEditor* ce) override; void adjusterChanged (Adjuster* a, double newval) override; - void avoidcolorshift_toggled (); void lcredsk_toggled(); + void gamutmunselChanged(); void updateCurveBackgroundHistogram( const LUTu& histToneCurve, diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 4fb61c1c6..90312b22b 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -277,6 +277,18 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit } else { r->shapeMethod = 3; } + + if (pp->locallab.spots.at(i).avoidgamutMethod == "NONE") { + r->avoidgamutMethod = 0; + } else if (pp->locallab.spots.at(i).avoidgamutMethod == "LAB") { + r->avoidgamutMethod = 1; + } else if (pp->locallab.spots.at(i).avoidgamutMethod == "XYZ") { + r->avoidgamutMethod= 2; + } else if (pp->locallab.spots.at(i).avoidgamutMethod == "XYZREL") { + r->avoidgamutMethod= 3; + } else if (pp->locallab.spots.at(i).avoidgamutMethod == "MUNS") { + r->avoidgamutMethod= 4; + } r->locX = pp->locallab.spots.at(i).loc.at(0); r->locXL = pp->locallab.spots.at(i).loc.at(1); @@ -306,8 +318,6 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit r->avoidrad = pp->locallab.spots.at(i).avoidrad; r->hishow = pp->locallab.spots.at(i).hishow; r->activ = pp->locallab.spots.at(i).activ; - r->avoid = pp->locallab.spots.at(i).avoid; - r->avoidmun = pp->locallab.spots.at(i).avoidmun; r->blwh = pp->locallab.spots.at(i).blwh; r->recurs = pp->locallab.spots.at(i).recurs; r->laplac = true; //pp->locallab.spots.at(i).laplac; @@ -441,6 +451,18 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r->shapeMethod = 3; } + if (newSpot->avoidgamutMethod == "NONE") { + r->avoidgamutMethod = 0; + } else if (newSpot->avoidgamutMethod == "LAB") { + r->avoidgamutMethod = 1; + } else if (newSpot->avoidgamutMethod == "XYZ") { + r->avoidgamutMethod = 2; + } else if (newSpot->avoidgamutMethod == "XYZREL") { + r->avoidgamutMethod = 3; + } else if (newSpot->avoidgamutMethod == "MUNS") { + r->avoidgamutMethod = 4; + } + // Calculate spot size and center position according to preview area if (provider && !batchMode) { provider->getImageSize(imW, imH); @@ -488,8 +510,6 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r->avoidrad = newSpot->avoidrad; r->hishow = newSpot->hishow; r->activ = newSpot->activ; - r->avoid = newSpot->avoid; - r->avoidmun = newSpot->avoidmun; r->blwh = newSpot->blwh; r->recurs = newSpot->recurs; r->laplac = newSpot->laplac; @@ -742,6 +762,18 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r->shapeMethod = 3; } //printf("n0=%f n1=%f n2=%f n3=%f\n", (double) newSpot->loc.at(0), (double) newSpot->loc.at(1), (double) newSpot->loc.at(2), (double) newSpot->loc.at(3)); + if (newSpot->avoidgamutMethod == "NONE") { + r->avoidgamutMethod = 0; + } else if (newSpot->avoidgamutMethod == "LAB") { + r->avoidgamutMethod = 1; + } else if (newSpot->avoidgamutMethod== "XYZ") { + r->avoidgamutMethod = 2; + } else if (newSpot->avoidgamutMethod== "XYZREL") { + r->avoidgamutMethod = 3; + } else if (newSpot->avoidgamutMethod== "MUNS") { + r->avoidgamutMethod = 4; + } + //printf("n0=%f n1=%f n2=%f n3=%f\n", (double) newSpot->loc.at(0), (double) newSpot->loc.at(1), (double) newSpot->loc.at(2), (double) newSpot->loc.at(3)); // Calculate spot size and center position according to preview area if (provider && !batchMode) { @@ -799,8 +831,6 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r->colorscope = newSpot->colorscope; r->avoidrad = newSpot->avoidrad; r->activ = newSpot->activ; - r->avoid = newSpot->avoid; - r->avoidmun = newSpot->avoidmun; r->blwh = newSpot->blwh; r->recurs = newSpot->recurs; r->laplac = newSpot->laplac; @@ -927,6 +957,18 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).shapeMethod = "SYMSL"; } + if (r->avoidgamutMethod == 0) { + pp->locallab.spots.at(pp->locallab.selspot).avoidgamutMethod = "NONE"; + } else if (r->avoidgamutMethod == 1) { + pp->locallab.spots.at(pp->locallab.selspot).avoidgamutMethod = "LAB"; + } else if (r->avoidgamutMethod == 2) { + pp->locallab.spots.at(pp->locallab.selspot).avoidgamutMethod = "XYZ"; + } else if (r->avoidgamutMethod == 3) { + pp->locallab.spots.at(pp->locallab.selspot).avoidgamutMethod = "XYZREL"; + } else if (r->avoidgamutMethod == 4) { + pp->locallab.spots.at(pp->locallab.selspot).avoidgamutMethod = "MUNS"; + } + pp->locallab.spots.at(pp->locallab.selspot).loc.at(0) = r->locX; pp->locallab.spots.at(pp->locallab.selspot).loc.at(1) = r->locXL; pp->locallab.spots.at(pp->locallab.selspot).loc.at(2) = r->locY; @@ -955,8 +997,6 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).avoidrad = r->avoidrad; pp->locallab.spots.at(pp->locallab.selspot).hishow = r->hishow; pp->locallab.spots.at(pp->locallab.selspot).activ = r->activ; - pp->locallab.spots.at(pp->locallab.selspot).avoid = r->avoid; - pp->locallab.spots.at(pp->locallab.selspot).avoidmun = r->avoidmun; pp->locallab.spots.at(pp->locallab.selspot).blwh = r->blwh; pp->locallab.spots.at(pp->locallab.selspot).recurs = r->recurs; pp->locallab.spots.at(pp->locallab.selspot).laplac = r->laplac; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index acdda4e8a..7d641d753 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -104,7 +104,7 @@ void ParamsEdited::set(bool v) labCurve.brightness = v; labCurve.contrast = v; labCurve.chromaticity = v; - labCurve.avoidcolorshift = v; + labCurve.gamutmunselmethod = v; labCurve.rstprotection = v; labCurve.lcredsk = v; localContrast.enabled = v; @@ -804,7 +804,7 @@ void ParamsEdited::initFrom(const std::vector& labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness; labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast; labCurve.chromaticity = labCurve.chromaticity && p.labCurve.chromaticity == other.labCurve.chromaticity; - labCurve.avoidcolorshift = labCurve.avoidcolorshift && p.labCurve.avoidcolorshift == other.labCurve.avoidcolorshift; + labCurve.gamutmunselmethod = labCurve.gamutmunselmethod && p.labCurve.gamutmunselmethod == other.labCurve.gamutmunselmethod; labCurve.rstprotection = labCurve.rstprotection && p.labCurve.rstprotection == other.labCurve.rstprotection; labCurve.lcredsk = labCurve.lcredsk && p.labCurve.lcredsk == other.labCurve.lcredsk; @@ -908,7 +908,6 @@ void ParamsEdited::initFrom(const std::vector& vibrance.avoidcolorshift = vibrance.avoidcolorshift && p.vibrance.avoidcolorshift == other.vibrance.avoidcolorshift; vibrance.pastsattog = vibrance.pastsattog && p.vibrance.pastsattog == other.vibrance.pastsattog; vibrance.skintonescurve = vibrance.skintonescurve && p.vibrance.skintonescurve == other.vibrance.skintonescurve; - colorappearance.enabled = colorappearance.enabled && p.colorappearance.enabled == other.colorappearance.enabled; colorappearance.degree = colorappearance.degree && p.colorappearance.degree == other.colorappearance.degree; colorappearance.autodegree = colorappearance.autodegree && p.colorappearance.autodegree == other.colorappearance.autodegree; @@ -1090,6 +1089,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).structexclu = locallab.spots.at(j).structexclu && pSpot.structexclu == otherSpot.structexclu; locallab.spots.at(j).struc = locallab.spots.at(j).struc && pSpot.struc == otherSpot.struc; locallab.spots.at(j).shapeMethod = locallab.spots.at(j).shapeMethod && pSpot.shapeMethod == otherSpot.shapeMethod; + locallab.spots.at(j).avoidgamutMethod = locallab.spots.at(j).avoidgamutMethod && pSpot.avoidgamutMethod == otherSpot.avoidgamutMethod; locallab.spots.at(j).loc = locallab.spots.at(j).loc && pSpot.loc == otherSpot.loc; locallab.spots.at(j).centerX = locallab.spots.at(j).centerX && pSpot.centerX == otherSpot.centerX; locallab.spots.at(j).centerY = locallab.spots.at(j).centerY && pSpot.centerY == otherSpot.centerY; @@ -1109,8 +1109,6 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).transitgrad = locallab.spots.at(j).transitgrad && pSpot.transitgrad == otherSpot.transitgrad; locallab.spots.at(j).hishow = locallab.spots.at(j).hishow && pSpot.hishow == otherSpot.hishow; locallab.spots.at(j).activ = locallab.spots.at(j).activ && pSpot.activ == otherSpot.activ; - locallab.spots.at(j).avoid = locallab.spots.at(j).avoid && pSpot.avoid == otherSpot.avoid; - locallab.spots.at(j).avoidmun = locallab.spots.at(j).avoidmun && pSpot.avoidmun == otherSpot.avoidmun; locallab.spots.at(j).blwh = locallab.spots.at(j).blwh && pSpot.blwh == otherSpot.blwh; locallab.spots.at(j).recurs = locallab.spots.at(j).recurs && pSpot.recurs == otherSpot.recurs; locallab.spots.at(j).laplac = locallab.spots.at(j).laplac && pSpot.laplac == otherSpot.laplac; @@ -2392,8 +2390,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.labCurve.chromaticity = dontforceSet && options.baBehav[ADDSET_LC_CHROMATICITY] ? toEdit.labCurve.chromaticity + mods.labCurve.chromaticity : mods.labCurve.chromaticity; } - if (labCurve.avoidcolorshift) { - toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift; + if (labCurve.gamutmunselmethod) { + toEdit.labCurve.gamutmunselmethod = mods.labCurve.gamutmunselmethod; } if (labCurve.rstprotection) { @@ -3434,6 +3432,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).shapeMethod = mods.locallab.spots.at(i).shapeMethod; } + if (locallab.spots.at(i).avoidgamutMethod) { + toEdit.locallab.spots.at(i).avoidgamutMethod = mods.locallab.spots.at(i).avoidgamutMethod; + } + if (locallab.spots.at(i).loc) { toEdit.locallab.spots.at(i).loc = mods.locallab.spots.at(i).loc; } @@ -3510,14 +3512,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).activ = mods.locallab.spots.at(i).activ; } - if (locallab.spots.at(i).avoid) { - toEdit.locallab.spots.at(i).avoid = mods.locallab.spots.at(i).avoid; - } - - if (locallab.spots.at(i).avoidmun) { - toEdit.locallab.spots.at(i).avoidmun = mods.locallab.spots.at(i).avoidmun; - } - if (locallab.spots.at(i).blwh) { toEdit.locallab.spots.at(i).blwh = mods.locallab.spots.at(i).blwh; } @@ -7412,6 +7406,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : structexclu(v), struc(v), shapeMethod(v), + avoidgamutMethod(v), loc(v), centerX(v), centerY(v), @@ -7431,8 +7426,6 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : transitgrad(v), hishow(v), activ(v), - avoid(v), - avoidmun(v), blwh(v), recurs(v), laplac(v), @@ -8104,6 +8097,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) structexclu = v; struc = v; shapeMethod = v; + avoidgamutMethod = v; loc = v; centerX = v; centerY = v; @@ -8123,8 +8117,6 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) transitgrad = v; hishow = v; activ = v; - avoid = v; - avoidmun = v; blwh = v; recurs = v; laplac = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 56d71cfa3..616e6d261 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -109,7 +109,7 @@ struct LCurveParamsEdited { bool brightness; bool contrast; bool chromaticity; - bool avoidcolorshift; + bool gamutmunselmethod; bool rstprotection; bool lcurve; bool acurve; @@ -402,6 +402,7 @@ public: bool structexclu; bool struc; bool shapeMethod; + bool avoidgamutMethod; bool loc; bool centerX; bool centerY; @@ -421,8 +422,6 @@ public: bool transitgrad; bool hishow; bool activ; - bool avoid; - bool avoidmun; bool blwh; bool recurs; bool laplac; From ba11a9355ac76342368ba122b252fe372b328128 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Tue, 31 Jan 2023 23:42:36 -0800 Subject: [PATCH 170/326] mac: fixes lensfun logic Fixes use of the v1 lensfun interface for v0.3.3, v0.3.4-RC1, etc. --- tools/osx/macosx_bundle.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index d0cbf4d6b..26b8b4d08 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -191,13 +191,15 @@ lensfunversion=$(pkg-config --modversion lensfun | cut -f3 -d'.') if [ $lensfunversion = 95 ] then ditto ${LOCAL_PREFIX}/share/lensfun/version_2/* "${RESOURCES}/share/lensfun" + # Copy liblensfun to Frameworks + ditto ${LOCAL_PREFIX}/lib/liblensfun.2.dylib "${CONTENTS}/Frameworks/liblensfun.2.dylib" + else ditto ${LOCAL_PREFIX}/share/lensfun/version_1/* "${RESOURCES}/share/lensfun" + # Copy liblensfun to Frameworks + ditto ${LOCAL_PREFIX}/lib/liblensfun.1.dylib "${CONTENTS}/Frameworks/liblensfun.1.dylib" fi -# Copy liblensfun to Frameworks -ditto ${LOCAL_PREFIX}/lib/liblensfun.2.dylib "${CONTENTS}/Frameworks/liblensfun.2.dylib" - # Copy libomp to Frameworks ditto ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" From 0421a0acfab8e0c2dc83ae72df3719a981509bd6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 29 Jun 2021 14:36:53 +0200 Subject: [PATCH 171/326] fixed bug in handling raw border Fixes 189 (cherry picked from commit 10df3c06c37a4eb6f38aae2f4a711798af0c4884) --- rtengine/rawimagesource.cc | 37 +++++++++---------------------------- rtengine/rawimagesource.h | 2 +- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 728d71b3a..77a07183a 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1010,35 +1010,13 @@ void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementP colorSpaceConversion (image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); } -void RawImageSource::getFullSize (int& w, int& h, int tr) +void RawImageSource::getFullSize(int& w, int& h, int tr) { - computeFullSize(ri, tr, w, h); - - // tr = defTransform(ri, tr); - - // if (fuji) { - // w = ri->get_FujiWidth() * 2 + 1; - // h = (H - ri->get_FujiWidth()) * 2 + 1; - // } else if (d1x) { - // w = W; - // h = 2 * H; - // } else { - // w = W; - // h = H; - // } - - // if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { - // int tmp = w; - // w = h; - // h = tmp; - // } - - // w -= 2 * border; - // h -= 2 * border; + computeFullSize(ri, tr, w, h, border); } -void RawImageSource::computeFullSize(const RawImage *ri, int tr, int &w, int &h) +void RawImageSource::computeFullSize(const RawImage *ri, int tr, int &w, int &h, int border) { tr = defTransform(ri, tr); @@ -1046,7 +1024,10 @@ void RawImageSource::computeFullSize(const RawImage *ri, int tr, int &w, int &h) const int H = ri->get_height(); const bool fuji = ri->get_FujiWidth() != 0; const bool d1x = !ri->get_model().compare("D1X"); - const int border = (ri->getSensorType() == ST_BAYER ? 4 : (ri->getSensorType() == ST_FUJI_XTRANS ? 7 : 0)); + const int b = + border >= 0 ? border : + (ri->getSensorType() == ST_BAYER ? 4 : + (ri->getSensorType() == ST_FUJI_XTRANS ? 7 : 0)); if (fuji) { w = ri->get_FujiWidth() * 2 + 1; @@ -1065,8 +1046,8 @@ void RawImageSource::computeFullSize(const RawImage *ri, int tr, int &w, int &h) h = tmp; } - w -= 2 * border; - h -= 2 * border; + w -= 2 * b; + h -= 2 * b; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 9ef0086da..50b59e9dd 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -231,7 +231,7 @@ public: virtual float operator()(int row) const { return 1.f; } }; - static void computeFullSize(const RawImage *ri, int tr, int &w, int &h); + static void computeFullSize(const RawImage *ri, int tr, int &w, int &h, int border=-1); protected: typedef unsigned short ushort; From b8d25d542a4dae532001ed6e0f6342d2b865e670 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 5 Feb 2023 17:46:13 -0800 Subject: [PATCH 172/326] Fix crash reading Pentax metadata --- rtengine/imagedata.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4dbc3f0a0..bf80f8c51 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -430,7 +430,6 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : ) { if (find_exif_tag("Exif.Pentax.DriveMode")) { std::string buf = pos->toString(3); - buf[3] = 0; if (buf == "HDR") { isHDR = true; #if PRINT_HDR_PS_DETECTION From a3adbce04b91f2cbb892d810df92805b216db4d2 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Mon, 6 Feb 2023 19:00:14 +0100 Subject: [PATCH 173/326] Support for Nikon Z9 --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 7a143e850..07f08d9a6 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1973,6 +1973,11 @@ Camera constants: "dcraw_matrix" : [13705, -6004, -1401, -5464, 13568, 2062, -940, 1706, 7618] // DNG }, + { // Quality C + "make_model" : "NIKON Z 9", + "dcraw_matrix" : [13389, -6049, -1441, -4544, 12757, 1969, 229, 498, 7390] //DNG + }, + { // Quality C, only color matrix and PDAF lines info "make_model" : "Nikon Z 6", "dcraw_matrix" : [8210, -2534, -683, -5355, 13338, 2212, -1143, 1928, 6464], // DNG v13.2 From 12ef477a6d6e150d513161b634661fdb688764f3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:44:57 -0800 Subject: [PATCH 174/326] Fix merge issues Adapt tone equalizer to favorites tab changes. --- rtgui/toneequalizer.cc | 3 ++- rtgui/toneequalizer.h | 2 ++ rtgui/toollocationpref.cc | 2 ++ rtgui/toolpanelcoord.cc | 7 +++++++ rtgui/toolpanelcoord.h | 1 + 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc index de748c2b7..d524bdc05 100644 --- a/rtgui/toneequalizer.cc +++ b/rtgui/toneequalizer.cc @@ -25,8 +25,9 @@ using namespace rtengine; using namespace rtengine::procparams; +const Glib::ustring ToneEqualizer::TOOL_NAME = "toneequalizer"; -ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, "toneequalizer", M("TP_TONE_EQUALIZER_LABEL"), false, true) +ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, TOOL_NAME, M("TP_TONE_EQUALIZER_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); EvEnabled = m->newEvent(AUTOEXP, "HISTORY_MSG_TONE_EQUALIZER_ENABLED"); diff --git a/rtgui/toneequalizer.h b/rtgui/toneequalizer.h index 657167f05..88a275799 100644 --- a/rtgui/toneequalizer.h +++ b/rtgui/toneequalizer.h @@ -28,6 +28,8 @@ class ToneEqualizer: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CheckBoxListener { public: + static const Glib::ustring TOOL_NAME; + ToneEqualizer(); void read(const rtengine::procparams::ProcParams *pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index cf25dbc34..a2e2c9480 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -70,6 +70,8 @@ Glib::ustring getToolTitleKey(Tool tool) return "TP_EXPOSURE_LABEL"; case Tool::SHADOWS_HIGHLIGHTS: return "TP_SHADOWSHLIGHTS_LABEL"; + case Tool::TONE_EQUALIZER: + return "TP_TONE_EQUALIZER_LABEL"; case Tool::IMPULSE_DENOISE: return "TP_IMPULSEDENOISE_LABEL"; case Tool::DEFRINGE_TOOL: diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 0a8a510c7..e9b0ce5cc 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -44,6 +44,9 @@ const std::vector EXPOSURE_PANEL_TOOLS = { { .id = Tool::SHADOWS_HIGHLIGHTS, }, + { + .id = Tool::TONE_EQUALIZER, + }, { .id = Tool::EPD, }, @@ -562,6 +565,8 @@ std::string ToolPanelCoordinator::getToolName(Tool tool) return ToneCurve::TOOL_NAME; case Tool::SHADOWS_HIGHLIGHTS: return ShadowsHighlights::TOOL_NAME; + case Tool::TONE_EQUALIZER: + return ToneEqualizer::TOOL_NAME; case Tool::IMPULSE_DENOISE: return ImpulseDenoise::TOOL_NAME; case Tool::DEFRINGE_TOOL: @@ -1908,6 +1913,8 @@ FoldableToolPanel *ToolPanelCoordinator::getFoldableToolPanel(Tool tool) const return toneCurve; case Tool::SHADOWS_HIGHLIGHTS: return shadowshighlights; + case Tool::TONE_EQUALIZER: + return toneEqualizer; case Tool::IMPULSE_DENOISE: return impulsedenoise; case Tool::DEFRINGE_TOOL: diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index e7338c90b..bc1e1a2d3 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -247,6 +247,7 @@ public: enum class Tool { TONE_CURVE, SHADOWS_HIGHLIGHTS, + TONE_EQUALIZER, IMPULSE_DENOISE, DEFRINGE_TOOL, SPOT, From e5d46032ffbe8b21946019203260ab1aefe9c483 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 9 Feb 2023 07:14:20 +0100 Subject: [PATCH 175/326] Add "Inpaint opposed" to Highlight reconstruction and improved Itcwb (#6635) * Essai HL * Try Inpaint opposed * Code improvment * Add file * Improvment to process inpaint opposed and color propagation * Clean code * Change Blend to Coloropp in Profile pp3 * Enable BENCHFUN hilite_recon * Clean rtengine cmakelist * Comment unused code * Neutralise unused code * Change bad Exposure in Pop2Lab.pp3 * Try to fix bug when Inpaint Opposed is used and White balance disabled * Changes to refreshmap * Change to improccoordinator M_RETINEX * Clean unused commented code * Force Inpaint-opposed in rawimagesouce if wb change * Suppressed message in console * Change events and limits to 1 the number of calls to inpaint-opposed * Comment code * Add gain theshold to inpaint opposed * fixed typo in procparams.cc * Change in option.cc itcwb_sort to true * Change itcw sorted in options and rawimagesource.cc * Change sampling read datas Itcwb * Allow or not purple in WB itcwb * Added option icwb.nopurple to bypass settings * Added code comment Itcwb * optimize Itcwb between green and student * Formated code used by Itcwb with Astylert.bat * Change color_match - thanks to Lawrence37 * Remove wrong text --- rtdata/languages/default | 3 + .../Auto-Matched Curve - ISO High.pp3 | 2 +- .../profiles/Auto-Matched Curve - ISO Low.pp3 | 2 +- .../Auto-Matched Curve - ISO Medium.pp3 | 2 +- .../Film Negative - Black and White.pp3 | 2 +- rtdata/profiles/Film Negative.pp3 | 2 +- rtdata/profiles/Pop/Pop 1.pp3 | 2 +- rtdata/profiles/Pop/Pop 2 Lab.pp3 | 2 +- rtdata/profiles/Pop/Pop 3 Skin.pp3 | 2 +- rtdata/profiles/Pop/Pop 4 Black-and-White.pp3 | 2 +- .../Standard Film Curve - ISO High.pp3 | 2 +- .../Standard Film Curve - ISO Low.pp3 | 2 +- .../Standard Film Curve - ISO Medium.pp3 | 2 +- rtengine/clutstore.cc | 2 +- rtengine/colortemp.cc | 91 +- rtengine/colortemp.h | 14 +- rtengine/dcrop.cc | 12 +- rtengine/filmnegativeproc.cc | 2 +- rtengine/hilite_recon.cc | 373 ++++++- rtengine/iimage.h | 2 +- rtengine/imagesource.h | 9 +- rtengine/improccoordinator.cc | 29 +- rtengine/iplocallab.cc | 2 +- rtengine/linalgebra.h | 275 ++++++ rtengine/perspectivecorrection.cc | 2 +- rtengine/previewimage.cc | 2 +- rtengine/procparams.cc | 7 +- rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 927 +++++++++++------- rtengine/rawimagesource.h | 14 +- rtengine/refreshmap.cc | 2 +- rtengine/rtthumbnail.cc | 2 +- rtengine/settings.h | 4 +- rtengine/simpleprocess.cc | 8 +- rtengine/spot.cc | 4 +- rtengine/stdimagesource.cc | 22 +- rtengine/stdimagesource.h | 8 +- rtgui/options.cc | 22 +- rtgui/paramsedited.cc | 6 + rtgui/paramsedited.h | 1 + rtgui/tonecurve.cc | 80 +- rtgui/tonecurve.h | 2 + 42 files changed, 1455 insertions(+), 497 deletions(-) create mode 100644 rtengine/linalgebra.h diff --git a/rtdata/languages/default b/rtdata/languages/default index 68fda352b..84b28c955 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1417,6 +1417,7 @@ 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 @@ -2518,8 +2519,10 @@ TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. TP_HLREC_BLEND;Blend TP_HLREC_CIELAB;CIELab Blending TP_HLREC_COLOR;Color Propagation +TP_HLREC_COLOROPP;Inpaint Opposed TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. TP_HLREC_HLBLUR;Blur +TP_HLREC_HLTH;Gain threshold TP_HLREC_LABEL;Highlight reconstruction TP_HLREC_LUMINANCE;Luminance Recovery TP_HLREC_METHOD;Method: diff --git a/rtdata/profiles/Auto-Matched Curve - ISO High.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO High.pp3 index 99f0af8fe..16c9a71f5 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO High.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO High.pp3 @@ -4,7 +4,7 @@ HistogramMatching=true [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Directional Pyramid Denoising] Enabled=true diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 index c94077b21..e6c7fb96c 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 @@ -4,7 +4,7 @@ HistogramMatching=true [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [LensProfile] LcMode=lfauto diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Medium.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Medium.pp3 index f9196bb30..ffb5587b9 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO Medium.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO Medium.pp3 @@ -4,7 +4,7 @@ HistogramMatching=true [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Directional Pyramid Denoising] Enabled=true diff --git a/rtdata/profiles/Film Negative - Black and White.pp3 b/rtdata/profiles/Film Negative - Black and White.pp3 index ad2a38e1e..3bebe7e3c 100644 --- a/rtdata/profiles/Film Negative - Black and White.pp3 +++ b/rtdata/profiles/Film Negative - Black and White.pp3 @@ -11,7 +11,7 @@ Curve2=1;0;0;0.0397505754145333;0.020171771436200074;0.54669745433149319;0.69419 [HLRecovery] Enabled=false -Method=Blend +Method=Coloropp [Black & White] Enabled=true diff --git a/rtdata/profiles/Film Negative.pp3 b/rtdata/profiles/Film Negative.pp3 index 0ecac1d33..e76c61866 100644 --- a/rtdata/profiles/Film Negative.pp3 +++ b/rtdata/profiles/Film Negative.pp3 @@ -11,7 +11,7 @@ Curve2=1;0;0;0.0397505754145333;0.020171771436200074;0.54669745433149319;0.69419 [HLRecovery] Enabled=false -Method=Blend +Method=Coloropp [Crop] FixedRatio=false diff --git a/rtdata/profiles/Pop/Pop 1.pp3 b/rtdata/profiles/Pop/Pop 1.pp3 index 2152a268b..cbdf4ab5b 100644 --- a/rtdata/profiles/Pop/Pop 1.pp3 +++ b/rtdata/profiles/Pop/Pop 1.pp3 @@ -19,7 +19,7 @@ Curve2=0; [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Luminance Curve] Enabled=true diff --git a/rtdata/profiles/Pop/Pop 2 Lab.pp3 b/rtdata/profiles/Pop/Pop 2 Lab.pp3 index 796aeb5ba..f4c01fd1b 100644 --- a/rtdata/profiles/Pop/Pop 2 Lab.pp3 +++ b/rtdata/profiles/Pop/Pop 2 Lab.pp3 @@ -19,7 +19,7 @@ Curve2=0; [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Luminance Curve] Enabled=true diff --git a/rtdata/profiles/Pop/Pop 3 Skin.pp3 b/rtdata/profiles/Pop/Pop 3 Skin.pp3 index 650b2e189..ebce37b58 100644 --- a/rtdata/profiles/Pop/Pop 3 Skin.pp3 +++ b/rtdata/profiles/Pop/Pop 3 Skin.pp3 @@ -19,7 +19,7 @@ Curve2=0; [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Luminance Curve] Enabled=true diff --git a/rtdata/profiles/Pop/Pop 4 Black-and-White.pp3 b/rtdata/profiles/Pop/Pop 4 Black-and-White.pp3 index 9faa32a0a..1e3527ceb 100644 --- a/rtdata/profiles/Pop/Pop 4 Black-and-White.pp3 +++ b/rtdata/profiles/Pop/Pop 4 Black-and-White.pp3 @@ -19,7 +19,7 @@ Curve2=0; [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Black & White] Enabled=true diff --git a/rtdata/profiles/Standard Film Curve - ISO High.pp3 b/rtdata/profiles/Standard Film Curve - ISO High.pp3 index 4dd3a9b1d..42bbed6d3 100644 --- a/rtdata/profiles/Standard Film Curve - ISO High.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO High.pp3 @@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0. [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Directional Pyramid Denoising] Enabled=true diff --git a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 index 45fcca730..342b1c8d3 100644 --- a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 @@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0. [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [LensProfile] LcMode=lfauto diff --git a/rtdata/profiles/Standard Film Curve - ISO Medium.pp3 b/rtdata/profiles/Standard Film Curve - ISO Medium.pp3 index 4aff630f5..f3b292094 100644 --- a/rtdata/profiles/Standard Film Curve - ISO Medium.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO Medium.pp3 @@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0. [HLRecovery] Enabled=true -Method=Blend +Method=Coloropp [Directional Pyramid Denoising] Enabled=true diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index e3bd9c988..4c70ad951 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -57,7 +57,7 @@ bool loadFile( rtengine::procparams::ColorManagementParams icm; icm.workingProfile = working_color_space; - img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams()); + img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams(), 0); if (!working_color_space.empty()) { img_src.convertColorSpace(img_float.get(), icm, curr_wb); diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index a4dd8a4d1..4ba47b25a 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -33,7 +33,7 @@ namespace rtengine { -static double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. +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}, {0.001368, 0.000039, 0.006450001}, {0.002236, 0.000064, 0.01054999}, {0.004243, 0.000120, 0.02005001}, @@ -70,7 +70,7 @@ static double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2 }; -static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. +static const color_match_type cie_colour_match_jd = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. {0.000000000000, 0.000000000000, 0.000000000000}, {0.000000000000, 0.000000000000, 0.000000000000}, {0.000000122200, 0.000000013398, 0.000000535027}, @@ -2963,15 +2963,16 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxy // We first test for specially handled methods const auto iterator = spectMap.find(method); + const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; if (iterator != spectMap.end()) { - spectrum_to_xyz_preset(iterator->second, x, y, z); + spectrum_to_xyz_preset(iterator->second, x, y, z, color_match); } else { // otherwise we use the Temp+Green generic solution if (temp <= INITIALBLACKBODY) { // if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K... // of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw). - spectrum_to_xyz_blackbody(temp, x, y, z); + spectrum_to_xyz_blackbody(temp, x, y, z, color_match); } else { // from 4000K up to 25000K: using the D illuminant (daylight) which is standard double x_D, y_D; @@ -2990,7 +2991,7 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxy double interm = 0.0241 + 0.2562 * x_D - 0.734 * y_D; double m1 = (-1.3515 - 1.7703 * x_D + 5.9114 * y_D) / interm; double m2 = (0.03 - 31.4424 * x_D + 30.0717 * y_D) / interm; - spectrum_to_xyz_daylight(m1, m2, x, y, z); + spectrum_to_xyz_daylight(m1, m2, x, y, z, color_match); } } @@ -3169,17 +3170,19 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, float CRI_RT = 0.0, CRI[50]; float CRI_RTs = 0.0, CRIs[8]; + const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; + for(int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i]); + spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i], color_match); } //calculate XYZ for each color : for Blackbody and Daylight at tempw if(tempw <= INITIALBLACKBODY) { for(int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_blackbody(spec_color[i], tempw, Xchk[i], Ychk[i], Zchk[i]); + spectrum_to_color_xyz_blackbody(spec_color[i], tempw, Xchk[i], Ychk[i], Zchk[i], color_match); } - spectrum_to_xyz_blackbody(tempw, x, y, z);//for white point + spectrum_to_xyz_blackbody(tempw, x, y, z, color_match);//for white point } else { // after 6600K (arbitrary) I use daylight...because ...but there is no lamp... double m11, m22, x_DD, y_DD, interm2; @@ -3197,10 +3200,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; for(int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_daylight(spec_color[i], m11, m22, Xchk[i], Ychk[i], Zchk[i]); + spectrum_to_color_xyz_daylight(spec_color[i], m11, m22, Xchk[i], Ychk[i], Zchk[i], color_match); } - spectrum_to_xyz_daylight(m11, m22, x, y, z); + spectrum_to_xyz_daylight(m11, m22, x, y, z, color_match); } if (settings->verbose) { @@ -3394,16 +3397,16 @@ I have increase precision used by J.Walker and pass to 350nm to 830nm And also add 10° standard observer */ -void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z) +void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0, XYZ; for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = daylight_spect(lambda, _m1, _m2); - X += Me * cie_colour_match_jd2[i][0]; - Y += Me * cie_colour_match_jd2[i][1]; - Z += Me * cie_colour_match_jd2[i][2]; + X += Me * color_match[i][0]; + Y += Me * color_match[i][1]; + Z += Me * color_match[i][2]; } XYZ = (X + Y + Z); @@ -3412,16 +3415,16 @@ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, doub z = Z / XYZ; } -void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z) +void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0, XYZ; for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = blackbody_spect(lambda, _temp); - X += Me * cie_colour_match_jd2[i][0]; - Y += Me * cie_colour_match_jd2[i][1]; - Z += Me * cie_colour_match_jd2[i][2]; + X += Me * color_match[i][0]; + Y += Me * color_match[i][1]; + Z += Me * color_match[i][2]; } XYZ = (X + Y + Z); @@ -3430,7 +3433,7 @@ void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, do z = Z / XYZ; } -void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z) +void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0, XYZ; @@ -3454,9 +3457,9 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou */ for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = get_spectral_color(lambda, spec_intens); - X += Me * cie_colour_match_jd2[i][0]; - Y += Me * cie_colour_match_jd2[i][1]; - Z += Me * cie_colour_match_jd2[i][2]; + X += Me * color_match[i][0]; + Y += Me * color_match[i][1]; + Z += Me * color_match[i][2]; } XYZ = (X + Y + Z); @@ -3466,7 +3469,7 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou } //calculate XYZ from spectrum data (color) and illuminant : J.Desmis December 2011 -void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz) +void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0, Yo = 0; @@ -3478,9 +3481,9 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou Me = get_spectral_color(lambda, spec_color); Mc = get_spectral_color(lambda, spec_intens); - X += Mc * cie_colour_match_jd2[i][0] * Me; - Y += Mc * cie_colour_match_jd2[i][1] * Me; - Z += Mc * cie_colour_match_jd2[i][2] * Me; + X += Mc * color_match[i][0] * Me; + Y += Mc * color_match[i][1] * Me; + Z += Mc * color_match[i][2] * Me; } for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { @@ -3488,7 +3491,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou double Ms; Ms = get_spectral_color(lambda, spec_intens); - Yo += cie_colour_match_jd2[i][1] * Ms; + Yo += color_match[i][1] * Ms; } xx = X / Yo; @@ -3497,7 +3500,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou } //calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 -void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz) +void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0; @@ -3505,9 +3508,9 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; const double Mc = daylight_spect(lambda, _m1, _m2); - X += Mc * cie_colour_match_jd2[i][0] * Me; - Y += Mc * cie_colour_match_jd2[i][1] * Me; - Z += Mc * cie_colour_match_jd2[i][2] * Me; + X += Mc * color_match[i][0] * Me; + Y += Mc * color_match[i][1] * Me; + Z += Mc * color_match[i][2] * Me; } xx = X / Y; @@ -3516,7 +3519,7 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double } //calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 -void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz) +void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match) { int i; double lambda, X = 0, Y = 0, Z = 0; @@ -3524,9 +3527,9 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; const double Mc = blackbody_spect(lambda, _temp); - X += Mc * cie_colour_match_jd2[i][0] * Me; - Y += Mc * cie_colour_match_jd2[i][1] * Me; - Z += Mc * cie_colour_match_jd2[i][2] * Me; + X += Mc * color_match[i][0] * Me; + Y += Mc * color_match[i][1] * Me; + Z += Mc * color_match[i][2] * Me; } xx = X / Y; @@ -3762,27 +3765,21 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float } if (settings->verbose) { - if (settings->itcwb_stdobserver10 == false) { + if (settings->itcwb_stdobserver10 == false) {//I will try to change settings by main printf("Use standard observer 2°\n"); } else { printf("Use standard observer 10°\n"); } } - if (settings->itcwb_stdobserver10 == true) { - for (int i = 0; i < 97; i++) { - cie_colour_match_jd2[i][0] = cie_colour_match_jd[i][0]; - cie_colour_match_jd2[i][1] = cie_colour_match_jd[i][1];; - cie_colour_match_jd2[i][2] = cie_colour_match_jd[i][2]; - } - } + const color_match_type &color_match = (settings->itcwb_stdobserver10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; if (separated) { const double tempw = Txyz[repref].Tem; if (tempw <= INITIALBLACKBODY) { for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i]); + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i], color_match); } } else { double m11, m22, x_DD, y_DD, interm2; @@ -3801,7 +3798,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i]); + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i], color_match); } } } else { @@ -3810,7 +3807,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float if (tempw <= INITIALBLACKBODY) { for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref); + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); } } else { double x_DD; @@ -3829,7 +3826,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float const double m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref); + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); } } diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index 89c324490..78091f51d 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -26,6 +26,8 @@ namespace rtengine { +using color_match_type = double [97][3]; + constexpr double MINTEMP = 1500.0; constexpr double MAXTEMP = 60000.0; constexpr double MINGREEN = 0.02; @@ -375,13 +377,13 @@ public: static const double JDC468_greym13_325_spect[97]; static const double JDC468_greyf26_156_spect[97]; */ - static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z); - static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z); - static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z); + static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z, const color_match_type &color_match); + static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z, const color_match_type &color_match); + static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z, const color_match_type &color_match); - static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz); - static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz); - static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match); + static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match); + static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz, const color_match_type &color_match); }; } diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index f4ac49fc4..8ddaa5f75 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -228,18 +228,18 @@ void Crop::update(int todo) if (settings->leveldnautsimpl == 1) { if (params.dirpyrDenoise.Cmethod == "MAN" || params.dirpyrDenoise.Cmethod == "PON") { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); } } else { if (params.dirpyrDenoise.C2method == "MANU") { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); } } if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PRE") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "PREV")) { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); if ((!isDetailWindow) && parent->adnListener && skip == 1 && params.dirpyrDenoise.enabled) { float lowdenoise = 1.f; @@ -451,7 +451,7 @@ void Crop::update(int todo) for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1); - parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); // we only need image reduced to 1/4 here for (int ii = 0; ii < crH; ii += 2) { @@ -613,7 +613,7 @@ void Crop::update(int todo) // if (params.dirpyrDenoise.Cmethod=="AUT" || params.dirpyrDenoise.Cmethod=="PON") {//reinit origCrop after Auto if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { //reinit origCrop after Auto PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); } if ((todo & M_SPOT) && params.spot.enabled && !params.spot.entries.empty()) { @@ -749,7 +749,7 @@ void Crop::update(int todo) fattalCrop.reset(f); PreviewProps pp(0, 0, parent->fw, parent->fh, skip); int tr = getCoarseBitMask(params.coarse); - parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw); + parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw, 0); parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB); if (params.dirpyrDenoise.enabled || params.filmNegative.enabled || params.spot.enabled) { diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index ae1813db9..c33dc4a9a 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -84,7 +84,7 @@ void getSpotAvgMax(ImageSource *imgsrc, ColorTemp currWB, const std::unique_ptr< } rtengine::Imagefloat spotImg(spotSize, spotSize); - imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw); + imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw, 0); auto avgMax = [spotSize, &spotImg](RGB & avg, RGB & max) -> void { avg = {}; diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index a45e5d345..07d1a7b7b 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -32,14 +32,15 @@ #include "opthelper.h" #include "rawimagesource.h" #include "rt_math.h" -//#define BENCHMARK -//#include "StopWatch.h" +#define BENCHMARK +#include "StopWatch.h" #include "guidedfilter.h" #include "settings.h" #include "gauss.h" #include "rescale.h" #include "iccstore.h" #include "color.h" +#include "linalgebra.h" namespace { @@ -301,7 +302,7 @@ using namespace procparams; void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue, int blur) { - // BENCHFUN + BENCHFUN double progress = 0.0; if (plistener) { @@ -1226,5 +1227,371 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue }// end of HLReconstruction + +//----------------------------------------------------------------------------- +// "inpaint opposed" algorithm taken from darktable +// +// (Very effective, very simple, very neat) +// +// Kudos to the original authors (@jenshannoschwalm from dt, in collaboration +// with @garagecoder and @Iain from gmic). +// +// Copyright and description of the original code follows +// +/* + Copyright (C) 2022 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 . +*/ + +/* The refavg values are calculated in raw-RGB-cube3 space + We calculate all color channels in the 3x3 photosite area, this can be understaood as a "superpixel", + the "asking" location is in the centre. + As this works for bayer and xtrans sensors we don't have a fixed ratio but calculate the average + for every color channel first. + refavg for one of red, green or blue is defined as means of both other color channels (opposing). + + The basic idea / observation for the _process_opposed algorithm is, the refavg is a good estimate + for any clipped color channel in the vast majority of images, working mostly fine both for small specular + highlighted spots and large areas. + + The correction via some sort of global chrominance further helps to correct color casts. + The chrominace data are taken from the areas morphologically very close to clipped data. + Failures of the algorithm (color casts) are in most cases related to + a) very large differences between optimal white balance coefficients vs what we have as D65 in the darktable pipeline + b) complicated lightings so the gradients are not well related + c) a wrong whitepoint setting in the rawprepare module. + d) the maths might not be best +*/ +//----------------------------------------------------------------------------- + +namespace { + +constexpr int HL_BORDER = 8; +constexpr float HL_POWERF = 3.0f; + +// void border_fill_zero(int *d, int width, int height) +// { +// for (int i = 0; i < HL_BORDER * width; i++) { +// d[i] = 0; +// } +// for (int i = (height - HL_BORDER - 1) * width; i < width*height; i++) { +// d[i] = 0; +// } +// for (int row = HL_BORDER; row < height - HL_BORDER; row++) { +// int *p1 = d + row*width; +// int *p2 = d + (row+1)*width - HL_BORDER; +// for(int i = 0; i < HL_BORDER; i++) { +// p1[i] = p2[i] = 0; +// } +// } +// } + + +int test_dilate(const int *img, int i, int w1) +{ + int retval = 0; + retval = img[i-w1-1] | img[i-w1] | img[i-w1+1] | + img[i-1] | img[i] | img[i+1] | + img[i+w1-1] | img[i+w1] | img[i+w1+1]; + if (retval) { + return retval; + } + + const size_t w2 = 2*w1; + retval = img[i-w2-1] | img[i-w2] | img[i-w2+1] | + img[i-w1-2] | img[i-w1+2] | + img[i-2] | img[i+2] | + img[i+w1-2] | img[i+w1+2] | + img[i+w2-1] | img[i+w2] | img[i+w2+1]; + if (retval) { + return retval; + } + + const size_t w3 = 3*w1; + retval = img[i-w3-2] | img[i-w3-1] | img[i-w3] | img[i-w3+1] | img[i-w3+2] | + img[i-w2-3] | img[i-w2-2] | img[i-w2+2] | img[i-w2+3] | + img[i-w1-3] | img[i-w1+3] | + img[i-3] | img[i+3] | + img[i+w1-3] | img[i+w1+3] | + img[i+w2-3] | img[i+w2-2] | img[i+w2+2] | img[i+w2+3] | + img[i+w3-2] | img[i+w3-1] | img[i+w3] | img[i+w3+1] | img[i+w3+2]; + return retval; +} + + +void dilating(const int *img, int *o, int w1, int height) +{ +#ifdef _OPENMP +# pragma omp parallel for +#endif + for (int row = HL_BORDER; row < height - HL_BORDER; row++) { + for (int col = HL_BORDER, i = row*w1 + col; col < w1 - HL_BORDER; col++, i++) { + o[i] = test_dilate(img, i, w1); + } + } +} + +} // namespace + +void RawImageSource::highlight_recovery_opposed(float scale_mul[3], const ColorTemp &wb, float gainth) +{ + BENCHFUN + + if (settings->verbose) { + std::cout << "Applying Highlight Recovery: Inpaint opposed" << std::endl; + } + + if (plistener) { + plistener->setProgressStr("PROGRESSBAR_HLREC"); + plistener->setProgress(0); + } + + double rr, gg, bb; + wb.getMultipliers(rr, gg, bb); + wbMul2Camera(rr, gg, bb); + + float gain = 1.2f * gainth; + + float clipval = 0.987f / gain; + const float scalecoeffs[3] = { + scale_mul[0] * float(rr) / 65535.f, + scale_mul[1] * float(gg) / 65535.f, + scale_mul[2] * float(bb) / 65535.f, + }; + const float clips[3] = { + clipval * float(rr), + clipval * float(gg), + clipval * float(bb) + }; + const float clipdark[3] = { + 0.03f * clips[0], + 0.125f * clips[1], + 0.03f * clips[2] + }; + + bool anyclipped = false; + float **chan[3] = { red, green, blue }; + + const float clipscale[3] = { + clips[0] / scalecoeffs[0], + clips[1] / scalecoeffs[1], + clips[2] / scalecoeffs[2] + }; + + int x1 = W, y1 = H, x2 = 0, y2 = 0; + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + for (int c = 0; c < 3; ++c) { + if (chan[c][y][x] >= clipscale[c]) { + anyclipped = true; + x1 = std::min(x, x1); + x2 = std::max(x, x2); + y1 = std::min(y, y1); + y2 = std::max(y, y2); + } + } + } + } + + if (!anyclipped) { + if (plistener) { + plistener->setProgress(1.0); + } + return; + } + + x1 = std::max(x1-1, 0); + x2 = std::min(x2+1, W-1); + y1 = std::max(y1-1, 0); + y2 = std::min(y2+1, H-1); + + const int cW = x2 - x1 + 1; + const int cH = y2 - y1 + 1; + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for (int y = 0; y < cH; ++y) { + const int yy = y + y1; + for (int x = 0; x < cW; ++x) { + const int xx = x + x1; + for (int c = 0; c < 3; ++c) { + chan[c][yy][xx] *= scalecoeffs[c]; + } + } + } + + if (plistener) { + plistener->setProgress(0.1); + } + + multi_array2D tmp(cW, cH); + + const int pwidth = cW + 2 * HL_BORDER; + const int pheight = cH + 2 * HL_BORDER; + const int p_size = pwidth * pheight; + AlignedBuffer mask_vec(4 * p_size); + int *mask_buffer = mask_vec.data; + + const auto mask_val = + [&](int c, int y, int x) -> int & + { + return mask_buffer[c * p_size + (HL_BORDER + y) * pwidth + x + HL_BORDER]; + }; + + const auto set_refavg = + [&](int y, int x) -> bool + { + const int yy = y + y1; + const int xx = x + x1; + bool found = false; + for (int c = 0; c < 3 && !found; ++c) { + if (chan[c][yy][xx] >= clips[c]) { + found = true; + } + } + if (!found) { + return false; + } + + float mean[3] = { 0.0f, 0.0f, 0.0f }; + for (int dy = -1; dy < 2; dy++) { + for (int dx = -1; dx < 2; dx++) { + for (int c = 0; c < 3; ++c) { + mean[c] += std::max(0.0f, chan[c][yy+dy][xx+dx]); + } + } + } + for (int c = 0; c < 3; ++c) { + mean[c] = pow_F(mean[c] / 9.0f, 1.0f / HL_POWERF); + } + + const float croot_refavg[3] = { + 0.5f * (mean[1] + mean[2]), + 0.5f * (mean[0] + mean[2]), + 0.5f * (mean[0] + mean[1]) + }; + + for (int c = 0; c < 3; ++c) { + if (chan[c][yy][xx] >= clips[c]) { + tmp[c][y][x] = pow_F(croot_refavg[c], HL_POWERF); + mask_val(c, y, x) = 1; + } + } + return true; + }; + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for (int y = 0; y < cH; ++y) { + const int yy = y + y1; + for (int x = 0; x < cW; ++x) { + const int xx = x + x1; + for (int c = 0; c < 3; ++c) { + tmp[c][y][x] = std::max(0.f, chan[c][yy][xx]); + } + + if ((x > 0) && (x < cW - 1) && (y > 0) && (y < cH - 1)) { + set_refavg(y, x); + } + } + } + + if (plistener) { + plistener->setProgress(0.3); + } + + for (size_t i = 0; i < 3; i++) { + int *mask = mask_buffer + i * p_size; + int *tmp = mask_buffer + 3 * p_size; + //border_fill_zero(mask, pwidth, pheight); + dilating(mask, tmp, pwidth, pheight); + memcpy(mask, tmp, p_size * sizeof(int)); + } + + float cr_sum[3] = { 0.f, 0.f, 0.f }; + int cr_cnt[3] = { 0, 0, 0 }; + +#ifdef _OPENMP +# pragma omp parallel for reduction(+ : cr_sum, cr_cnt) +#endif + for (int y = 1; y < cH-1; ++y) { + const int yy = y + y1; + for (int x = 1; x < cW-1; ++x) { + const int xx = x + x1; + for (int c = 0; c < 3; ++c) { + const float inval = std::max(0.0f, chan[c][yy][xx]); + if (mask_val(c, y, x) && (inval > clipdark[c]) && (inval < clips[c])) { + cr_sum[c] += inval - tmp[c][y][x]; + ++cr_cnt[c]; + } + } + } + } + + if (plistener) { + plistener->setProgress(0.6); + } + + float chrominance[3] = { + cr_sum[0] / std::max(1.f, float(cr_cnt[0])), + cr_sum[1] / std::max(1.f, float(cr_cnt[1])), + cr_sum[2] / std::max(1.f, float(cr_cnt[2])) + }; + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for (int y = 0; y < cH; ++y) { + const int yy = y + y1; + for (int x = 0; x < cW; ++x) { + const int xx = x + x1; + for (int c = 0; c < 3; ++c) { + const float inval = std::max(0.0f, chan[c][yy][xx]); + if (inval >= clips[c]) { + chan[c][yy][xx] = std::max(inval, tmp[c][y][x] + chrominance[c]); + } + } + } + } + + if (plistener) { + plistener->setProgress(0.9); + } + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for (int y = 0; y < cH; ++y) { + const int yy = y + y1; + for (int x = 0; x < cW; ++x) { + const int xx = x + x1; + for (int c = 0; c < 3; ++c) { + chan[c][yy][xx] /= scalecoeffs[c]; + } + } + } + + if (plistener) { + plistener->setProgress(1.0); + } +} + + + + } diff --git a/rtengine/iimage.h b/rtengine/iimage.h index 2c75a0d59..a544b454a 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -111,7 +111,7 @@ public: { rm = gm = bm = 1.0; } - virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) + virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) { rm = gm = bm = 1.0; } diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index a8ea8f851..d6d22c269 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -109,7 +109,7 @@ public: virtual void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const = 0; // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* - virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw) = 0; + virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw, int opposed) = 0; virtual eSensorType getSensorType () const = 0; virtual bool isMono () const = 0; // true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource @@ -117,10 +117,10 @@ 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(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, 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) = 0; + virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, 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 ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) = 0; - virtual void WBauto(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 &studgood, 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) = 0; + virtual void WBauto(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 &studgood, 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; virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) = 0; virtual double getDefGain () const @@ -195,6 +195,9 @@ public: } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; virtual void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) = 0; + virtual void wbMul2Camera(double &rm, double &gm, double &bm) = 0; + virtual void wbCamera2Mul(double &rm, double &gm, double &bm) = 0; + }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ec5ffc8ef..cc2d75b3d 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1,6 +1,6 @@ /* * This file is part of RawTherapee. - * + * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify @@ -409,11 +409,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (imageTypeListener) { imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported()); } - + bool iscolor = (params->toneCurve.method == "Color");// || params->toneCurve.method == "Coloropp"); if ((todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) - || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) - || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + || (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified()) + || (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) { if (settings->verbose) { if (imgsrc->getSensorType() == ST_BAYER) { @@ -466,8 +468,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) - || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) - || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + || (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified()) + || (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) { if (highDetailNeeded) { highDetailRawComputed = true; } else { @@ -510,8 +514,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { MyMutex::MyLock initLock(minit); // Also used in crop window - - imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery + // imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery if (settings->verbose) { @@ -538,7 +541,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) printf("tempref=%f greref=%f\n", tempref, greenref); } - imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw); + imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 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; @@ -617,8 +620,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) PreviewProps pp(0, 0, fw, fh, scale); // Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications ipf.setScale(scale); - - imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw); + int inpaintopposed = 1;//force getimage to use inpaint-opposed if enable, only once + imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw, inpaintopposed); if ((todo & M_SPOT) && params->spot.enabled && !params->spot.entries.empty()) { spotsDone = true; @@ -2462,7 +2465,7 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou double greenitc = 1.; float studgood = 1000.f; double tempref, greenref; - imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw); + imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); if (rm != -1) { autoWB.update(rm, gm, bm, equal, tempBias); @@ -2649,7 +2652,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a currWB = ColorTemp(); // = no white balance } - imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw); + imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw, 0); ImProcFunctions ipf(&ppar, true); if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) { diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index bdc1b6db1..811e941e4 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2128,7 +2128,7 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, Imagefloat img(int(fw / SCALE + 0.5), int(fh / SCALE + 0.5)); const ProcParams neutral; - imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw); + imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw, 0); imgsrc->convertColorSpace(&img, params->icm, imgsrc->getWB()); float minVal = RT_INFINITY; float maxVal = -RT_INFINITY; diff --git a/rtengine/linalgebra.h b/rtengine/linalgebra.h new file mode 100644 index 000000000..32e44e147 --- /dev/null +++ b/rtengine/linalgebra.h @@ -0,0 +1,275 @@ +/* -*- C++ -*- + * This file is part of ART + * + * Copyright (c) 2022 Alberto Griggio + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#pragma once +#include + +namespace rtengine { + +template +class Vec3 { +public: + Vec3() { data_[0] = data_[1] = data_[2] = T(); } + Vec3(T a, T b, T c) { data_[0] = a; data_[1] = b; data_[2] = c; } + + template + Vec3(T2 const a[3]) { data_[0] = a[0]; data_[1] = a[1]; data_[2] = a[2]; } + + Vec3 &operator=(const Vec3 &a) = default; + + template + Vec3 &operator=(T2 const a[3]) + { + data_[0] = a[0]; data_[1] = a[1]; data_[2] = a[2]; + return *this; + } + + T operator[](int i) const { return data_[i]; } + T &operator[](int i) { return data_[i]; } + operator const T *() const { return data_; } + operator T *() { return data_; } + +private: + T data_[3]; +}; + +typedef Vec3 Vec3f; + + +template +class Mat33 { +public: + Mat33() + { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + data_[i][j] = T(); + } + } + } + + Mat33(T a00, T a01, T a02, + T a10, T a11, T a12, + T a20, T a21, T a22) + { + data_[0][0] = a00; data_[0][1] = a01; data_[0][2] = a02; + data_[1][0] = a10; data_[1][1] = a11; data_[1][2] = a12; + data_[2][0] = a20; data_[2][1] = a21; data_[2][2] = a22; + } + + template + Mat33(const T2 m[3][3]) + { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + data_[i][j] = m[i][j]; + } + } + } + + Mat33 &operator=(const Mat33 &m) = default; + + template + Mat33 &operator=(const T2 m[3][3]) + { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + data_[i][j] = m[i][j]; + } + } + return *this; + } + + T const *operator[](int i) const { return data_[i]; } + T *operator[](int i) { return data_[i]; } + typedef const T(*Data)[3]; + operator Data() const { return data_; } + +private: + T data_[3][3]; +}; + + +typedef Mat33 Mat33f; + + +template +Mat33 identity() +{ + return Mat33(1, 0, 0, 0, 1, 0, 0, 0, 1); +} + + +template +Mat33 diagonal(T a, T b, T c) +{ + return Mat33(a, 0, 0, 0, b, 0, 0, 0, c); +} + + +template +Mat33 transpose(T const m[3][3]) +{ + return Mat33(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); +} + +template +Mat33 transpose(const Mat33 &m) +{ + return transpose(static_cast::Data>(m)); +} + + +template +bool inverse(T const m[3][3], Mat33 &out) +{ + const T res00 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + const T res10 = m[2][0] * m[1][2] - m[1][0] * m[2][2]; + const T res20 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + const T det = m[0][0] * res00 + m[0][1] * res10 + m[0][2] * res20; + + if (std::abs(det) >= 1.0e-10) { + out[0][0] = res00 / det; + out[0][1] = (m[2][1] * m[0][2] - m[0][1] * m[2][2]) / det; + out[0][2] = (m[0][1] * m[1][2] - m[1][1] * m[0][2]) / det; + out[1][0] = res10 / det; + out[1][1] = (m[0][0] * m[2][2] - m[2][0] * m[0][2]) / det; + out[1][2] = (m[1][0] * m[0][2] - m[0][0] * m[1][2]) / det; + out[2][0] = res20 / det; + out[2][1] = (m[2][0] * m[0][1] - m[0][0] * m[2][1]) / det; + out[2][2] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) / det; + return true; + } else { + return false; + } +} + +template +Mat33 inverse(const Mat33 &m) +{ + Mat33 res; + inverse(static_cast::Data>(m), res); + return res; +} + +template +Mat33 inverse(T const m[3][3]) +{ + Mat33 res; + inverse(m, res); + return res; +} + +template +bool inverse(const Mat33 &m, Mat33 &out) +{ + return inverse(static_cast::Data>(m), out); +} + + +template +Mat33 dot_product(T const a[3][3], T const b[3][3]) +{ + Mat33 res; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + res[i][j] = 0; + + for (int k = 0; k < 3; ++k) { + res[i][j] += a[i][k] * b[k][j]; + } + } + } + + return res; +} + +template +Mat33 dot_product(const Mat33 &a, T const b[3][3]) +{ + return dot_product(static_cast::Data>(a), b); +} + +template +Mat33 dot_product(T const a[3][3], const Mat33 &b) +{ + return dot_product(a, static_cast::Data>(b)); +} + +template +Mat33 dot_product(const Mat33 &a, const Mat33 &b) +{ + return dot_product(static_cast::Data>(a), static_cast::Data>(b)); +} + + +template +Vec3 dot_product(T const a[3][3], T const b[3]) +{ + Vec3 res; + + for (int i = 0; i < 3; ++i) { + res[i] = 0; + for (int k = 0; k < 3; ++k) { + res[i] += a[i][k] * b[k]; + } + } + + return res; +} + + +template +Vec3 dot_product(const Mat33 &a, T const b[3]) +{ + return dot_product(static_cast::Data>(a), b); +} + +template +Vec3 dot_product(T const a[3][3], const Vec3 &b) +{ + return dot_product(a, static_cast(b)); +} + +template +Vec3 dot_product(const Mat33 &a, const Vec3 &b) +{ + return dot_product(static_cast::Data>(a), static_cast(b)); +} + + +template +Mat33 operator*(const Mat33 &m, T v) +{ + return Mat33(m[0][0] * v, m[0][1] * v, m[0][2] * v, + m[1][0] * v, m[1][1] * v, m[1][2] * v, + m[2][0] * v, m[2][1] * v, m[2][2] * v); +} + +template +Vec3 operator*(const Vec3 &a, T v) +{ + return Vec3(a[0] * v, a[1] * v, a[2] * v); +} + +} // namespace rtengine diff --git a/rtengine/perspectivecorrection.cc b/rtengine/perspectivecorrection.cc index 7a56ef5a8..f4428faf2 100644 --- a/rtengine/perspectivecorrection.cc +++ b/rtengine/perspectivecorrection.cc @@ -297,7 +297,7 @@ PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *sr neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); neutral.icm.outputProfile = ColorManagementParams::NoICMString; - src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw); + src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw, 0); src->convertColorSpace(img.get(), pparams->icm, src->getWB()); neutral.commonTrans.autofill = false; // Ensures crop factor is correct. diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index de1603f1c..1afe72c92 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -121,7 +121,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext double contrastThresholdDummy = 0.0; rawImage.demosaic(params.raw, false, contrastThresholdDummy); Imagefloat image(fw, fh); - rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw); + rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw, 0); rtengine::Image8 output(fw, fh); rawImage.convertColorSpace(&image, params.icm, wb); #ifdef _OPENMP diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e6bdc9619..9323bd9e7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -373,7 +373,7 @@ ToneCurveParams::ToneCurveParams() : autoexp(false), clip(0.02), hrenabled(false), - method("Blend"), + method("Coloropp"), expcomp(0), curve{ DCT_Linear @@ -390,6 +390,7 @@ ToneCurveParams::ToneCurveParams() : shcompr(50), hlcompr(0), hlbl(0), + hlth(1.0), hlcomprthresh(0), histmatching(false), fromHistMatching(false), @@ -416,6 +417,7 @@ bool ToneCurveParams::isPanningRelatedChange(const ToneCurveParams& other) const && shcompr == other.shcompr && hlcompr == other.hlcompr && hlbl == other.hlbl + && hlth == other.hlth && hlcomprthresh == other.hlcomprthresh && histmatching == other.histmatching && clampOOG == other.clampOOG); @@ -440,6 +442,7 @@ bool ToneCurveParams::operator ==(const ToneCurveParams& other) const && shcompr == other.shcompr && hlcompr == other.hlcompr && hlbl == other.hlbl + && hlth == other.hlth && hlcomprthresh == other.hlcomprthresh && histmatching == other.histmatching && fromHistMatching == other.fromHistMatching @@ -5912,6 +5915,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->toneCurve.hrenabled, "HLRecovery", "Enabled", toneCurve.hrenabled, keyFile); saveToKeyfile(!pedited || pedited->toneCurve.method, "HLRecovery", "Method", toneCurve.method, keyFile); saveToKeyfile(!pedited || pedited->toneCurve.hlbl, "HLRecovery", "Hlbl", toneCurve.hlbl, keyFile); + saveToKeyfile(!pedited || pedited->toneCurve.hlth, "HLRecovery", "Hlth", toneCurve.hlth, keyFile); const std::map tc_mapping = { {ToneCurveMode::STD, "Standard"}, @@ -7697,6 +7701,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); } if (keyFile.has_group("Channel Mixer")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e86272b0a..33d95a619 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -299,6 +299,7 @@ struct ToneCurveParams { int shcompr; int hlcompr; // Highlight Recovery's compression int hlbl; // Highlight Recovery's compression + double hlth; // Highlight Recovery's threshold int hlcomprthresh; // Highlight Recovery's threshold bool histmatching; // histogram matching bool fromHistMatching; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 550c59e9c..7ff9c4d0f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -468,6 +468,7 @@ RawImageSource::RawImageSource () { embProfile = nullptr; rgbSourceModified = false; + for (int i = 0; i < 4; ++i) { psRedBrightness[i] = psGreenBrightness[i] = psBlueBrightness[i] = 1.f; } @@ -639,6 +640,57 @@ float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const flo return gain; } +void RawImageSource::wbMul2Camera(double &rm, double &gm, double &bm) +{ + double r = rm; + double g = gm; + double b = bm; + + auto imatrices = getImageMatrices(); + + if (imatrices) { + double rr = imatrices->cam_rgb[0][0] * r + imatrices->cam_rgb[0][1] * g + imatrices->cam_rgb[0][2] * b; + double gg = imatrices->cam_rgb[1][0] * r + imatrices->cam_rgb[1][1] * g + imatrices->cam_rgb[1][2] * b; + double bb = imatrices->cam_rgb[2][0] * r + imatrices->cam_rgb[2][1] * g + imatrices->cam_rgb[2][2] * b; + r = rr; + g = gg; + b = bb; + } + + rm = ri->get_pre_mul(0) / r; + gm = ri->get_pre_mul(1) / g; + bm = ri->get_pre_mul(2) / b; + + rm /= gm; + bm /= gm; + gm = 1.0; +} + + +void RawImageSource::wbCamera2Mul(double &rm, double &gm, double &bm) +{ + auto imatrices = getImageMatrices(); + + double r = ri->get_pre_mul(0) / rm; + double g = ri->get_pre_mul(1) / gm; + double b = ri->get_pre_mul(2) / bm; + + if (imatrices) { + double rr = imatrices->rgb_cam[0][0] * r + imatrices->rgb_cam[0][1] * g + imatrices->rgb_cam[0][2] * b; + double gg = imatrices->rgb_cam[1][0] * r + imatrices->rgb_cam[1][1] * g + imatrices->rgb_cam[1][2] * b; + double bb = imatrices->rgb_cam[2][0] * r + imatrices->rgb_cam[2][1] * g + imatrices->rgb_cam[2][2] * b; + r = rr; + g = gg; + b = bb; + } + + rm = r / g; + bm = b / g; + gm = 1.0; +} + + + void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, std::array& out_scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const { @@ -689,10 +741,9 @@ void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, s autoGainComp = camInitialGain / initialGain; } -void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) -{ +void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) +{// added int opposed to force getimage to use inpaint-opposed if enable, only once MyMutex::MyLock lock(getImageMutex); - tran = defTransform (tran); // compute channel multipliers @@ -705,7 +756,9 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima gm = ri->get_pre_mul(1); bm = ri->get_pre_mul(2); } else { - ctemp.getMultipliers (r, g, b); + // ctemp.getMultipliers (r, g, b); + r = g = b = 1; + wbCamera2Mul(r, g, b); rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; @@ -790,22 +843,52 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima int maxx = this->W, maxy = this->H, skip = pp.getSkip(); - // raw clip levels after white balance + bool iscolor = (hrp.method == "Color" || hrp.method == "Coloropp"); + const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; + bool doHr = (hrp.hrenabled && !iscolor); + if (hrp.hrenabled && iscolor) { + + if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited tne number to 1 + rgbSourceModified = false; + } + if (!rgbSourceModified) { + if(hrp.method == "Color") { + if (settings->verbose) { + printf ("Applying Highlight Recovery: Color propagation.\n"); + } + HLRecovery_inpaint (red, green, blue, hrp.hlbl); + } else if(hrp.method == "Coloropp" && ctemp.getTemp() >= 0) { + float s[3] = { rm, gm, bm }; + highlight_recovery_opposed(s, ctemp, hrp.hlth); + } + rgbSourceModified = true; + } + } + + // now apply the wb coefficients + if (ctemp.getTemp() >= 0) { + double r, g, b; + ctemp.getMultipliers(r, g, b); + wbMul2Camera(r, g, b); + + rm *= r; + gm *= g; + bm *= b; + } hlmax[0] = clmax[0] * rm; hlmax[1] = clmax[1] * gm; hlmax[2] = clmax[2] * bm; - const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; + const float expcomp = std::pow(2, ri->getBaselineExposure()); + rm *= expcomp; + gm *= expcomp; + bm *= expcomp; float area = skip * skip; rm /= area; gm /= area; bm /= area; - bool doHr = (hrp.hrenabled && hrp.method != "Color"); - const float expcomp = std::pow(2, ri->getBaselineExposure()); - rm *= expcomp; - gm *= expcomp; - bm *= expcomp; + #ifdef _OPENMP #pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) @@ -1697,7 +1780,6 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c rgbSourceModified = false; - if (cache) { if (!redCache) { redCache = new array2D(W, H); @@ -2396,7 +2478,6 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara } rgbSourceModified = false; // tricky handling for Color propagation - t5.set(); if (settings->verbose) { @@ -2442,16 +2523,17 @@ void RawImageSource::flush() void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) { - if (hrp.hrenabled && hrp.method == "Color") { - if (!rgbSourceModified) { - if (settings->verbose) { - printf ("Applying Highlight Recovery: Color propagation...\n"); - } - - HLRecovery_inpaint (red, green, blue, hrp.hlbl); - rgbSourceModified = true; - } - } + // if (hrp.hrenabled && hrp.method == "Color") { + // if (!rgbSourceModified) { + // if (settings->verbose) { + // printf ("Applying Highlight Recovery: Color propagation...\n"); + // } +// + // HLRecovery_inpaint (red, green, blue, hrp.hlbl); +// +// rgbSourceModified = true; + // } +// } } @@ -3460,6 +3542,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed // very effective to reduce (or remove) the magenta, but with levels of grey ! void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int width, float maxval, float* hlmax) { + constexpr int ColorCount = 3; // Transform matrixes rgb>lab and back @@ -3684,6 +3767,7 @@ void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, floa void RawImageSource::hlRecovery (const std::string &method, float* red, float* green, float* blue, int width, float* hlmax) { +// BENCHFUN if (method == "Luminance") { HLRecovery_Luminance (red, green, blue, red, green, blue, width, 65535.0); @@ -3953,12 +4037,12 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) } } - -static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy) +static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy, bool purp) { - //calculate histogram x y in a range of 190 colors - //this "choice" are guided by generally colors who are in nature skin, sky, etc. in those cases "steps" are small + // calculate histogram x y in a range of 236 colors + // this "choice" are guided by generally colors who are in nature skin, sky, etc. in those cases "steps" are small // of course we can change to be more precise + // purp enable or not purple color in xyY - approximation... #ifdef _OPENMP #pragma omp parallel #endif @@ -3971,434 +4055,528 @@ static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const ar yyythr.clear(); LUTf YYYthr(YYY.getSize()); YYYthr.clear(); + // bool purp = false; #ifdef _OPENMP #pragma omp for schedule(dynamic, 4) nowait #endif - for (int y = 0; y < bfhitc ; y++) { + + for (int y = 0; y < bfhitc ; y++) + { for (int x = 0; x < bfwitc ; x++) { int nh = -1; + if (xc[y][x] < 0.12f && xc[y][x] > 0.03f && yc[y][x] > 0.1f) { // near Prophoto if (yc[y][x] < 0.2f) { nh = 0; //blue hard - } else if (yc[y][x] < 0.3f) { + } else if (yc[y][x] < 0.25f) { nh = 1; - //blue - } else if (yc[y][x] < 0.4f) { + } else if (yc[y][x] < 0.3f) { nh = 2; - + //blue + } else if (yc[y][x] < 0.35f) { + nh = 3; + } else if (yc[y][x] < 0.4f) { + nh = 4; + } else if (yc[y][x] < 0.45f) { + nh = 5; } else if (yc[y][x] < 0.5f) { //blue green - nh = 3; + nh = 6; + } else if (yc[y][x] < 0.55f) { + nh = 7; } else if (yc[y][x] < 0.6f) { - nh = 4; + nh = 8; + } else if (yc[y][x] < 0.7f) { + nh = 9; } else if (yc[y][x] < 0.82f) { //green - nh = 5; + nh = 10; } } else if (xc[y][x] < 0.24f && yc[y][x] > 0.05f) { if (yc[y][x] < 0.2f) { - nh = 6; - } else if (yc[y][x] < 0.3f) { - nh = 7; - } else if (yc[y][x] < 0.4f) { - nh = 8; - } else if (yc[y][x] < 0.5f) { - nh = 9; - } else if (yc[y][x] < 0.6f) { - nh = 10; - } else if (yc[y][x] < 0.75f) { nh = 11; - } - } else if (xc[y][x] < 0.28f && yc[y][x] > 0.1f) {//blue sky and other - if (yc[y][x] < 0.2f) { - nh = 12; } else if (yc[y][x] < 0.25f) { + nh = 12; + } else if (yc[y][x] < 0.3f) { nh = 13; - } else if (yc[y][x] < 0.29f) { + } else if (yc[y][x] < 0.35f) { nh = 14; - } else if (yc[y][x] < 0.33f) { - nh = 15; - } else if (yc[y][x] < 0.37f) { - nh = 16; } else if (yc[y][x] < 0.4f) { - nh = 17; + nh = 15; } else if (yc[y][x] < 0.45f) { - nh = 18; + nh = 16; } else if (yc[y][x] < 0.5f) { - nh = 19; + nh = 17; + } else if (yc[y][x] < 0.55f) { + nh = 18; } else if (yc[y][x] < 0.6f) { + nh = 19; + } else if (yc[y][x] < 0.67f) { nh = 20; } else if (yc[y][x] < 0.75f) { nh = 21; } - } else if (xc[y][x] < 0.31f && yc[y][x] > 0.1f) {//near neutral others + } else if (xc[y][x] < 0.28f && yc[y][x] > 0.1f) {//blue sky and other if (yc[y][x] < 0.2f) { nh = 22; - } else if (yc[y][x] < 0.24f) { + } else if (yc[y][x] < 0.23f) { nh = 23; - } else if (yc[y][x] < 0.29f) { + } else if (yc[y][x] < 0.25f) { nh = 24; - } else if (yc[y][x] < 0.32f) { + } else if (yc[y][x] < 0.27f) { nh = 25; - } else if (yc[y][x] < 0.36f) { + } else if (yc[y][x] < 0.29f) { nh = 26; - } else if (yc[y][x] < 0.4f) { + } else if (yc[y][x] < 0.31f) { nh = 27; - } else if (yc[y][x] < 0.5f) { + } else if (yc[y][x] < 0.33f) { nh = 28; - } else if (yc[y][x] < 0.7f) { + } else if (yc[y][x] < 0.35f) { nh = 29; + } else if (yc[y][x] < 0.37f) { + nh = 30; + } else if (yc[y][x] < 0.4f) { + nh = 31; + } else if (yc[y][x] < 0.45f) { + nh = 32; + } else if (yc[y][x] < 0.5f) { + nh = 33; + } else if (yc[y][x] < 0.55f) { + nh = 34; + } else if (yc[y][x] < 0.6f) { + nh = 35; + } else if (yc[y][x] < 0.67f) { + nh = 36; + } else if (yc[y][x] < 0.75f) { + nh = 37; + } + } else if (xc[y][x] < 0.31f && yc[y][x] > 0.1f) {//near neutral others + if (yc[y][x] < 0.2f) { + nh = 38; + } else if (yc[y][x] < 0.22f) { + nh = 39; + } else if (yc[y][x] < 0.24f) { + nh = 40; + } else if (yc[y][x] < 0.26f) { + nh = 41; + } else if (yc[y][x] < 0.29f) { + nh = 42; + } else if (yc[y][x] < 0.32f) { + nh = 43; + } else if (yc[y][x] < 0.36f) { + nh = 44; + } else if (yc[y][x] < 0.4f) { + nh = 45; + } else if (yc[y][x] < 0.45f) { + nh = 46; + } else if (yc[y][x] < 0.5f) { + nh = 47; + } else if (yc[y][x] < 0.6f) { + nh = 48; + } else if (yc[y][x] < 0.7f) { + nh = 49; } } else if (xc[y][x] < 0.325f && yc[y][x] > 0.1f) {//neutral 34 if (yc[y][x] < 0.2f) { - nh = 30; + nh = 50; + } else if (yc[y][x] < 0.22f) { + nh = 51; } else if (yc[y][x] < 0.24f) { - nh = 31; + nh = 52; } else if (yc[y][x] < 0.29f) { - nh = 32; + nh = 53; } else if (yc[y][x] < 0.32f) { - nh = 33; + nh = 54; } else if (yc[y][x] < 0.33f) { - nh = 34; + nh = 55; } else if (yc[y][x] < 0.335f) { - nh = 35; + nh = 56; } else if (yc[y][x] < 0.34f) { - nh = 36; + nh = 57; } else if (yc[y][x] < 0.35f) { - nh = 37; + nh = 58; } else if (yc[y][x] < 0.37f) { - nh = 38; + nh = 59; } else if (yc[y][x] < 0.4f) { - nh = 39; + nh = 60; } else if (yc[y][x] < 0.45f) { - nh = 40; + nh = 61; } else if (yc[y][x] < 0.5f) { - nh = 41; + nh = 62; } else if (yc[y][x] < 0.55f) { - nh = 42; + nh = 63; + } else if (yc[y][x] < 0.6f) { + nh = 64; + } else if (yc[y][x] < 0.65f) { + nh = 65; } else if (yc[y][x] < 0.7f) { - nh = 43; + nh = 66; } } else if (xc[y][x] < 0.335f && yc[y][x] > 0.1f) {//neutral if (yc[y][x] < 0.2f) { - nh = 44; + nh = 67; + } else if (yc[y][x] < 0.22f) { + nh = 68; } else if (yc[y][x] < 0.24f) { - nh = 45; + nh = 69; + } else if (yc[y][x] < 0.27f) { + nh = 70; } else if (yc[y][x] < 0.29f) { - nh = 46; + nh = 71; } else if (yc[y][x] < 0.32f) { - nh = 47; + nh = 72; } else if (yc[y][x] < 0.33f) { - nh = 48; + nh = 73; } else if (yc[y][x] < 0.335f) { - nh = 49; + nh = 74; } else if (yc[y][x] < 0.34f) { - nh = 50; + nh = 75; } else if (yc[y][x] < 0.345f) { - nh = 51; + nh = 76; } else if (yc[y][x] < 0.35f) { - nh = 52; + nh = 77; } else if (yc[y][x] < 0.355f) { - nh = 53; + nh = 78; } else if (yc[y][x] < 0.36f) { - nh = 54; + nh = 79; } else if (yc[y][x] < 0.37f) { - nh = 55; + nh = 80; } else if (yc[y][x] < 0.38f) { - nh = 56; + nh = 81; } else if (yc[y][x] < 0.4f) { - nh = 57; + nh = 82; } else if (yc[y][x] < 0.45f) { - nh = 58; + nh = 83; } else if (yc[y][x] < 0.5f) { - nh = 59; + nh = 84; } else if (yc[y][x] < 0.55f) { - nh = 60; + nh = 85; + } else if (yc[y][x] < 0.6f) { + nh = 86; + } else if (yc[y][x] < 0.65f) { + nh = 87; } else if (yc[y][x] < 0.7f) { - nh = 61; + nh = 88; } } else if (xc[y][x] < 0.340f && yc[y][x] > 0.1f) {//neutral if (yc[y][x] < 0.2f) { - nh = 62; + nh = 89; + } else if (yc[y][x] < 0.22f) { + nh = 90; } else if (yc[y][x] < 0.24f) { - nh = 63; + nh = 91; } else if (yc[y][x] < 0.29f) { - nh = 64; + nh = 92; } else if (yc[y][x] < 0.32f) { - nh = 65; + nh = 93; } else if (yc[y][x] < 0.325f) { - nh = 66; + nh = 94; } else if (yc[y][x] < 0.33f) { - nh = 67; + nh = 95; } else if (yc[y][x] < 0.335f) { - nh = 68; + nh = 96; } else if (yc[y][x] < 0.34f) { - nh = 69; + nh = 97; } else if (yc[y][x] < 0.345f) { - nh = 70; + nh = 98; } else if (yc[y][x] < 0.35f) { - nh = 71; + nh = 99; } else if (yc[y][x] < 0.355f) { - nh = 72; + nh = 100; } else if (yc[y][x] < 0.36f) { - nh = 73; + nh = 101; } else if (yc[y][x] < 0.37f) { - nh = 74; + nh = 102; } else if (yc[y][x] < 0.38f) { - nh = 75; + nh = 103; } else if (yc[y][x] < 0.4f) { - nh = 76; + nh = 104; } else if (yc[y][x] < 0.45f) { - nh = 77; + nh = 105; } else if (yc[y][x] < 0.5f) { - nh = 78; + nh = 106; } else if (yc[y][x] < 0.55f) { - nh = 79; + nh = 107; + } else if (yc[y][x] < 0.6f) { + nh = 108; + } else if (yc[y][x] < 0.65f) { + nh = 109; } else if (yc[y][x] < 0.7f) { - nh = 80; + nh = 110; } } else if (xc[y][x] < 0.345f && yc[y][x] > 0.1f) {//neutral 37 if (yc[y][x] < 0.2f) { - nh = 81; + nh = 111; + } else if (yc[y][x] < 0.22f) { + nh = 112; } else if (yc[y][x] < 0.24f) { - nh = 82; + nh = 113; + } else if (yc[y][x] < 0.26f) { + nh = 114; } else if (yc[y][x] < 0.29f) { - nh = 83; + nh = 115; } else if (yc[y][x] < 0.32f) { - nh = 84; + nh = 116; } else if (yc[y][x] < 0.33f) { - nh = 85; + nh = 117; } else if (yc[y][x] < 0.335f) { - nh = 86; + nh = 118; } else if (yc[y][x] < 0.34f) { - nh = 87; + nh = 119; } else if (yc[y][x] < 0.345f) { - nh = 88; + nh = 120; } else if (yc[y][x] < 0.35f) { - nh = 89; + nh = 121; } else if (yc[y][x] < 0.355f) { - nh = 90; + nh = 122; } else if (yc[y][x] < 0.36f) { - nh = 91; + nh = 123; } else if (yc[y][x] < 0.37f) { - nh = 92; + nh = 124; } else if (yc[y][x] < 0.38f) { - nh = 93; + nh = 125; } else if (yc[y][x] < 0.39f) { - nh = 94; + nh = 126; } else if (yc[y][x] < 0.4f) { - nh = 95; + nh = 127; } else if (yc[y][x] < 0.42f) { - nh = 96; + nh = 128; } else if (yc[y][x] < 0.45f) { - nh = 97; + nh = 129; } else if (yc[y][x] < 0.48f) { - nh = 98; + nh = 130; } else if (yc[y][x] < 0.5f) { - nh = 99; + nh = 131; } else if (yc[y][x] < 0.55f) { - nh = 100; + nh = 132; } else if (yc[y][x] < 0.65f) { - nh = 101; + nh = 133; } } else if (xc[y][x] < 0.355f && yc[y][x] > 0.1f) {//neutral 37 if (yc[y][x] < 0.2f) { - nh = 102; + nh = 134; + } else if (yc[y][x] < 0.22f) { + nh = 135; } else if (yc[y][x] < 0.24f) { - nh = 103; + nh = 136; + } else if (yc[y][x] < 0.26f) { + nh = 137; } else if (yc[y][x] < 0.29f) { - nh = 104; + nh = 138; } else if (yc[y][x] < 0.32f) { - nh = 105; + nh = 139; } else if (yc[y][x] < 0.33f) { - nh = 106; + nh = 140; } else if (yc[y][x] < 0.335f) { - nh = 107; + nh = 141; } else if (yc[y][x] < 0.34f) { - nh = 108; + nh = 142; } else if (yc[y][x] < 0.345f) { - nh = 109; + nh = 143; } else if (yc[y][x] < 0.35f) { - nh = 110; + nh = 144; } else if (yc[y][x] < 0.355f) { - nh = 111; + nh = 145; } else if (yc[y][x] < 0.36f) { - nh = 112; + nh = 146; } else if (yc[y][x] < 0.37f) { - nh = 113; + nh = 147; } else if (yc[y][x] < 0.38f) { - nh = 114; + nh = 148; } else if (yc[y][x] < 0.39f) { - nh = 115; + nh = 149; } else if (yc[y][x] < 0.4f) { - nh = 116; + nh = 150; } else if (yc[y][x] < 0.42f) { - nh = 117; + nh = 151; } else if (yc[y][x] < 0.45f) { - nh = 118; + nh = 152; } else if (yc[y][x] < 0.48f) { - nh = 119; + nh = 153; } else if (yc[y][x] < 0.5f) { - nh = 120; + nh = 154; } else if (yc[y][x] < 0.55f) { - nh = 121; + nh = 155; + } else if (yc[y][x] < 0.6f) { + nh = 156; } else if (yc[y][x] < 0.65f) { - nh = 122; + nh = 157; } } else if (xc[y][x] < 0.365f && yc[y][x] > 0.15f) { //0.4 if (yc[y][x] < 0.2f) { - nh = 123; + nh = 158; + } else if (yc[y][x] < 0.22f) { + nh = 159; } else if (yc[y][x] < 0.24f) { - nh = 124; + nh = 160; + } else if (yc[y][x] < 0.26f) { + nh = 161; } else if (yc[y][x] < 0.29f) { - nh = 125; + nh = 162; } else if (yc[y][x] < 0.32f) { - nh = 126; + nh = 163; } else if (yc[y][x] < 0.33f) { - nh = 127; + nh = 164; } else if (yc[y][x] < 0.34f) { - nh = 128; + nh = 165; } else if (yc[y][x] < 0.35f) { - nh = 129; + nh = 166; } else if (yc[y][x] < 0.36f) { - nh = 130; + nh = 167; } else if (yc[y][x] < 0.37f) { - nh = 131; + nh = 168; } else if (yc[y][x] < 0.38f) { - nh = 132; + nh = 169; } else if (yc[y][x] < 0.39f) { - nh = 133; + nh = 170; } else if (yc[y][x] < 0.4f) { - nh = 134; + nh = 171; } else if (yc[y][x] < 0.42f) { - nh = 135; + nh = 172; } else if (yc[y][x] < 0.45f) { - nh = 136; + nh = 173; } else if (yc[y][x] < 0.5f) { - nh = 137; + nh = 174; } else if (yc[y][x] < 0.55f) { - nh = 138; + nh = 175; } else if (yc[y][x] < 0.63f) { - nh = 139; + nh = 176; } } else if (xc[y][x] < 0.405f && yc[y][x] > 0.15f) {//45 - if (yc[y][x] < 0.2f) { - nh = 140; - } else if (yc[y][x] < 0.24f) { - nh = 141; - } else if (yc[y][x] < 0.29f) { - nh = 142; - } else if (yc[y][x] < 0.32f) { - nh = 143; - } else if (yc[y][x] < 0.34f) { - nh = 144; - } else if (yc[y][x] < 0.37f) { - nh = 145; - } else if (yc[y][x] < 0.4f) { - nh = 146; - } else if (yc[y][x] < 0.45f) { - nh = 147; - } else if (yc[y][x] < 0.5f) { - nh = 148; - } else if (yc[y][x] < 0.55f) { - nh = 149; - } else if (yc[y][x] < 0.6f) { - nh = 150; - } - } else if (xc[y][x] < 0.445f && yc[y][x] > 0.15f) {//45 - if (yc[y][x] < 0.2f) { - nh = 151; - } else if (yc[y][x] < 0.24f) { - nh = 152; - } else if (yc[y][x] < 0.29f) { - nh = 153; - } else if (yc[y][x] < 0.32f) { - nh = 154; - } else if (yc[y][x] < 0.34f) { - nh = 155; - } else if (yc[y][x] < 0.37f) { - nh = 156; - } else if (yc[y][x] < 0.4f) { - nh = 157; - } else if (yc[y][x] < 0.45f) { - nh = 158; - } else if (yc[y][x] < 0.5f) { - nh = 159; - } else if (yc[y][x] < 0.55f) { - nh = 160; - } else if (yc[y][x] < 0.58f) { - nh = 161; - } - } else if (xc[y][x] < 0.495f && yc[y][x] > 0.15f) { - if (yc[y][x] < 0.2f) { - nh = 162; - } else if (yc[y][x] < 0.24f) { - nh = 163; - } else if (yc[y][x] < 0.29f) { - nh = 164; - } else if (yc[y][x] < 0.32f) { - nh = 165; - } else if (yc[y][x] < 0.34f) { - nh = 166; - } else if (yc[y][x] < 0.37f) { - nh = 167; - } else if (yc[y][x] < 0.4f) { - nh = 168; - } else if (yc[y][x] < 0.45f) { - nh = 169; - } else if (yc[y][x] < 0.5f) { - nh = 170; - } else if (yc[y][x] < 0.55f) { - nh = 171; - } - } else if (xc[y][x] < 0.545f && yc[y][x] > 0.15f) { - if (yc[y][x] < 0.2f) { - nh = 172; - } else if (yc[y][x] < 0.24f) { - nh = 173; - } else if (yc[y][x] < 0.29f) { - nh = 174; - } else if (yc[y][x] < 0.32f) { - nh = 175; - } else if (yc[y][x] < 0.34f) { - nh = 176; - } else if (yc[y][x] < 0.37f) { + if (yc[y][x] < 0.2f && purp) {//no take into account if purp = false nh = 177; - } else if (yc[y][x] < 0.4f) { + } else if (yc[y][x] < 0.22f && purp) { nh = 178; - } else if (yc[y][x] < 0.45f) { + } else if (yc[y][x] < 0.24f && purp) { nh = 179; - } else if (yc[y][x] < 0.5f) { + } else if (yc[y][x] < 0.26f && purp) { nh = 180; - } - } else if (xc[y][x] < 0.595f && yc[y][x] > 0.15f) { - if (yc[y][x] < 0.22f) { + } else if (yc[y][x] < 0.29f && purp) { nh = 181; - } else if (yc[y][x] < 0.25f) { + } else if (yc[y][x] < 0.32f) { nh = 182; - } else if (yc[y][x] < 0.3f) { + } else if (yc[y][x] < 0.34f) { nh = 183; - } else if (yc[y][x] < 0.35f) { + } else if (yc[y][x] < 0.37f) { nh = 184; } else if (yc[y][x] < 0.4f) { nh = 185; } else if (yc[y][x] < 0.45f) { nh = 186; + } else if (yc[y][x] < 0.5f) { + nh = 187; + } else if (yc[y][x] < 0.55f) { + nh = 188; + } else if (yc[y][x] < 0.6f) { + nh = 189; + } + } else if (xc[y][x] < 0.445f && yc[y][x] > 0.15f) {//45 + if (yc[y][x] < 0.2f && purp) { + nh = 190; + } else if (yc[y][x] < 0.22f && purp) { + nh = 191; + } else if (yc[y][x] < 0.24f && purp) { + nh = 192; + } else if (yc[y][x] < 0.26f && purp) { + nh = 193; + } else if (yc[y][x] < 0.29f && purp) { + nh = 194; + } else if (yc[y][x] < 0.32f && purp) { + nh = 195; + } else if (yc[y][x] < 0.34f && purp) { + nh = 196; + } else if (yc[y][x] < 0.37f) { + nh = 197; + } else if (yc[y][x] < 0.4f) { + nh = 198; + } else if (yc[y][x] < 0.45f) { + nh = 199; + } else if (yc[y][x] < 0.5f) { + nh = 200; + } else if (yc[y][x] < 0.55f) { + nh = 201; + } else if (yc[y][x] < 0.58f) { + nh = 202; + } + } else if (xc[y][x] < 0.495f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f && purp) { + nh = 203; + } else if (yc[y][x] < 0.22f && purp) { + nh = 204; + } else if (yc[y][x] < 0.24f && purp) { + nh = 205; + } else if (yc[y][x] < 0.26f && purp) { + nh = 206; + } else if (yc[y][x] < 0.29f && purp) { + nh = 207; + } else if (yc[y][x] < 0.32f && purp) { + nh = 208; + } else if (yc[y][x] < 0.34f && purp) { + nh = 209; + } else if (yc[y][x] < 0.37f) { + nh = 210; + } else if (yc[y][x] < 0.4f) { + nh = 211; + } else if (yc[y][x] < 0.45f) { + nh = 212; + } else if (yc[y][x] < 0.5f) { + nh = 213; + } else if (yc[y][x] < 0.55f) { + nh = 214; + } + } else if (xc[y][x] < 0.545f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f && purp) { + nh = 215; + } else if (yc[y][x] < 0.22f && purp) { + nh = 216; + } else if (yc[y][x] < 0.24f && purp) { + nh = 217; + } else if (yc[y][x] < 0.26f && purp) { + nh = 218; + } else if (yc[y][x] < 0.29f && purp) { + nh = 219; + } else if (yc[y][x] < 0.32f && purp) { + nh = 220; + } else if (yc[y][x] < 0.34f && purp) { + nh = 221; + } else if (yc[y][x] < 0.37f) { + nh = 222; + } else if (yc[y][x] < 0.4f) { + nh = 223; + } else if (yc[y][x] < 0.45f) { + nh = 224; + } else if (yc[y][x] < 0.5f) { + nh = 225; + } + } else if (xc[y][x] < 0.595f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.22f) { + nh = 226; + } else if (yc[y][x] < 0.25f) { + nh = 227; + } else if (yc[y][x] < 0.3f) { + nh = 228; + } else if (yc[y][x] < 0.35f) { + nh = 229; + } else if (yc[y][x] < 0.4f) { + nh = 230; + } else if (yc[y][x] < 0.45f) { + nh = 231; } } else if (xc[y][x] < 0.65f && yc[y][x] > 0.12f) { if (yc[y][x] < 0.25f) { - nh = 187; + nh = 232; } else if (yc[y][x] < 0.3f) { - nh = 188; + nh = 233; } else if (yc[y][x] < 0.35f) { - nh = 189; + nh = 234; } else if (yc[y][x] < 0.45f) { - nh = 190; + nh = 235; } } else if (xc[y][x] < 0.75f && yc[y][x] > 0.1f) { - nh = 191; + nh = 236; //191 } + if (nh >= 0) { histxythr[nh]++; xxxthr[nh] += xc[y][x]; @@ -4407,6 +4585,7 @@ static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const ar } } } + #ifdef _OPENMP #pragma omp critical #endif @@ -4431,24 +4610,28 @@ float static studentXY(const array2D & YYcurr, const array2D & ref somcurrY += YYcurr[i][tt]; //sum observations first group } + somcurrY *= 100.f; for (int i = 0; i < Nc; i++) { somreffY += reffYY[i][tt]; //sum observations second group } + somreffY *= 100.f; for (int i = 0; i < sizcurr; i++) { somcurr2Y += SQR(YYcurr[i][tt]); //sum sqr observations first group } + somcurr2Y *= SQR(100.f); for (int i = 0; i < Nc; i++) { somreff2Y += SQR(reffYY[i][tt]); //sum sqr observations second group } + somreff2Y *= SQR(100.f); const float somsqueccurrY = somcurr2Y - SQR(somcurrY) / sizcurr; @@ -4465,19 +4648,22 @@ float static studentXY(const array2D & YYcurr, const array2D & ref //student coeeficient } -void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar) + + + +void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar, const ToneCurveParams &hrp) { /* - Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com + Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com, update 1 - 2023 Copyright (c) Ingo Weyrich 3 - 2020 (heckflosse67@gmx.de) - This algorithm try to find temperature correlation between 20 to 201 color between 201 spectral color and about 20 to 55 color found in the image between 192, I just found the idea in the web "correlate with chroma" instead of RGB grey point,but I don't use any algo found on the web. + This algorithm try to find temperature correlation between 20 to 80 colors between 201 spectral color and about 20 to 55 color found in the image between 236, I just found the idea in the web "correlate with chroma" instead of RGB grey point,but I don't use any algo found on the web. I have test many many algorithms to find the first one that work :) Probably (sure) there are improvement to do... I have create a table temperature with temp and white point with 118 values between 2000K and 12000K we can obviously change these values, more...with different steps - I have create a table for tint (green)with 134 values between 0.4 to 4. + I have create a table for tint (green)with 134 values between 0.4 to 4. I have create or recuparate and transformed 201 spectral colors from Colorchecker24, others color and my 468 colors target, or from web flowers, etc. with a step of 5nm, I think it is large enough. I think this value of 201 is now complete: I tested correlation with 60, 90, 100, 120, 155...better student increase with number of color, but now it seems stabilized Of course we can increase this number :) @@ -4520,17 +4706,18 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double You can change parameters in option.cc Itcwb_thres : 34 by default ==> number of color used in final algorithm - between 10 and max 55 - Itcwb_sort : false by default, can improve algorithm if true, ==> sort value in something near chroma order, instead of histogram number + Itcwb_sorted : true by default, can improve algorithm if true, ==> sort value in something near chroma order, instead of histogram number Itcwb_greenrange : 0 amplitude of green variation - between 0 to 2 Itcwb_greendeltatemp : 1 - delta temp in green iterate loop for "extra" - between 0 to 4 - Itcwb_forceextra : false - if true force algorithm "extra" ("extra" is used when camera wbsettings are wrong) to all images + Itcwb_forceextra : true by default - if true force algorithm "extra" ("extra" is used when camera wbsettings are wrong) to all images Itcwb_sizereference : 3 by default, can be set to 5 ==> size of reference color compare to size of histogram real color itcwb_delta : 1 by default can be set between 0 to 5 ==> delta temp to build histogram xy - if camera temp is not probably good itcwb_stdobserver10 : true by default - use standard observer 10°, false = standard observer 2° - itcwb_precis : 5 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file + itcwb_precis : 3 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file + itcwb_nopurple : true default - allow to bypass highlight recovery and inpait opposed when need flowers and not purple due to highlights... */ -// BENCHFUN - + BENCHFUN + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix("sRGB"); const float wp[3][3] = { {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, @@ -4570,7 +4757,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {0.590, 1.f}, {0.600, 1.f}, {0.610, 1.f}, - {0.620, 1.f}, + {0.620, 1.f},//extended range {0.630, 1.f}, {0.640, 1.f}, {0.650, 1.f}, @@ -4579,7 +4766,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {0.680, 1.f}, {0.690, 1.f}, {0.700, 1.f}, - {0.714, 1.f}, + {0.714, 1.f},//usual range {0.727, 1.f}, {0.741, 1.f}, {0.755, 1.f}, @@ -4610,7 +4797,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {0.971, 1.f}, {0.980, 1.f}, {0.990, 1.f}, - {1.000, 1.f},//55 + {1.000, 1.f},//55 reference {1.010, 1.f}, {1.020, 1.f}, {1.030, 1.f}, @@ -4641,14 +4828,14 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {1.325, 1.f}, {1.350, 1.f}, {1.375, 1.f}, - {1.400, 1.f}, + {1.400, 1.f},//usual range {1.425, 1.f}, {1.450, 1.f}, {1.475, 1.f}, {1.500, 1.f}, {1.525, 1.f}, {1.550, 1.f}, - {1.575, 1.f}, + {1.575, 1.f},//extended range {1.600, 1.f}, {1.633, 1.f}, {1.666, 1.f}, @@ -4697,7 +4884,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double int end; } RangeGreen; - constexpr RangeGreen Rangestandard = {24, 86}; + constexpr RangeGreen Rangestandard = {24, 86};//usual green range constexpr RangeGreen Rangeextended = {15, 93}; const RangeGreen Rangemax = {0, N_g}; @@ -4778,7 +4965,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {4927., 0.965414, 0.809229}, {4952., 0.964908, 0.814366}, {4977., 0.964415, 0.819412}, - {5002., 0.963934, 0.824438}, + {5002., 0.963934, 0.824438},//57 reference {5027., 0.963465, 0.829444}, {5052., 0.963008, 0.834429}, {5077., 0.962563, 0.839395}, @@ -4857,10 +5044,10 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double float gmm[N_t]; float bmm[N_t]; - constexpr int siza = 192;//size of histogram + constexpr int siza = 237; //192 untill 01/2023 size of histogram - //tempref and greenref are camera wb values. - // I used them by default to select good spectral values !! + // tempref and greenref are camera wb values. + // I used them by default to select good spectral values !! but they are changed after tempref = rtengine::min(tempref, 12000.0); int repref = 0; @@ -4874,7 +5061,8 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double //calculate R G B multiplier in function illuminant and temperature const bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) - || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + for (int tt = 0; tt < N_t; ++tt) { double r, g, b; float rm, gm, bm; @@ -4924,19 +5112,27 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } ; LUTu histxy(siza); //number of values for each pair xy + histxy.clear(); LUTf xxx(siza);//for color references calculated ==> max in images "like histogram" + xxx.clear(); + LUTf yyy(siza); + yyy.clear(); + LUTf YYY(siza);//not used directly, but necessary to keep good range + YYY.clear(); bool separated = true; + int w = -1; array2D reff_spect_yy_camera(N_t, 2 * Nc + 2); + array2D reff_spect_xx_camera(N_t, 2 * Nc + 2); //here we select the good spectral color inside the 113 values @@ -4965,6 +5161,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double #ifdef _OPENMP #pragma omp parallel for #endif + for (int y = 0; y < bfh ; ++y) { for (int x = 0; x < bfw ; ++x) { const float RR = rmm[rep] * redloc[y][x]; @@ -4973,6 +5170,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wp); } } + //histogram xy depend of temp...but in most cases D45 ..D65.. //calculate for this image the mean values for each family of color, near histogram x y (number) //xy vary from x 0..0.77 y 0..0.82 @@ -4982,8 +5180,14 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double // step about 0.02 x 0.32 0.34 y= 0.34 0.36 skin -- sky x 0.24 0.30 y 0.28 0.32 //big step about 0.2 - histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy); - //return histogram x and y for each temp and in a range of 158 colors (siza) + bool purp = true;//if inpaint-opposed or something else enable purp + + if (hrp.hrenabled && hrp.method == "Coloropp" && settings->itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) + purp = false; + } + + histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB + //return histogram x and y for each temp and in a range of 235 colors (siza) } // free some memory @@ -5014,15 +5218,19 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double int n4 = 0; int n15 = 0; int n30 = 0; + //part to improve //determined the number of colors who be used after for (int nh = 0; nh < siza; nh++) { if (Wbhis[nh].histnum < 30) { n30++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 15) { n15++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 4) { n4++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 1) { n1++; //keep only existing color but avoid to small } @@ -5047,7 +5255,11 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double int sizcurr2ref = sizcurrref - ntr; const int sizcu30 = sizcurrref - n30; - const int sizcu4 = rtengine::min(sizcu30, 55); + const int sizcu4 = rtengine::min(sizcu30, 55);// + + if (settings->verbose) { + printf("ntr=%i sizcurr2ref=%i sizcu30=%i sizcu4=%i\n", ntr, sizcurr2ref, sizcu30, sizcu4); + } chrom wbchro[sizcu4]; const float swpr = Txyz[repref].XX + Txyz[repref].ZZ + 1.f; @@ -5062,6 +5274,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } float estimchrom = 0.f; + //estimate chromaticity for references for (int nh = 0; nh < sizcu4; ++nh) { const float chxy = std::sqrt(SQR(xx_curref[nh][repref] - xwpr) + SQR(yy_curref[nh][repref] - ywpr)); @@ -5075,10 +5288,12 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } estimchrom /= sizcu4; - if (settings->verbose) { + + if (settings->verbose) { printf("estimchrom=%f\n", estimchrom); } - if (settings->itcwb_sort) { //sort in ascending with chroma values + + if (settings->itcwb_sorted) { //sort in ascending with chroma values std::sort(wbchro, wbchro + sizcu4, wbchro[0]); } @@ -5105,7 +5320,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double for (int nb = 1; nb <= maxnb; ++nb) { //max 5 iterations for Itcwb_thres=33, after trial 3 is good in most cases but in some cases 5 for (int i = 0; i < w; ++i) { - float mindeltaE = 100000.f; + float mindeltaE = 100000.f;//we can change this value... int kN = 0; for (int j = 0; j < Nc ; j++) { @@ -5192,7 +5407,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } } - if (extra) {//always used because I made this choice, brings better results + if (extra) {//always used if extra = true because I made this choice, brings better results struct Tempgreen { float student; int tempref; @@ -5206,14 +5421,15 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double for (int i = 0; i < N_g; ++i) {//init variables with Tgstud[i].student = 1000.f;//max value to initialize - Tgstud[i].tempref = 57;//5002K - Tgstud[i].greenref = 55;// 1.f + Tgstud[i].tempref = 57;//5002K position in the list + Tgstud[i].greenref = 55;// 1.f position in the list } const int dgoodref = rtengine::min(settings->itcwb_greendeltatemp, 4); const int scantempbeg = rtengine::max(goodref - (dgoodref + 1), 1); const int scantempend = rtengine::min(goodref + dgoodref, N_t - 1); + for (int gr = Rangegreenused.begin; gr < Rangegreenused.end; ++gr) { float minstudgr = 100000.f; int goodrefgr = 1; @@ -5249,6 +5465,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double const float BB = bmm[tt] * B_curref_reduc[i][repref]; Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wp); } + //recalculate xy spectral now with good range of temp and green for (int j = 0; j < Nc ; ++j) { @@ -5257,6 +5474,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } int kkg = -1; + for (int i = 0; i < Nc ; ++i) { if (good_spectral[i]) { kkg++; @@ -5264,6 +5482,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double reff_spect_xxyy[2 * kkg + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; } } + //now we have good spectral data //calculate student correlation const float abstudgr = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * kkg, tt)); @@ -5272,6 +5491,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double minstudgr = abstudgr; goodrefgr = tt; } + //found the values Tgstud[gr].tempref = goodrefgr; Tgstud[gr].greenref = gr; @@ -5282,48 +5502,35 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double std::sort(Tgstud, Tgstud + N_g, Tgstud[0]); - //now search the value of green the nearest of 1 with a good student value - // I take the 3 first values - //I admit a symetrie in green coefiicient for rgb multiplier...probably not exactly true - //perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% - int greengood; - int greengoodprov; - int goodrefprov; - float studprov; - const int goodref0 = Tgstud[0].tempref; - const int greengood0 = Tgstud[0].greenref - 55;//55 green = 1 - const float stud0 = Tgstud[0].student; - const int goodref1 = Tgstud[1].tempref; - const float stud1 = Tgstud[1].student; - const int greengood1 = Tgstud[1].greenref - 55; - const int goodref2 = Tgstud[2].tempref; - const int greengood2 = Tgstud[2].greenref - 55; - const float stud2 = Tgstud[2].student; + // now search the value of green the nearest of 1 with a good student value, I think it is a good choice, perhaps no... + // I take the 5 first values + // I admit a symetrie in green coefiicient for rgb multiplier...probably not exactly true + // perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% + int greengood = 55; - if (std::fabs(greengood2) < std::fabs(greengood1)) { - greengoodprov = greengood2; - goodrefprov = goodref2; - studprov = stud2; - } else { - greengoodprov = greengood1; - goodrefprov = goodref1; - studprov = stud1; + int maxkgood = 5;//we can change ...to test 3, 4, 5. High values perhaps less good student, but it is a compromise... + int mingood = std::min(std::fabs(Tgstud[0].greenref - 55), std::fabs(Tgstud[1].greenref - 55)); + for (int k = 2; k < maxkgood; ++k) { + mingood = std::min(std::fabs(mingood), std::fabs(Tgstud[k].greenref - 55)); } - if (std::fabs(greengoodprov) < std::fabs(greengood0)) { - goodref = goodrefprov; - greengood = greengoodprov + 55; - studgood = studprov; + for (int k = 0; k < maxkgood ; ++k) { + if (mingood == fabs(Tgstud[k].greenref - 55)) { + greengood = Tgstud[k].greenref ; + goodref = Tgstud[k].tempref; + studgood = Tgstud[k].student;; + } + } - } else { - goodref = goodref0; - greengood = greengood0 + 55; - studgood = stud0; + if (settings->verbose) { + printf("Student_0=%f Student_k= %f\n", Tgstud[0].student, Tgstud[maxkgood - 1].student); + printf("mingood=%i greeng=%i goodref=%i stud=%f\n", mingood, greengood, goodref, (double) studgood); } tempitc = Txyz[goodref].Tem; greenitc = gree[greengood].green; + if (estimchrom < 0.025f) { float ac = -2.40f * estimchrom + 0.06f;//small empirical correction, maximum 0.06 if chroma=0 for all image, currently for very low chroma +0.02 greenitc += ac; @@ -5337,13 +5544,14 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double if (!extra) { tempitc = Txyz[goodref].Tem; } + //now we have temp green and student if (settings->verbose) { printf("ITCWB tempitc=%f gritc=%f stud=%f \n", tempitc, greenitc, studgood); } } -void RawImageSource::WBauto(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 & studgood, bool & twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams & cmp, const RAWParams & raw) +void RawImageSource::WBauto(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 & studgood, bool & twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams & cmp, const RAWParams & raw, const ToneCurveParams &hrp) { // BENCHFUN //auto white balance @@ -5364,8 +5572,7 @@ void RawImageSource::WBauto(double & tempref, double & greenref, array2D } tempitc = 5000.; - - ItcWB(extra, tempref, greenref, tempitc, greenitc, studgood, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, cmp, raw, wbpar); + ItcWB(extra, tempref, greenref, tempitc, greenitc, studgood, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, cmp, raw, wbpar, hrp); } } @@ -5373,15 +5580,18 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int { // BENCHFUN //used by auto WB local to calculate red, green, blue in local region + int precision = 5; + if (settings->itcwb_precis == 5) { precision = 5; } else if (settings->itcwb_precis < 5) { - precision = 3; + precision = 3; } else if (settings->itcwb_precis > 5) { precision = 9; } + 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); @@ -5404,6 +5614,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int #ifdef _OPENMP #pragma omp parallel for reduction(+:avgL, nn) #endif + for (int i = 0; i < H; i ++) { for (int j = 0; j < W; j++) { const float LL = 0.299f * red[i][j] + 0.587f * green[i][j] + 0.114f * blue[i][j]; @@ -5411,6 +5622,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int nn++; } } + avgL /= nn; double vari = 0.f; @@ -5419,6 +5631,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int #ifdef _OPENMP #pragma omp parallel for reduction(+:vari, mm) #endif + for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { const float LL = 0.299f * red[i][j] + 0.587f * green[i][j] + 0.114f * blue[i][j]; @@ -5432,8 +5645,10 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int #ifdef _OPENMP #pragma omp parallel for #endif + for (int i = 0; i < bfh; ++i) { const int ii = i * precision; + if (ii < H) { for (int j = 0, jj = 0; j < bfw; ++j, jj += precision) { redloc[i][j] = red[ii][jj] * multip; @@ -5444,7 +5659,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int } } -void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref, double & tempitc, double & greenitc, float &studgood, 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) +void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref, double & tempitc, double & greenitc, float &studgood, 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) { // BENCHFUN constexpr double clipHigh = 64000.0; @@ -5459,6 +5674,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref double avg_b = 0; int rn = 0, gn = 0, bn = 0; double avg_rm, avg_gm, avg_bm; + if (wbpar.method == "autold") { if (fuji) { for (int i = 32; i < H - 32; i++) { @@ -5468,7 +5684,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref for (int j = start; j < end; j++) { if (ri->getSensorType() != ST_BAYER) { - double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dr = CLIP(initialGain * (rawData[i][3 * j])); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -5507,18 +5723,18 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref if (ri->getSensorType() == ST_FUJI_XTRANS) { const double compval = clipHigh / initialGain; #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel #endif { double avg_c[3] = {0.0}; int cn[3] = {0}; #ifdef _OPENMP - #pragma omp for schedule(dynamic,16) nowait + #pragma omp for schedule(dynamic,16) nowait #endif for (int i = 32; i < H - 32; i++) { for (int j = 32; j < W - 32; j++) { - // each loop read 1 rgb triplet value + // each loop read 1 rgb triplet value double d = rawData[i][j]; if (d > compval) { @@ -5532,7 +5748,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref } #ifdef _OPENMP - #pragma omp critical + #pragma omp critical #endif { avg_r += avg_c[0]; @@ -5549,9 +5765,9 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref } else { for (int i = 32; i < H - 32; i++) for (int j = 32; j < W - 32; j++) { - // each loop read 1 rgb triplet value + // each loop read 1 rgb triplet value - double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dr = CLIP(initialGain * (rawData[i][3 * j])); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -5569,7 +5785,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref bn = rn; } } else { - //determine GRBG coset; (ey,ex) is the offset of the R subarray + //determine GRBG coset; (ey,ex) is the offset of the R subarray int ey, ex; if (ri->ISGREEN(0, 0)) { //first pixel is G @@ -5592,12 +5808,12 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref const double compval = clipHigh / initialGain; #ifdef _OPENMP - #pragma omp parallel for reduction(+:avg_r,avg_g,avg_b,rn,gn,bn) schedule(dynamic,8) + #pragma omp parallel for reduction(+:avg_r,avg_g,avg_b,rn,gn,bn) schedule(dynamic,8) #endif for (int i = 32; i < H - 32; i += 2) for (int j = 32; j < W - 32; j += 2) { - //average each Bayer quartet component individually if non-clipped + //average each Bayer quartet component individually if non-clipped double d[2][2]; d[0][0] = rawData[i][j]; d[0][1] = rawData[i][j + 1]; @@ -5636,17 +5852,18 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref if (wbpar.method == "autitcgreen") { bool twotimes = false; int precision = 5; + if (settings->itcwb_precis == 5) { precision = 5; } else if (settings->itcwb_precis < 5) { - precision = 3; + precision = 3; } else if (settings->itcwb_precis > 5) { precision = 9; } - + 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); - WBauto(tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, studgood, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw); + WBauto(tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, studgood, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw, hrp); } redloc(0, 0); @@ -5654,7 +5871,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref blueloc(0, 0); if (settings->verbose) { - printf ("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); + printf("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") { @@ -5673,7 +5890,7 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref } -void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) +void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) { // BENCHFUN constexpr double clipHigh = 64000.0; @@ -5710,7 +5927,7 @@ void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) for (int j = start; j < end; j++) { if (ri->getSensorType() != ST_BAYER) { - double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dr = CLIP(initialGain * (rawData[i][3 * j])); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -5793,7 +6010,7 @@ void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) for (int j = 32; j < W - 32; j++) { // each loop read 1 rgb triplet value - double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dr = CLIP(initialGain * (rawData[i][3 * j])); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -5875,7 +6092,7 @@ void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) } if (settings->verbose) { - printf ("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); + printf("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); } // return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index d7549fe71..fabea5ffc 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -112,7 +112,7 @@ protected: void hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax); void transformRect(const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw); void transformPosition(int x, int y, int tran, int& tx, int& ty); - void ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar); + void ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar, const procparams::ToneCurveParams &hrp); unsigned FC(int row, int col) const; inline void getRowStartEnd (int x, int &start, int &end); @@ -141,12 +141,12 @@ public: void processFlatField(const procparams::RAWParams &raw, const 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(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 &studgood, 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) override; - void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; + void WBauto(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 &studgood, 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; + void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) 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 getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw, int opposed) override; eSensorType getSensorType () const override; bool isMono () const override; ColorTemp getWB () const override @@ -199,7 +199,8 @@ public: 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); void HLRecovery_inpaint (float** red, float** green, float** blue, int blur); - static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); + void highlight_recovery_opposed(float scale_mul[3], const ColorTemp &wb, float gainth); + static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]); static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax); static void init (); @@ -308,6 +309,9 @@ protected: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override; void applyDngGainMap(const float black[4], const std::vector &gainMaps); +public: + void wbMul2Camera(double &rm, double &gm, double &bm) override; + void wbCamera2Mul(double &rm, double &gm, double &bm) override; }; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3916adfbe..eb4a3f888 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -94,7 +94,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { HDR, // EvCACorr, ALLNORAW, // EvHREnabled, 0, // EvHRAmount : obsolete, - ALLNORAW, // EvHRMethod, + ALLNORAW|M_RAW, // EvHRMethod, DEMOSAIC, // EvWProfile, OUTPUTPROFILE, // EvOProfile, ALLNORAW, // EvIProfile, diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 86f1c1372..84c33a734 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -349,7 +349,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml PreviewProps pp(0, 0, w, h, 1); Imagefloat tmp(w, h); - src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw); + src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw, 0); src.convertColorSpace(&tmp, neutral.icm, src.getWB()); Image8 *img = new Image8(w, h); diff --git a/rtengine/settings.h b/rtengine/settings.h index 1c8c73630..6e787a112 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -44,6 +44,7 @@ public: bool monitorBPC; ///< Black Point Compensation for the Labimage->Monitor transform (directly, i.e. not soft-proofing and no WCS in between) bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; + bool observer10; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode bool verbose; Glib::ustring darkFramesPath; ///< The default directory for dark frames @@ -94,7 +95,7 @@ public: // bool showtooltip; int itcwb_thres; - bool itcwb_sort; + bool itcwb_sorted; int itcwb_greenrange; int itcwb_greendeltatemp; bool itcwb_forceextra; @@ -102,6 +103,7 @@ public: int itcwb_delta; bool itcwb_stdobserver10; int itcwb_precis; + bool itcwb_nopurple; //wavelet levels double edghi; double edglo; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index c542cf726..5de3b08b0 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -261,7 +261,7 @@ private: pl->setProgress(0.40); } - imgsrc->HLRecovery_Global(params.toneCurve); + // imgsrc->HLRecovery_Global(params.toneCurve); if (pl) { @@ -372,7 +372,7 @@ private: int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f; int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; PreviewProps ppP(beg_tileW, beg_tileH, crW, crH, skipP); - imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); + imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); // we only need image reduced to 1/4 here @@ -596,7 +596,7 @@ private: for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1); - imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); + imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); @@ -756,7 +756,7 @@ private: } baseImg = new Imagefloat(fw, fh); - imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw); + imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw, 1); if (pl) { pl->setProgress(0.50); diff --git a/rtengine/spot.cc b/rtengine/spot.cc index 5ed090712..09186a399 100644 --- a/rtengine/spot.cc +++ b/rtengine/spot.cc @@ -459,7 +459,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s } } - imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw); + imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw, 0); if (cmp) { imgsrc->convertColorSpace(srcImage, *cmp, currWB); } @@ -479,7 +479,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s dstImage->b(y, x) = 60000.f; } } - imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw); + imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw, 0); if (cmp) { imgsrc->convertColorSpace(dstImage, *cmp, currWB); } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 8cb8fa792..a3f2502f0 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -193,7 +193,7 @@ int StdImageSource::load (const Glib::ustring &fname) return 0; } -void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) +void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) { // the code will use OpenMP as of now. @@ -311,11 +311,11 @@ void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) } } -void StdImageSource::WBauto(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 &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw) +void StdImageSource::WBauto(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 &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp) { } -void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) +void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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.) { rm = redAWBMul; @@ -324,7 +324,7 @@ void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, return; } - img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw); + img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); redAWBMul = rm; greenAWBMul = gm; @@ -367,6 +367,20 @@ void StdImageSource::flush() { img->allocate(0, 0); }; +void StdImageSource::wbMul2Camera(double &rm, double &gm, double &bm) +{ + rm = 1.0 / rm; + gm = 1.0 / gm; + bm = 1.0 / bm; +} + + +void StdImageSource::wbCamera2Mul(double &rm, double &gm, double &bm) +{ + rm = 1.0 / rm; + gm = 1.0 / gm; + bm = 1.0 / bm; +} } diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index f83c58a04..90c4be654 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -58,7 +58,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 getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw, int opposed) override; void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) override {}; ColorTemp getWB () const override { @@ -66,8 +66,8 @@ public: } void getAutoWBMultipliers (double &rm, double &gm, double &bm) override; ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) override; - void WBauto(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 &studgood, 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) override; - void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; + void WBauto(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 &studgood, 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; + void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; eSensorType getSensorType() const override {return ST_NONE;} bool isMono() const override {return false;} @@ -123,6 +123,8 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} + void wbMul2Camera(double &rm, double &gm, double &bm) override; + void wbCamera2Mul(double &rm, double &gm, double &bm) override; void flush () override; void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override {}; diff --git a/rtgui/options.cc b/rtgui/options.cc index 3ce97567c..66b9e92a1 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -594,6 +594,7 @@ void Options::setDefaults() rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.monitorBPC = true; rtSettings.autocielab = false; + rtSettings.observer10 = false; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RTv2_Medium"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RTv2_Large"; // these names appear in the menu "output profile" @@ -623,14 +624,15 @@ void Options::setDefaults() rtSettings.fftwsigma = true; //choice between sigma^2 or empirical formula rtSettings.itcwb_thres = 34;//between 10 to 55 - rtSettings.itcwb_sort = false; + rtSettings.itcwb_sorted = true; rtSettings.itcwb_greenrange = 0;//between 0 to 2 rtSettings.itcwb_greendeltatemp = 2;//between 0 and 4 rtSettings.itcwb_forceextra = true; rtSettings.itcwb_sizereference = 3;//between 1 and 5 rtSettings.itcwb_delta = 1;//between 0 and 5 rtSettings.itcwb_stdobserver10 = true; - rtSettings.itcwb_precis = 5;//3 or 5 or 9 + rtSettings.itcwb_precis = 3;//3 or 5 or 9 + rtSettings.itcwb_nopurple = true; // end locallab //wavelet @@ -1760,6 +1762,10 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.autocielab = keyFile.get_boolean("Color Management", "Autocielab"); } + if (keyFile.has_key("Color Management", "Observer10")) { + rtSettings.observer10 = keyFile.get_boolean("Color Management", "Observer10"); + } + if (keyFile.has_key("Color Management", "CRI")) { rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); } @@ -1795,14 +1801,18 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.itcwb_thres = keyFile.get_integer("Color Management", "Itcwb_thres"); } - if (keyFile.has_key("Color Management", "Itcwb_sort")) { - rtSettings.itcwb_sort = keyFile.get_boolean("Color Management", "Itcwb_sort"); + if (keyFile.has_key("Color Management", "Itcwb_sorted")) { + rtSettings.itcwb_sorted = keyFile.get_boolean("Color Management", "Itcwb_sorted"); } if (keyFile.has_key("Color Management", "Itcwb_forceextra")) { rtSettings.itcwb_forceextra = keyFile.get_boolean("Color Management", "Itcwb_forceextra"); } + if (keyFile.has_key("Color Management", "Itcwb_nopurple")) { + rtSettings.itcwb_nopurple = keyFile.get_boolean("Color Management", "Itcwb_nopurple"); + } + if (keyFile.has_key("Color Management", "Itcwb_stdobserver10")) { rtSettings.itcwb_stdobserver10 = keyFile.get_boolean("Color Management", "Itcwb_stdobserver10"); } @@ -2563,6 +2573,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Color Management", "MonitorProfile", rtSettings.monitorProfile); keyFile.set_boolean("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean("Color Management", "Autocielab", rtSettings.autocielab); + keyFile.set_boolean("Color Management", "Observer10", rtSettings.observer10); keyFile.set_boolean("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); keyFile.set_integer("Color Management", "Intent", rtSettings.monitorIntent); keyFile.set_boolean("Color Management", "MonitorBPC", rtSettings.monitorBPC); @@ -2596,10 +2607,11 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_double("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); keyFile.set_double("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); keyFile.set_integer("Color Management", "Itcwb_thres", rtSettings.itcwb_thres); - keyFile.set_boolean("Color Management", "Itcwb_sort", rtSettings.itcwb_sort); + keyFile.set_boolean("Color Management", "Itcwb_sorted", rtSettings.itcwb_sorted); keyFile.set_integer("Color Management", "Itcwb_greenrange", rtSettings.itcwb_greenrange); keyFile.set_integer("Color Management", "Itcwb_greendeltatemp", rtSettings.itcwb_greendeltatemp); keyFile.set_boolean("Color Management", "Itcwb_forceextra", rtSettings.itcwb_forceextra); + keyFile.set_boolean("Color Management", "Itcwb_nopurple", rtSettings.itcwb_nopurple); keyFile.set_integer("Color Management", "Itcwb_sizereference", rtSettings.itcwb_sizereference); keyFile.set_integer("Color Management", "Itcwb_delta", rtSettings.itcwb_delta); keyFile.set_boolean("Color Management", "Itcwb_stdobserver10", rtSettings.itcwb_stdobserver10); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 7d641d753..abd4e8608 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -48,6 +48,7 @@ void ParamsEdited::set(bool v) toneCurve.shcompr = v; toneCurve.hlcompr = v; toneCurve.hlbl = v; + toneCurve.hlth = v; toneCurve.hlcomprthresh = v; toneCurve.autoexp = v; toneCurve.clip = v; @@ -749,6 +750,7 @@ void ParamsEdited::initFrom(const std::vector& toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr; toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr; toneCurve.hlbl = toneCurve.hlbl && p.toneCurve.hlbl == other.toneCurve.hlbl; + toneCurve.hlth = toneCurve.hlth && p.toneCurve.hlth == other.toneCurve.hlth; toneCurve.hlcomprthresh = toneCurve.hlcomprthresh && p.toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh; toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp; toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip; @@ -2192,6 +2194,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.toneCurve.hlbl = mods.toneCurve.hlbl; } + if (toneCurve.hlth) { + toEdit.toneCurve.hlth = mods.toneCurve.hlth; + } + if (toneCurve.histmatching) { toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 616e6d261..66db8346f 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -52,6 +52,7 @@ struct ToneCurveParamsEdited { bool shcompr; bool hlcompr; bool hlbl; + bool hlth; bool hlcomprthresh; bool autoexp; bool clip; diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index c39bd3bda..bf81c6f22 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -42,6 +42,7 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL EvHistMatchingBatch = m->newEvent(M_VOID, "HISTORY_MSG_HISTMATCHING"); EvClampOOG = m->newEvent(DARKFRAME, "HISTORY_MSG_CLAMPOOG"); EvHLbl = m->newEvent(DEMOSAIC, "HISTORY_MSG_HLBL"); + EvHLth = m->newEvent(DEMOSAIC, "HISTORY_MSG_HLTH"); CurveListener::setMulti(true); @@ -97,13 +98,14 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL method = Gtk::manage (new MyComboBoxText ()); method->append (M("TP_HLREC_LUMINANCE")); method->append (M("TP_HLREC_CIELAB")); - method->append (M("TP_HLREC_COLOR")); method->append (M("TP_HLREC_BLEND")); + method->append (M("TP_HLREC_COLOR")); + method->append (M("TP_HLREC_COLOROPP")); Gtk::Box *hrVBox; hrVBox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); hrVBox->set_spacing(2); - method->set_active(0); + method->set_active(4); Gtk::Frame* const hrFrame = Gtk::manage(new Gtk::Frame()); hrFrame->set_label_align(0.025, 0.5); hrFrame->set_label_widget(*hrenabled); @@ -113,9 +115,11 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL hlrbox->pack_start (*lab, Gtk::PACK_SHRINK); hlrbox->pack_start (*method); hlbl = Gtk::manage(new Adjuster(M("TP_HLREC_HLBLUR"), 0, 4, 1, 0)); + hlth = Gtk::manage(new Adjuster(M("TP_HLREC_HLTH"), 0.25, 1.75, 0.01, 1.)); hrVBox->pack_start(*hlrbox, Gtk::PACK_SHRINK); hrVBox->pack_start(*hlbl); + hrVBox->pack_start(*hlth); hrFrame->add(*hrVBox); pack_start(*hrFrame); @@ -223,6 +227,7 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL black->setAdjusterListener(this); hlcompr->setAdjusterListener(this); hlbl->setAdjusterListener(this); + hlth->setAdjusterListener(this); hlcomprthresh->setAdjusterListener(this); shcompr->setAdjusterListener(this); contrast->setAdjusterListener(this); @@ -254,6 +259,7 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited) black->setValue(pp->toneCurve.black); hlcompr->setValue(pp->toneCurve.hlcompr); hlbl->setValue(pp->toneCurve.hlbl); + hlth->setValue(pp->toneCurve.hlth); hlcomprthresh->setValue(pp->toneCurve.hlcomprthresh); shcompr->setValue(pp->toneCurve.shcompr); @@ -283,6 +289,7 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited) black->setEditedState(pedited->toneCurve.black ? Edited : UnEdited); hlcompr->setEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited); hlbl->setEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited); + hlth->setEditedState(pedited->toneCurve.hlth ? Edited : UnEdited); hlcomprthresh->setEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); shcompr->setEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited); brightness->setEditedState(pedited->toneCurve.brightness ? Edited : UnEdited); @@ -310,16 +317,18 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited) hrenabled->set_active(pp->toneCurve.hrenabled); enaconn.block(false); - if (pedited && !pedited->toneCurve.method) { - method->set_active(4); - } else if (pp->toneCurve.method == "Luminance") { + if (pedited && !pedited->toneCurve.method) { + method->set_active(5); + } else if (pp->toneCurve.method == "Luminance") { method->set_active(0); } else if (pp->toneCurve.method == "CIELab blending") { method->set_active(1); - } else if (pp->toneCurve.method == "Color") { - method->set_active(2); } else if (pp->toneCurve.method == "Blend") { + method->set_active(2); + } else if (pp->toneCurve.method == "Color") { method->set_active(3); + } else if (pp->toneCurve.method == "Coloropp") { + method->set_active(4); } hrenabledChanged(); @@ -354,6 +363,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited) pp->toneCurve.black = black->getValue(); pp->toneCurve.hlcompr = hlcompr->getValue(); pp->toneCurve.hlbl = hlbl->getValue(); + pp->toneCurve.hlth = hlth->getValue(); pp->toneCurve.hlcomprthresh = hlcomprthresh->getValue(); pp->toneCurve.shcompr = shcompr->getValue(); pp->toneCurve.brightness = brightness->getValue(); @@ -403,6 +413,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited) pedited->toneCurve.black = black->getEditedState(); pedited->toneCurve.hlcompr = hlcompr->getEditedState(); pedited->toneCurve.hlbl = hlbl->getEditedState(); + pedited->toneCurve.hlth = hlth->getEditedState(); pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState(); pedited->toneCurve.shcompr = shcompr->getEditedState(); pedited->toneCurve.brightness = brightness->getEditedState(); @@ -414,7 +425,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited) pedited->toneCurve.curve2 = !shape2->isUnChanged(); pedited->toneCurve.curveMode = toneCurveMode->get_active_row_number() != 6; pedited->toneCurve.curveMode2 = toneCurveMode2->get_active_row_number() != 6; - pedited->toneCurve.method = method->get_active_row_number() != 4; + pedited->toneCurve.method = method->get_active_row_number() != 5; pedited->toneCurve.hrenabled = !hrenabled->get_inconsistent(); pedited->toneCurve.histmatching = !histmatching->get_inconsistent(); pedited->toneCurve.fromHistMatching = true; @@ -428,9 +439,11 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited) } else if (method->get_active_row_number() == 1) { pp->toneCurve.method = "CIELab blending"; } else if (method->get_active_row_number() == 2) { - pp->toneCurve.method = "Color"; - } else if (method->get_active_row_number() == 3) { pp->toneCurve.method = "Blend"; + } else if (method->get_active_row_number() == 3) { + pp->toneCurve.method = "Color"; + } else if (method->get_active_row_number() == 4) { + pp->toneCurve.method = "Coloropp"; } } @@ -454,15 +467,21 @@ void ToneCurve::hrenabledChanged() if (hrenabled->get_active()) { hlrbox->show(); hlrbox->set_sensitive(true); - if (method->get_active_row_number() == 2) { + if (method->get_active_row_number() == 3) { hlbl->show(); + hlth->hide(); + } else if (method->get_active_row_number() == 4){ + hlbl->hide(); + hlth->show(); } else { hlbl->hide(); - } + hlth->hide(); + } } else { hlrbox->show(); hlrbox->set_sensitive(false); hlbl->hide(); + hlth->hide(); } } @@ -487,11 +506,16 @@ void ToneCurve::hrenabledChanged() void ToneCurve::methodChanged() { - if (method->get_active_row_number() == 2) { + if (method->get_active_row_number() == 3) { hlbl->show(); - } else { + hlth->hide(); + } else if (method->get_active_row_number() == 4){ hlbl->hide(); - } + hlth->show(); + } else { + hlbl->hide(); + hlth->hide(); + } if (listener) { setHistmatching(false); if (hrenabled->get_active()) { @@ -513,6 +537,7 @@ void ToneCurve::setRaw(bool raw) disableListener(); method->set_sensitive(raw); hlbl->set_sensitive(raw); + hlth->set_sensitive(raw); hrenabled->set_sensitive(raw); histmatching->set_sensitive(raw); enableListener(); @@ -526,6 +551,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped black->setDefault(defParams->toneCurve.black); hlcompr->setDefault(defParams->toneCurve.hlcompr); hlbl->setDefault(defParams->toneCurve.hlbl); + hlth->setDefault(defParams->toneCurve.hlth); hlcomprthresh->setDefault(defParams->toneCurve.hlcomprthresh); shcompr->setDefault(defParams->toneCurve.shcompr); contrast->setDefault(defParams->toneCurve.contrast); @@ -536,6 +562,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped black->setDefaultEditedState(pedited->toneCurve.black ? Edited : UnEdited); hlcompr->setDefaultEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited); hlbl->setDefaultEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited); + hlth->setDefaultEditedState(pedited->toneCurve.hlth ? Edited : UnEdited); hlcomprthresh->setDefaultEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); shcompr->setDefaultEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited); brightness->setDefaultEditedState(pedited->toneCurve.brightness ? Edited : UnEdited); @@ -546,6 +573,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped black->setDefaultEditedState(Irrelevant); hlcompr->setDefaultEditedState(Irrelevant); hlbl->setDefaultEditedState(Irrelevant); + hlth->setDefaultEditedState(Irrelevant); hlcomprthresh->setDefaultEditedState(Irrelevant); shcompr->setDefaultEditedState(Irrelevant); brightness->setDefaultEditedState(Irrelevant); @@ -660,6 +688,8 @@ void ToneCurve::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvSaturation, costr); } else if (a == hlbl) { listener->panelChanged(EvHLbl, costr); + } else if (a == hlth) { + listener->panelChanged(EvHLth, costr); } else if (a == hlcompr) { listener->panelChanged(EvHLCompr, costr); @@ -695,6 +725,7 @@ void ToneCurve::neutral_pressed() expcomp->setValue(0); hlcompr->setValue(0); hlbl->setValue(0); + hlth->setValue(1.0); hlcomprthresh->setValue(0); brightness->setValue(0); black->setValue(0); @@ -707,6 +738,7 @@ void ToneCurve::neutral_pressed() hlrbox->show(); hlrbox->set_sensitive(false); hlbl->hide(); + hlth->hide(); } if (!black->getAddMode() && !batchMode) { @@ -841,6 +873,7 @@ void ToneCurve::waitForAutoExp() hrenabled->set_sensitive(false); method->set_sensitive(false); hlbl->set_sensitive(false); + hlth->set_sensitive(false); histmatching->set_sensitive(false); } @@ -853,6 +886,7 @@ void ToneCurve::enableAll() black->setEnabled(true); hlcompr->setEnabled(true); hlbl->setEnabled(true); + hlth->setEnabled(true); hlcomprthresh->setEnabled(true); shcompr->setEnabled(true); contrast->setEnabled(true); @@ -864,6 +898,7 @@ void ToneCurve::enableAll() hrenabled->set_sensitive(true); method->set_sensitive(true); hlbl->set_sensitive(true); + hlth->set_sensitive(true); histmatching->set_sensitive(true); } @@ -883,6 +918,7 @@ void ToneCurve::setBatchMode(bool batchMode) black->showEditedCB(); hlcompr->showEditedCB(); hlbl->showEditedCB(); + hlth->showEditedCB(); hlcomprthresh->showEditedCB(); shcompr->showEditedCB(); brightness->showEditedCB(); @@ -996,16 +1032,22 @@ void ToneCurve::autoExpChanged(double expcomp, int bright, int contr, int black, if (nextHLRecons) { hlrbox->show(); hlrbox->set_sensitive(true); - if (method->get_active_row_number() == 2) { + if (method->get_active_row_number() == 3) { hlbl->show(); - } else { + hlth->hide(); + } else if (method->get_active_row_number() == 4){ hlbl->hide(); - } + hlth->show(); + } else { + hlbl->hide(); + hlth->hide(); + } } else if (!batchMode) { hlrbox->show(); hlrbox->set_sensitive(false); hlbl->hide(); - } + hlth->hide(); + } if (!this->black->getAddMode() && !batchMode) { shcompr->set_sensitive(static_cast(this->black->getValue())); //at black=0 shcompr value has no effect diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 7ba2178ac..7f0f1ef69 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -48,6 +48,7 @@ protected: sigc::connection enaconn; bool lasthrEnabled; Adjuster* hlbl; + Adjuster* hlth; Gtk::Box* abox; Gtk::Box* hlrbox; @@ -82,6 +83,7 @@ protected: rtengine::ProcEvent EvHistMatchingBatch; rtengine::ProcEvent EvClampOOG; rtengine::ProcEvent EvHLbl; + rtengine::ProcEvent EvHLth; // used temporarily in eventing double nextExpcomp; From 8047aded3ba4756233be0d4e833e535bdd6293f0 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Thu, 9 Feb 2023 16:15:42 +0100 Subject: [PATCH 176/326] remove BENCHFUN for inpaint-opposed color-propagation Itcwb --- rtengine/hilite_recon.cc | 4 ++-- rtengine/rawimagesource.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 07d1a7b7b..f573ff015 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -302,7 +302,7 @@ using namespace procparams; void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue, int blur) { - BENCHFUN + //BENCHFUN double progress = 0.0; if (plistener) { @@ -1347,7 +1347,7 @@ void dilating(const int *img, int *o, int w1, int height) void RawImageSource::highlight_recovery_opposed(float scale_mul[3], const ColorTemp &wb, float gainth) { - BENCHFUN + //BENCHFUN if (settings->verbose) { std::cout << "Applying Highlight Recovery: Inpaint opposed" << std::endl; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 7ff9c4d0f..75757d325 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4716,7 +4716,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double itcwb_precis : 3 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file itcwb_nopurple : true default - allow to bypass highlight recovery and inpait opposed when need flowers and not purple due to highlights... */ - BENCHFUN + // BENCHFUN TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix("sRGB"); const float wp[3][3] = { From e5904297864b95a02d93e955a6b3d14d87cccd94 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 11 Feb 2023 17:51:43 -0800 Subject: [PATCH 177/326] Remove outdated comment Issue #5787 in the Exiv2 branch is handled by commit 522f6f4. --- rtengine/imageio.cc | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 67b856092..9aa8a0702 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1152,23 +1152,6 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_ADOBE_DEFLATE); TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, (bps == 16 || bps == 32) && isFloat ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT); - /* - - TODO: Re-apply fix from #5787 - - [out]() - { - const std::vector default_tags = rtexif::ExifManager::getDefaultTIFFTags(nullptr); - - TIFFSetField (out, TIFFTAG_XRESOLUTION, default_tags[2]->toDouble()); - TIFFSetField (out, TIFFTAG_YRESOLUTION, default_tags[3]->toDouble()); - TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, default_tags[4]->toInt()); - - for (auto default_tag : default_tags) { - delete default_tag; - } - }();*/ - // somehow Exiv2 (tested with 0.27.3) doesn't seem to be able to update // XResolution and YResolution, so we do it ourselves here.... constexpr float default_resolution = 300.f; From 9c6dac5f25be4473610b2d30d5f5ab4f76605f31 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 11 Feb 2023 18:06:20 -0800 Subject: [PATCH 178/326] Remove outdated comments Validation of metadata is still needed for #5923. --- rtengine/imagedata.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index bf80f8c51..0ed5ab253 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -160,11 +160,11 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : // List of tag names taken from exiv2's printSummary() in actions.cpp if (find_tag(Exiv2::make)) { - make = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + make = validateUft8(pos->print(&exif)); } if (find_tag(Exiv2::model)) { - model = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + model = validateUft8(pos->print(&exif)); } if (make.size() > 0) { @@ -303,15 +303,15 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } if (find_tag(Exiv2::lensName)) { - lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + lens = validateUft8(pos->print(&exif)); auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { - lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + lens = validateUft8(pos->print(&exif)); } else if (p->count() == 1 && lens == std::to_string(p->toLong())) { if (find_exif_tag("Exif.Canon.LensModel")) { - lens = validateUft8(pos->print(&exif)); // validateUft8 (#5923) still needed? + lens = validateUft8(pos->print(&exif)); } else if (find_exif_tag("Exif.Photo.LensModel")) { - lens = validateUft8(p->print(&exif)); // validateUft8 (#5923) still needed? + lens = validateUft8(p->print(&exif)); } } } else if (find_exif_tag("Exif.Photo.LensSpecification") && pos->count() == 4) { @@ -333,7 +333,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : if (fn_lo < fn_hi) { buf << "-" << fn_hi; } - lens = buf.str(); + lens = validateUft8(buf.str()); } if (lens.empty() || lens.find_first_not_of('-') == std::string::npos) { lens = "Unknown"; From cf545abc874c98e3578495b7e423ff850fac0553 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Feb 2023 17:10:00 -0800 Subject: [PATCH 179/326] Read serial number with Exiv2 --- rtengine/imagedata.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 0ed5ab253..4c4d4112b 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -264,6 +264,44 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } } + if (find_tag(Exiv2::serialNumber)) { + serial = validateUft8(pos->toString()); + } else { + const std::vector serial_number_tags{ + "Exif.Photo.BodySerialNumber", + "Exif.Canon.SerialNumber", + "Exif.Fujifilm.SerialNumber", + "Exif.Nikon3.SerialNumber", + "Exif.Nikon3.SerialNO", + "Exif.Olympus.SerialNumber2", + "Exif.OlympusEq.SerialNumber", + "Exif.Pentax.SerialNumber", + "Exif.PentaxDng.SerialNumber", + "Exif.Sigma.SerialNumber", + "Exif.Canon.InternalSerialNumber", + "Exif.OlympusEq.InternalSerialNumber", + "Exif.Panasonic.InternalSerialNumber", + }; + if (serial_number_tags.cend() != std::find_if(serial_number_tags.cbegin(), serial_number_tags.cend(), find_exif_tag)) { + serial = validateUft8(pos->toString()); + } else if (find_exif_tag("Exif.Minolta.WBInfoA100") || find_exif_tag("Exif.SonyMinolta.WBInfoA100")) { + const long index = 18908; + const int length = 12; + if (pos->count() >= index + length) { + for (int i = 0; i < length; ++i) { + serial += static_cast(pos->toLong(index + i)); + } + serial = validateUft8(serial); + } + } else if (find_exif_tag("Exif.Pentax.CameraInfo") || find_exif_tag("Exif.PentaxDng.CameraInfo")) { + const long index = 4; + if (pos->count() >= index) { + serial = validateUft8(pos->toString(index)); + } + } + // TODO: Serial number from tags not supported by Exiv2. + } + if (find_tag(Exiv2::focalLength)) { // This works around a bug in exiv2 the developers refuse to fix // For details see http://dev.exiv2.org/issues/1083 From cac76c18c0672166e8e6ab76e5bf1562d428ada8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Feb 2023 17:47:07 -0800 Subject: [PATCH 180/326] Re-introduce UTF-8 validation for EXIF panel --- rtgui/exifpanel.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 0664132f6..487635f5b 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -194,13 +194,10 @@ void ExifPanel::setImageData (const FramesMetaData* id) idata = id; } -void ExifPanel::addTag(const std::string &key, const std::pair &label, const Glib::ustring &value, bool editable, bool edited) +void ExifPanel::addTag(const std::string &key, const std::pair &label, const Glib::ustring &exifValue, bool editable, bool edited) { - // TODO Re-fix #5923 if necessary - //if (!value.validate()) { - // value = "???"; - //} + const Glib::ustring& value = exifValue.validate() ? exifValue : "???"; // auto root = exifTreeModel->children(); From a329e423ec6086b84b3a6d3b2c0ec25fbb51d066 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Feb 2023 18:19:28 -0800 Subject: [PATCH 181/326] Remove outdated comments about ratings --- rtengine/imagedata.cc | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4c4d4112b..4e5022973 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -88,7 +88,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : make("Unknown"), model("Unknown"), orientation("Unknown"), - rating(0), // FIXME: Implement + rating(0), lens("Unknown"), sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), @@ -196,27 +196,6 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } } - /* - TODO: Implement ratings in exiv2 situations. See PR #5325 - - // Look for Rating metadata in the following order: - // 1. EXIF - // 2. XMP - // 3. pp3 sidecar file - tag = newFrameRootDir->findTagUpward("Rating"); - if (tag && tag->toInt() != 0) { - rating = tag->toInt(); - } - char sXMPRating[64]; - if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) { - // Guard against out-of-range values (<0, >5) - rating = rtengine::max(0, rtengine::min(5, atoi(sXMPRating))); - // Currently, Rating=-1 is not supported. A value of -1 should mean - // "Rejected" according to the specification. Maybe in the future, Rating=-1 - // sets InTrash=true? - } - */ - std::string::size_type nonspace_pos = make.find_last_not_of(' '); if (nonspace_pos != std::string::npos && nonspace_pos + 1 < make.size()) { make.erase(nonspace_pos + 1); From 8704c1dd8655e43abfd0631e5bcd66e7fb1c1314 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Wed, 15 Feb 2023 21:34:03 -0800 Subject: [PATCH 182/326] Add bound check Thanks to Floessie (https://github.com/Beep6581/RawTherapee/pull/5889#discussion_r622755925) --- rtengine/dcp.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 1f9de0158..29d3625a2 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -650,13 +650,16 @@ public: } case FLOAT: { - union IntFloat { - std::uint32_t i; - float f; - } conv; + if (offset + 3 < tag->second.value.size()) { + union IntFloat { + std::uint32_t i; + float f; + } conv; - conv.i = sget4(tag->second.value.data() + offset); - return conv.f; // IEEE FLOATs are already C format, they just need a recast + conv.i = sget4(tag->second.value.data() + offset); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + } + return 0.0; } default: { From d5aae723b8adc74d12fd548a5f3bdb0838d94309 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Thu, 16 Feb 2023 11:10:18 +0100 Subject: [PATCH 183/326] Fixed the same Observer for general and Itcwb --- rtengine/colortemp.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 4ba47b25a..f6e980f2a 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -3764,15 +3764,17 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float Refxyz[i].Zref = 0.f; } - if (settings->verbose) { +/* if (settings->verbose) { + if (settings->itcwb_stdobserver10 == false) {//I will try to change settings by main printf("Use standard observer 2°\n"); } else { printf("Use standard observer 10°\n"); } - } - - const color_match_type &color_match = (settings->itcwb_stdobserver10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; + } +*/ + const color_match_type &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; + // const color_match_type &color_match = (settings->itcwb_stdobserver10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; if (separated) { const double tempw = Txyz[repref].Tem; From 01441ccb4b1ea76105cf9173e608e25e6de09229 Mon Sep 17 00:00:00 2001 From: Matei George-Daniel Date: Sat, 18 Feb 2023 02:55:15 +0200 Subject: [PATCH 184/326] initialize pointer variable with null --- rtengine/improccoordinator.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index cc2d75b3d..9437f1a75 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -163,6 +163,7 @@ ImProcCoordinator::ImProcCoordinator() : imageTypeListener(nullptr), filmNegListener(nullptr), actListener(nullptr), + primListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), From 887cf9966526487dbe62d5628d52023059040a0f Mon Sep 17 00:00:00 2001 From: Matei George-Daniel Date: Sat, 18 Feb 2023 19:58:59 +0200 Subject: [PATCH 185/326] make dpfa lines mark safer --- rtengine/pdaflinesfilter.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rtengine/pdaflinesfilter.cc b/rtengine/pdaflinesfilter.cc index b5c72f7f4..60f2abcb6 100644 --- a/rtengine/pdaflinesfilter.cc +++ b/rtengine/pdaflinesfilter.cc @@ -275,7 +275,11 @@ int PDAFLinesFilter::mark(const array2D &rawData, PixelsMap &bpMap) for (int y = 1; y < H_-1; ++y) { int yy = pattern_[idx] + off; if (y == yy) { - int n = markLine(rawData, bpMap, y) + markLine(rawData, bpMap, y-1) + markLine(rawData, bpMap, y+1); + int n = 0; + n += markLine(rawData, bpMap, y); + n += (y-1 <= 0 ) ? 0 : markLine(rawData, bpMap, y-1); + n += (y+1 >= H_-1) ? 0 : markLine(rawData, bpMap, y+1); + if (n) { found += n; if (settings->verbose) { From 1bacb8b5b0b43e01b8c9e950915c5ba3fe379f83 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 18 Feb 2023 12:10:41 -0800 Subject: [PATCH 186/326] Add Exiv2 to GitHub Actions workflows --- .github/workflows/appimage.yml | 19 ++++++++++++++++++- .github/workflows/codeql.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cc0d16b8f..ec724c379 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -28,7 +28,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 + 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 + + - name: Install Exiv2 + run: | + EXIV2_VERSION='v0.27.6' + echo "Cloning Exiv2 $EXIV2_VERSION." + git clone --depth 1 --branch "$EXIV2_VERSION" https://github.com/Exiv2/exiv2.git ext/exiv2 + + echo "Configuring build." + mkdir ext/exiv2/build + cd ext/exiv2/build + cmake -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_BMFF=ON .. + + echo "Building and installing." + sudo make -j$(nproc) install - name: Configure build run: | @@ -111,6 +125,9 @@ jobs: - name: Package AppImage working-directory: ./build run: | + echo "LD_LIBRARY_PATH is '$LD_LIBRARY_PATH'. Adding /usr/local/lib." + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib" + echo "Creating artifact name." if [ '${{github.ref_type}}' == 'tag' ]; then ARTIFACT_NAME="RawTherapee_${REF_NAME_FILTERED}_${{matrix.build_type}}" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b90d30e27..d3b3244b4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.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 + 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 - name: Configure build run: | diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 11ae28aa4..7b0df3ac3 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -21,7 +21,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 | 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 | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ab81edec6..3b9791865 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -45,6 +45,7 @@ jobs: mingw-w64-x86_64-fftw mingw-w64-x86_64-lensfun mingw-w64-x86_64-libiptcdata + mingw-w64-x86_64-exiv2 - name: Configure build run: | From 006a7d9975daea025eb809b1ed5b33aceebc083d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 18 Feb 2023 18:16:12 -0800 Subject: [PATCH 187/326] Fix CodeQL alert --- rtengine/dcp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 29d3625a2..76dfeff5c 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -773,7 +773,7 @@ private: const std::size_t saved_position = std::ftell(file_) + 4; // Load value field (possibly seek before) - const std::size_t value_size = tag.count * getTypeSize(tag.type); + const std::size_t value_size = static_cast(tag.count) * getTypeSize(tag.type); if (value_size > 4) { if (std::fseek(file_, get4(), SEEK_SET) == -1) { From 23408bfcb3117404af376d24bad07e011e8f0fb2 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Thu, 23 Feb 2023 09:18:48 +0100 Subject: [PATCH 188/326] Local adjustments denoise - Removes the need to have luminance denoise curve activates to activate Nlmeans --- rtengine/iplocallab.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 811e941e4..243f3595d 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -8165,7 +8165,7 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform deltasobelL = new LabImage(spotSi, spotSi); bool isdenoise = false; - if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) { + if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.nlstr > 0 || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) { isdenoise = true; } @@ -10891,7 +10891,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl // const int hspot = ye - ys; // const int wspot = xe - xs; - 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 + 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"); @@ -13025,7 +13025,6 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int if(scale > 5.f) {//avoid to small values - leads to crash - but enough to evaluate noise return; } - BENCHFUN const int W = bfw; const int H = bfh; @@ -13666,7 +13665,7 @@ void ImProcFunctions::Lab_Local( //Prepare mask for Blur and noise and Denoise bool denoiz = false; - if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.wavcurvedenoi || lp.noisecf > 0.f || lp.noisecc > 0.f || lp.bilat > 0.f) && lp.denoiena) { + if ((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.noiselc > 0.f || lp.wavcurvedenoi || lp.nlstr > 0 || lp.noisecf > 0.f || lp.noisecc > 0.f || lp.bilat > 0.f) && lp.denoiena) { denoiz = true; } @@ -14410,7 +14409,7 @@ void ImProcFunctions::Lab_Local( } //local denoise - if (lp.activspot && lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used + if (lp.activspot && lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi ||lp.nlstr > 0 || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used float slidL[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; float slida[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; float slidb[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; From 03fd015e7716781fc97abeb82def05dd975a325f Mon Sep 17 00:00:00 2001 From: Shiho Midorikawa Date: Mon, 27 Feb 2023 03:26:10 +0900 Subject: [PATCH 189/326] Compute return buffer size at ExifManager::createJPEGMarker and make the buffer in that --- rtengine/imageio.cc | 6 +++--- rtexif/rtexif.cc | 24 +++++++++++++----------- rtexif/rtexif.h | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index ce44d1ff4..fb7c9aee7 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1027,7 +1027,7 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED) png_set_option(png, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); #endif - + png_infop info = png_create_info_struct(png); if (!info) { @@ -1227,12 +1227,12 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con jpeg_start_compress(&cinfo, TRUE); // buffer for exif and iptc markers - unsigned char* buffer = new unsigned char[165535]; //FIXME: no buffer size check so it can be overflowed in createJPEGMarker() for large tags, and then software will crash + unsigned char* buffer; unsigned int size; // assemble and write exif marker if (exifRoot) { - int size = rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer); + rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer, size); if (size > 0 && size < 65530) { jpeg_write_marker(&cinfo, JPEG_APP0 + 1, buffer, size); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index a7125fb9a..a48db5229 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3243,24 +3243,17 @@ std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) -int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer) +int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize) { // write tiff header - int offs = 6; - memcpy (buffer, "Exif\0\0", 6); + int offs = 6; // "Exif\0\0" ByteOrder order = INTEL; if (root) { order = root->getOrder (); } - sset2 ((unsigned short)order, buffer + offs, order); - offs += 2; - sset2 (42, buffer + offs, order); - offs += 2; - sset4 (8, buffer + offs, order); - TagDirectory* cl; if (root) { @@ -3322,11 +3315,20 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro } cl->sort (); - int size = cl->write (8, buffer + 6); + bufferSize = cl->calculateSize() + 8 + 6; + buffer = new unsigned char[bufferSize]; // this has to be deleted in caller + memcpy (buffer, "Exif\0\0", 6); + sset2 ((unsigned short)order, buffer + offs, order); + offs += 2; + sset2 (42, buffer + offs, order); + offs += 2; + sset4 (8, buffer + offs, order); + + int endOffs = cl->write (8, buffer + 6); delete cl; - return size + 6; + return endOffs; } int ExifManager::createPNGMarker(const TagDirectory* root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize) diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 7b2f8ad23..beb21131a 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -379,7 +379,7 @@ public: /// @param forthis The byte order will be taken from the given directory. /// @return The ownership of the return tags is passed to the caller. static std::vector getDefaultTIFFTags (TagDirectory* forthis); - static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer); + static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize); static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); static int createPNGMarker(const TagDirectory *root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char *iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); }; From 62c1f34c4f68beeb1338609ba6065bb459baab0e Mon Sep 17 00:00:00 2001 From: Shiho Midorikawa Date: Mon, 27 Feb 2023 03:43:25 +0900 Subject: [PATCH 190/326] Separate IPTC/EXIF buffers --- rtengine/imageio.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index fb7c9aee7..16f6a7246 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1226,19 +1226,27 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con jpeg_start_compress(&cinfo, TRUE); - // buffer for exif and iptc markers - unsigned char* buffer; - unsigned int size; + // buffer for exif marker + unsigned char* exifBuffer = nullptr; + unsigned int exifBufferSize = 0; // assemble and write exif marker if (exifRoot) { - rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer, size); + rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, exifBuffer, exifBufferSize); - if (size > 0 && size < 65530) { - jpeg_write_marker(&cinfo, JPEG_APP0 + 1, buffer, size); + if (exifBufferSize > 0 && exifBufferSize < 65530) { + jpeg_write_marker(&cinfo, JPEG_APP0 + 1, exifBuffer, exifBufferSize); } + } + if (exifBuffer != nullptr) { + delete [] exifBuffer; + } + + // buffer for iptc marker + unsigned char* iptcBuffer = new unsigned char[65535]; + // assemble and write iptc marker if (iptc) { unsigned char* iptcdata; @@ -1254,7 +1262,7 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con int bytes = 0; - if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, size, buffer, 65532)) < 0) { + if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, size, iptcBuffer, 65532)) < 0) { error = true; } @@ -1263,11 +1271,11 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con } if (!error) { - jpeg_write_marker(&cinfo, JPEG_APP0 + 13, buffer, bytes); + jpeg_write_marker(&cinfo, JPEG_APP0 + 13, iptcBuffer, bytes); } } - delete [] buffer; + delete [] iptcBuffer; // write icc profile to the output if (profileData) { From f759cff2fe4f6011c38039c6b5c077bbea69b79d Mon Sep 17 00:00:00 2001 From: Shiho Midorikawa Date: Mon, 27 Feb 2023 14:27:47 +0900 Subject: [PATCH 191/326] Fix separation mistake --- rtengine/imageio.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 16f6a7246..23b0fafec 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1250,9 +1250,10 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con // assemble and write iptc marker if (iptc) { unsigned char* iptcdata; + unsigned int iptcSize; bool error = false; - if (iptc_data_save (iptc, &iptcdata, &size)) { + if (iptc_data_save (iptc, &iptcdata, &iptcSize)) { if (iptcdata) { iptc_data_free_buf (iptc, iptcdata); } @@ -1262,7 +1263,7 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con int bytes = 0; - if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, size, iptcBuffer, 65532)) < 0) { + if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, iptcSize, iptcBuffer, 65532)) < 0) { error = true; } From fe69ebff6abbb7d5756f909b3d6abf246215cd4c Mon Sep 17 00:00:00 2001 From: Benitoite Date: Sun, 26 Feb 2023 23:13:24 -0800 Subject: [PATCH 192/326] macOS CI pass architecture to cmake for arch variable set by https://github.com/Beep6581/RawTherapee/blob/dev/tools/osx/macosx_bundle.sh#L102 --- .github/workflows/macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 11ae28aa4..576440714 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -48,6 +48,7 @@ jobs: -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_MAJOR}.${RAW_THERAPEE_MINOR}-${REF}" \ -DPROC_TARGET_NUMBER="1" \ -DPROC_LABEL="generic processor" \ + -DCMAKE_OSX_ARCHITECTURES=$(uname -m) \ -DWITH_LTO="OFF" \ -DLENSFUNDBDIR="/Applications/RawTherapee.app/Contents/Resources/share/lensfun" \ -DCMAKE_C_COMPILER=clang \ From 0838d77fb94d4297e911ac975b6348115d93067d Mon Sep 17 00:00:00 2001 From: Benitoite Date: Sun, 26 Feb 2023 23:26:50 -0800 Subject: [PATCH 193/326] macOS CI: libomp ruby file is a formula Uses the --formula flag to tell brew the ruby file is a formula so it doesn't issue a red non-fatal error message. --- .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 576440714..e466787db 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -64,7 +64,7 @@ jobs: -DCMAKE_RANLIB=/usr/bin/ranlib \ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \ .. - curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install libomp.rb + 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 69397aea097e8cd5f9c65add70925483d12be1ee Mon Sep 17 00:00:00 2001 From: Benitoite Date: Sun, 26 Feb 2023 23:32:20 -0800 Subject: [PATCH 194/326] macOS CI: update two actions to @v3 updates actions for node12->16 requirements. --- .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 e466787db..4a258354a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -14,7 +14,7 @@ jobs: build: runs-on: macos-11 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | date -u @@ -92,7 +92,7 @@ jobs: "ARTIFACT_FILE: ${ARTIFACT_FILE}" \ "PUBLISH_NAME: ${PUBLISH_NAME}" exit - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: ${{env.ARTIFACT_FILE}} path: ${{env.ARTIFACT_PATH}} From c55bc5103fc50bc2499ebc2a7933bbd8eb4b1495 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 12:49:26 -0800 Subject: [PATCH 195/326] macOS: mute tput warnings tput warns you when running with no attached terminal; eg. GitHub CI. Redirects warnings to /dev/null --- tools/osx/macosx_bundle.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 26b8b4d08..9de3a7a5f 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -9,11 +9,11 @@ # - GTK_PREFIX # Formatting -fNormal="$(tput sgr0)" -fBold="$(tput bold)" +fNormal="$(tput sgr0)" >/dev/null 2>&1 +fBold="$(tput bold)" >/dev/null 2>&1 # Colors depend upon the user's terminal emulator color scheme - what is readable for you may be not readable for someone else. -fMagenta="$(tput setaf 5)" -fRed="$(tput setaf 1)" +fMagenta="$(tput setaf 5)" >/dev/null 2>&1 +fRed="$(tput setaf 1)" >/dev/null 2>&1 function msg { printf "\\n${fBold}-- %s${fNormal}\\n" "${@}" From 4d794d6bbb0c4cd258187a14971021c78f75a596 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 17:50:10 -0800 Subject: [PATCH 196/326] macOS: set the 'latest' artifact Uses a generically-named nightly instead of name-tagged with commit hash. --- .github/workflows/macos.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4a258354a..7d3e0cbfd 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -62,7 +62,8 @@ jobs: -DOpenMP_libomp_LIBRARY=/usr/local/lib/libomp.dylib \ -DCMAKE_AR=/usr/bin/ar \ -DCMAKE_RANLIB=/usr/bin/ranlib \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ + -DOSX_NIGHTLY=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"' @@ -78,7 +79,7 @@ jobs: zsh date +%s > build/bundlestamp && date -u && cd build export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle - export ARTIFACT=(RawTherapee*.zip) + export ARTIFACT=(RawTherapee*latest.zip) echo "=== artifact: ${ARTIFACT}" # defining environment variables for next step as per # https://github.com/actions/starter-workflows/issues/68 From d89ed3b5957140f797cb2700b9bc6810aa4dd2e2 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 19:46:25 -0800 Subject: [PATCH 197/326] mac: remove obsolete patch --- tools/osx/libiconv_1.16_rt.patch | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 tools/osx/libiconv_1.16_rt.patch diff --git a/tools/osx/libiconv_1.16_rt.patch b/tools/osx/libiconv_1.16_rt.patch deleted file mode 100644 index 470f7780c..000000000 --- a/tools/osx/libiconv_1.16_rt.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/lib/iconv.c b/lib/iconv.c -index b7a04f8..41c5896 100644 ---- a/lib/iconv.c -+++ b/lib/iconv.c -@@ -610,5 +610,26 @@ strong_alias (libiconv_open, iconv_open) - strong_alias (libiconv, iconv) - strong_alias (libiconv_close, iconv_close) - #endif -+ -+#undef iconv_open -+#undef iconv -+#undef iconv_close -+ -+LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode) -+{ -+ return libiconv_open(tocode, fromcode); -+} -+ -+LIBICONV_DLL_EXPORTED size_t iconv (iconv_t icd, -+ ICONV_CONST char * * inbuf, size_t *inbytesleft, -+ char * * outbuf, size_t *outbytesleft) -+{ -+ return libiconv(icd, inbuf, inbytesleft, outbuf, outbytesleft); -+} -+ -+LIBICONV_DLL_EXPORTED int iconv_close (iconv_t icd) -+{ -+ return libiconv_close(icd); -+} - - #endif From 0d6733973865983d5c4c30333291dd820324e683 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 20:59:45 -0800 Subject: [PATCH 198/326] macOS: altool --notarize -> notarytool Updates notary script to use `xcrun notarytool` per Apple deprecation notices. --- tools/osx/macosx_bundle.sh | 45 ++------------------------------------ 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 9de3a7a5f..87b318bf0 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -370,27 +370,7 @@ if [[ -n $NOTARY ]]; then msg "Notarizing the application:" ditto -c -k --sequesterRsrc --keepParent "${APP}" "${APP}.zip" echo "Uploading..." - uuid=`xcrun altool --notarize-app --primary-bundle-id "com.rawtherapee.RawTherapee" ${NOTARY} --file "${APP}.zip" 2>&1 | grep 'RequestUUID' | awk '{ print $3 }'` - echo "Result= $uuid" # Display identifier string - sleep 15 - while : - do - fullstatus=`xcrun altool --notarization-info "$uuid" ${NOTARY} 2>&1` # get the status - status1=`echo "$fullstatus" | grep 'Status\:' | awk '{ print $2 }'` - if [[ $status1 = "success" ]]; then - xcrun stapler staple *app # staple the ticket - xcrun stapler validate -v *app - echo "Notarization success" - break - elif [[ $status1 = "in" ]]; then - echo "Notarization still in progress, sleeping for 15 seconds and trying again" - sleep 15 - else - echo "Notarization failed fullstatus below" - echo "$fullstatus" - exit 1 - fi - done + sudo xcrun notarytool submit "${APP}.zip" ${NOTARY} --wait fi function CreateDmg { @@ -452,28 +432,7 @@ function CreateDmg { msg "Notarizing the dmg:" zip "${dmg_name}.dmg.zip" "${dmg_name}.dmg" echo "Uploading..." - uuid=$(xcrun altool --notarize-app --primary-bundle-id "com.rawtherapee" ${NOTARY} --file "${dmg_name}.dmg.zip" 2>&1 | grep 'RequestUUID' | awk '{ print $3 }') - echo "dmg Result= ${uuid}" # Display identifier string - sleep 15 - while : - do - fullstatus=`xcrun altool --notarization-info "$uuid" ${NOTARY} 2>&1` # get the status - status1=`echo "$fullstatus" | grep 'Status\:' | awk '{ print $2 }'` - if [[ $status1 = "success" ]]; then - xcrun stapler staple "${dmg_name}.dmg" # staple the ticket - xcrun stapler validate -v "${dmg_name}.dmg" - echo "dmg Notarization success" - rm *dmg.zip - break - elif [[ $status1 = "in" ]]; then - echo "dmg Notarization still in progress, sleeping for 15 seconds and trying again" - sleep 15 - else - echo "dmg Notarization failed fullstatus below" - echo "$fullstatus" - exit 1 - fi - done + sudo xcrun notarytool submit "${dmg_name}.dmg.zip" ${NOTARY} --wait fi # Zip disk image for redistribution From 74d6762f790e2a5d46d7788e05d4f267ffced820 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 21:04:46 -0800 Subject: [PATCH 199/326] macOS: show new notarytool format of notary string --- tools/osx/macosx_bundle.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 87b318bf0..1bfe6986d 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -135,8 +135,8 @@ EXPATLIB="$(cmake .. -LA -N | grep pkgcfg_lib_EXPAT_expat)"; pkgcfg_lib_EXPAT_ex #Out: Developer ID Application: Doctor Who (1234567890) CODESIGNID="$(cmake .. -L -N | grep CODESIGNID)"; CODESIGNID="${CODESIGNID#*=}" -#In: NOTARY:STRING=--username drwho@bbc.com --password abcd-efgh-hijk-lmno -#Out: --username drwho@bbc.com --password abcd-efgh-hijk-lmno +#In: NOTARY:STRING="--apple-id drwho@bbc.com --password abcd-efgh-hijk-lmno --team-id ABCDE12345" +#Out: --apple-id drwho@bbc.com --password abcd-efgh-hijk-lmno --team-id ABCDE12345 NOTARY="$(cmake .. -L -N | grep NOTARY)"; NOTARY="${NOTARY#*=}" # In: FANCY_DMG:BOOL=ON From 3fe30277bf2022f785453d0a5593d5adfee131d6 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Mon, 27 Feb 2023 21:14:10 -0800 Subject: [PATCH 200/326] macOS: fixes a few packaging warnings and tries not forcing a non-system z or expat into Frameworks. --- tools/osx/macosx_bundle.sh | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 1bfe6986d..a43a1814c 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -201,7 +201,7 @@ else fi # Copy libomp to Frameworks -ditto ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" +cp ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" msg "Copying dependencies from ${GTK_PREFIX}." CheckLink "${EXECUTABLE}" 2>&1 @@ -209,24 +209,20 @@ CheckLink "${EXECUTABLE}" 2>&1 # dylib install names ModifyInstallNames 2>&1 -# Copy libjpeg-turbo ("62") into the app bundle -ditto ${LOCAL_PREFIX}/lib/libjpeg.62.dylib "${CONTENTS}/Frameworks/libjpeg.62.dylib" +## Copy libexpat into the app bundle (which is keg-only) +## if [[ -d /usr/local/Cellar/expat ]]; then ditto /usr/local/Cellar/expat/*/lib/libexpat.1.dylib "${CONTENTS}/Frameworks"; else cp "${EXPATLIB}" "${CONTENTS}/Frameworks/libexpat.1.dylib"; fi -# Copy libexpat into the app bundle (which is keg-only) -if [[ -d /usr/local/Cellar/expat ]]; then ditto /usr/local/Cellar/expat/*/lib/libexpat.1.dylib "${CONTENTS}/Frameworks"; else ditto "${EXPATLIB}" "${CONTENTS}/Frameworks/libexpat.1.dylib"; fi +## Copy libz into the app bundle +## cp ${LOCAL_PREFIX}/lib/libz.1.dylib "${CONTENTS}/Frameworks" -# Copy libz into the app bundle -ditto ${LOCAL_PREFIX}/lib/libz.1.dylib "${CONTENTS}/Frameworks" - -# Copy libpng12 & 16 to the app bundle -ditto ${LOCAL_PREFIX}/lib/libpng16.16.dylib "${CONTENTS}/Frameworks/libpng16.16.dylib" -ditto ${LOCAL_PREFIX}/lib/libpng12.0.dylib "${CONTENTS}/Frameworks/libpng12.0.dylib" +# Copy libpng16 to the app bundle +cp ${LOCAL_PREFIX}/lib/libpng16.16.dylib "${CONTENTS}/Frameworks/libpng16.16.dylib" # Copy libtiff 5 into the app bundle -ditto ${LOCAL_PREFIX}/lib/libtiff.5.dylib "${CONTENTS}/Frameworks/libtiff.5.dylib" +cp ${LOCAL_PREFIX}/lib/libtiff.5.dylib "${CONTENTS}/Frameworks/libtiff.5.dylib" # Copy libomp to Frameworks -ditto ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" +cp ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" # Prepare GTK+3 installation msg "Copying configuration files from ${GTK_PREFIX}:" @@ -240,7 +236,7 @@ find -E "${LIB}" -type f -regex '.*\.(a|la|cache)$' | while read -r; do rm "${RE # Make Frameworks folder flat msg "Flattening the Frameworks folder" cp -RL "${LIB}"/gdk-pixbuf-2.0/2*/loaders/* "${LIB}" -cp "${LIB}"/gtk-3.0/3*/immodules/*.{dylib,so} "${LIB}" +cp "${LIB}"/gtk-3.0/3*/immodules/*.{dylib,so} "${LIB}" >/dev/null 2>&1 rm -r "${LIB}"/gtk-3.0 rm -r "${LIB}"/gdk-pixbuf-2.0 From a07c38f4054957c7f43b70708ae6feaa6d2020aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Wed, 1 Mar 2023 12:47:55 +0100 Subject: [PATCH 201/326] Support for saving TIFFs as BigTIFF (#6690) --- rtdata/languages/default | 1 + rtengine/iimage.h | 8 +++++- rtengine/image16.h | 2 +- rtengine/image8.h | 10 +++++-- rtengine/imagefloat.h | 10 +++++-- rtengine/imageio.cc | 61 +++++++++++++++++++++++++++------------- rtengine/imageio.h | 8 +++++- rtgui/batchqueue.cc | 11 +++++++- rtgui/batchqueueentry.cc | 3 ++ rtgui/editorpanel.cc | 6 ++-- rtgui/options.cc | 6 ++++ rtgui/options.h | 4 +++ rtgui/saveformatpanel.cc | 12 ++++++++ rtgui/saveformatpanel.h | 1 + 14 files changed, 113 insertions(+), 30 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 84b28c955..bda477f14 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2061,6 +2061,7 @@ SAMPLEFORMAT_16;16-bit floating-point SAMPLEFORMAT_32;24-bit floating-point SAMPLEFORMAT_64;32-bit floating-point SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +SAVEDLG_BIGTIFF;BigTIFF SAVEDLG_FILEFORMAT;File format SAVEDLG_FILEFORMAT_FLOAT; floating-point SAVEDLG_FORCEFORMATOPTS;Force saving options diff --git a/rtengine/iimage.h b/rtengine/iimage.h index a544b454a..cdb7dd6eb 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -1882,7 +1882,13 @@ public: * @param bps can be 8 or 16 depending on the bits per pixels the output file will have * @param isFloat is true for saving float images. Will be ignored by file format not supporting float data @return the error code, 0 if none */ - virtual int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const = 0; + virtual int saveAsTIFF ( + const Glib::ustring &fname, + int bps = -1, + bool isFloat = false, + bool uncompressed = false, + bool big = false + ) const = 0; /** @brief Sets the progress listener if you want to follow the progress of the image saving operations (optional). * @param pl is the pointer to the class implementing the ProgressListener interface */ virtual void setSaveProgressListener (ProgressListener* pl) = 0; diff --git a/rtengine/image16.h b/rtengine/image16.h index 25b777832..273ae63a1 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -81,7 +81,7 @@ public: return saveJPEG(fname, quality, subSamp); } - int saveAsTIFF(const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override + int saveAsTIFF(const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false, bool big = false) const override { return saveTIFF(fname, bps, isFloat, uncompressed); } diff --git a/rtengine/image8.h b/rtengine/image8.h index 76a580bb6..416dc9143 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -79,9 +79,15 @@ public: return saveJPEG (fname, quality, subSamp); } - int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override + int saveAsTIFF ( + const Glib::ustring &fname, + int bps = -1, + bool isFloat = false, + bool uncompressed = false, + bool big = false + ) const override { - return saveTIFF (fname, bps, isFloat, uncompressed); + return saveTIFF (fname, bps, isFloat, uncompressed, big); } void setSaveProgressListener (ProgressListener* pl) override diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index fc3ba318d..d69df9325 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -82,9 +82,15 @@ public: { return saveJPEG (fname, quality, subSamp); } - int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override + int saveAsTIFF ( + const Glib::ustring &fname, + int bps = -1, + bool isFloat = false, + bool uncompressed = false, + bool big = false + ) const override { - return saveTIFF (fname, bps, isFloat, uncompressed); + return saveTIFF (fname, bps, isFloat, uncompressed, big); } void setSaveProgressListener (ProgressListener* pl) override { diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index ce44d1ff4..573a391aa 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -17,21 +17,17 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include -#include -#include -#include #include #include -#include -#include #include -#include "rt_math.h" -#include "procparams.h" -#include "utils.h" -#include "../rtgui/options.h" -#include "../rtgui/version.h" -#include "../rtexif/rtexif.h" +#include + +#include +#include +#include +#include +#include +#include #ifdef WIN32 #include @@ -39,12 +35,20 @@ #include #endif +#include "color.h" +#include "iccjpeg.h" #include "imageio.h" #include "iptcpairs.h" -#include "iccjpeg.h" -#include "color.h" - #include "jpeg.h" +#include "procparams.h" +#include "rt_math.h" +#include "utils.h" + +#include "../rtgui/options.h" +#include "../rtgui/version.h" + +#include "../rtexif/rtexif.h" + using namespace std; using namespace rtengine; @@ -1328,7 +1332,13 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con return IMIO_SUCCESS; } -int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool uncompressed) const +int ImageIO::saveTIFF ( + const Glib::ustring &fname, + int bps, + bool isFloat, + bool uncompressed, + bool big +) const { if (getWidth() < 1 || getHeight() < 1) { return IMIO_HEADERERROR; @@ -1345,15 +1355,28 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u int lineWidth = width * 3 * bps / 8; unsigned char* linebuffer = new unsigned char[lineWidth]; + std::string mode = "w"; + // little hack to get libTiff to use proper byte order (see TIFFClienOpen()): - const char *mode = !exifRoot ? "w" : (exifRoot->getOrder() == rtexif::INTEL ? "wl" : "wb"); + if (exifRoot) { + if (exifRoot->getOrder() == rtexif::INTEL) { + mode += 'l'; + } else { + mode += 'b'; + } + } + + if (big) { + mode += '8'; + } + #ifdef WIN32 FILE *file = g_fopen_withBinaryAndLock (fname); int fileno = _fileno(file); int osfileno = _get_osfhandle(fileno); - TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode); + TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode.c_str()); #else - TIFF* out = TIFFOpen(fname.c_str(), mode); + TIFF* out = TIFFOpen(fname.c_str(), mode.c_str()); int fileno = TIFFFileno (out); #endif diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 566fef13b..e900feccd 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -113,7 +113,13 @@ public: int savePNG (const Glib::ustring &fname, int bps = -1) const; int saveJPEG (const Glib::ustring &fname, int quality = 100, int subSamp = 3) const; - int saveTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const; + int saveTIFF ( + const Glib::ustring &fname, + int bps = -1, + bool isFloat = false, + bool uncompressed = false, + bool big = false + ) const; cmsHPROFILE getEmbeddedProfile () const; void getEmbeddedProfileData (int& length, unsigned char*& pdata) const; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 19da96fb5..4e25475f0 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -264,6 +264,7 @@ bool BatchQueue::saveBatchQueue () << saveFormat.tiffBits << '|' << (saveFormat.tiffFloat ? 1 : 0) << '|' << saveFormat.tiffUncompressed << '|' << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' << entry->fast_pipeline << '|' + << saveFormat.bigTiff << '|' << std::endl; } } @@ -331,6 +332,7 @@ bool BatchQueue::loadBatchQueue () const auto saveParams = nextIntOr (options.saveFormat.saveParams); const auto forceFormatOpts = nextIntOr (options.forceFormatOpts); const auto fast = nextIntOr(false); + const auto bigTiff = nextIntOr (options.saveFormat.bigTiff); rtengine::procparams::ProcParams pparams; @@ -370,6 +372,7 @@ bool BatchQueue::loadBatchQueue () saveFormat.tiffBits = tiffBits; saveFormat.tiffFloat = tiffFloat == 1; saveFormat.tiffUncompressed = tiffUncompressed != 0; + saveFormat.bigTiff = bigTiff != 0; saveFormat.saveParams = saveParams != 0; entry->forceFormatOpts = forceFormatOpts != 0; } else { @@ -693,7 +696,13 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) int err = 0; if (saveFormat.format == "tif") { - err = img->saveAsTIFF (fname, saveFormat.tiffBits, saveFormat.tiffFloat, saveFormat.tiffUncompressed); + err = img->saveAsTIFF ( + fname, + saveFormat.tiffBits, + saveFormat.tiffFloat, + saveFormat.tiffUncompressed, + saveFormat.bigTiff + ); } else if (saveFormat.format == "png") { err = img->saveAsPNG (fname, saveFormat.pngBits); } else if (saveFormat.format == "jpg") { diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 9fe4dd605..7499fb63b 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -201,6 +201,9 @@ std::tuple BatchQueueEntry::getToolTip (int x, int y) const if (saveFormat.tiffUncompressed) { tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_TIFFUNCOMPRESSED")); } + if (saveFormat.bigTiff) { + tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_BIGTIFF")); + } } } } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 95808d4b0..ffe13fea3 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2013,7 +2013,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc, img->setSaveProgressListener (parent->getProgressListener()); if (sf.format == "tif") - ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fname, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed), + ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fname, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff), sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf, pparams)); else if (sf.format == "png") ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsPNG), fname, sf.pngBits), @@ -2270,7 +2270,7 @@ bool EditorPanel::saveImmediately (const Glib::ustring &filename, const SaveForm if (gimpPlugin) { err = img->saveAsTIFF (filename, 32, true, true); } else if (sf.format == "tif") { - err = img->saveAsTIFF (filename, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed); + err = img->saveAsTIFF (filename, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff); } else if (sf.format == "png") { err = img->saveAsPNG (filename, sf.pngBits); } else if (sf.format == "jpg") { @@ -2380,7 +2380,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p ProgressConnector *ld = new ProgressConnector(); img->setSaveProgressListener (parent->getProgressListener()); - ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fileName, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed), + ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fileName, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff), sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_sentToGimp), ld, img, fileName)); } else { Glib::ustring msg_ = Glib::ustring (" Error during image processing\n"); diff --git a/rtgui/options.cc b/rtgui/options.cc index 66b9e92a1..e230dcf8a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -313,6 +313,7 @@ void Options::setDefaults() saveFormat.tiffBits = 16; saveFormat.tiffFloat = false; saveFormat.tiffUncompressed = true; + saveFormat.bigTiff = false; saveFormat.saveParams = true; saveFormatBatch.format = "jpg"; @@ -1046,6 +1047,10 @@ void Options::readFromFile(Glib::ustring fname) saveFormat.tiffUncompressed = keyFile.get_boolean("Output", "TiffUncompressed"); } + if (keyFile.has_key("Output", "BigTiff")) { + saveFormat.bigTiff = keyFile.get_boolean("Output", "BigTiff"); + } + if (keyFile.has_key("Output", "SaveProcParams")) { saveFormat.saveParams = keyFile.get_boolean("Output", "SaveProcParams"); } @@ -2447,6 +2452,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("Output", "TiffBps", saveFormat.tiffBits); keyFile.set_boolean("Output", "TiffFloat", saveFormat.tiffFloat); keyFile.set_boolean("Output", "TiffUncompressed", saveFormat.tiffUncompressed); + keyFile.set_boolean("Output", "BigTiff", saveFormat.bigTiff); keyFile.set_boolean("Output", "SaveProcParams", saveFormat.saveParams); keyFile.set_string("Output", "FormatBatch", saveFormatBatch.format); diff --git a/rtgui/options.h b/rtgui/options.h index 286c64df0..5fb4e4f8b 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -72,6 +72,7 @@ struct SaveFormat { int _tiff_bits, bool _tiff_float, bool _tiff_uncompressed, + bool _big_tiff, bool _save_params ) : format(_format), @@ -81,6 +82,7 @@ struct SaveFormat { tiffBits(_tiff_bits), tiffFloat(_tiff_float), tiffUncompressed(_tiff_uncompressed), + bigTiff(_big_tiff), saveParams(_save_params) { } @@ -98,6 +100,7 @@ struct SaveFormat { _tiff_bits, _tiff_float, true, + false, true ) { @@ -114,6 +117,7 @@ struct SaveFormat { int tiffBits; bool tiffFloat; bool tiffUncompressed; + bool bigTiff; bool saveParams; }; diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index 00f6e7b2b..773ee9105 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -100,6 +100,11 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) tiffUncompressed->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged)); tiffUncompressed->show_all(); + bigTiff = new Gtk::CheckButton (M("SAVEDLG_BIGTIFF")); + setExpandAlignProperties(bigTiff, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + bigTiff->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged)); + bigTiff->show_all(); + // --------------------- MAIN BOX @@ -114,12 +119,14 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) attach (*hb1, 0, 0, 1, 1); attach (*jpegOpts, 0, 1, 1, 1); attach (*tiffUncompressed, 0, 2, 1, 1); + attach (*bigTiff, 0, 3, 1, 1); attach (*savesPP, 0, 4, 1, 2); } SaveFormatPanel::~SaveFormatPanel () { delete jpegQual; delete tiffUncompressed; + delete bigTiff; } void SaveFormatPanel::init (SaveFormat &sf) @@ -158,6 +165,7 @@ void SaveFormatPanel::init (SaveFormat &sf) jpegQual->setValue(sf.jpegQuality); savesPP->set_active(sf.saveParams); tiffUncompressed->set_active(sf.tiffUncompressed); + bigTiff->set_active(sf.bigTiff); listener = tmp; } @@ -175,6 +183,7 @@ SaveFormat SaveFormatPanel::getFormat () sf.jpegQuality = jpegQual->getValue(); sf.jpegSubSamp = jpegSubSamp->get_active_row_number() + 1; sf.tiffUncompressed = tiffUncompressed->get_active(); + sf.bigTiff = bigTiff->get_active(); sf.saveParams = savesPP->get_active(); return sf; @@ -193,12 +202,15 @@ void SaveFormatPanel::formatChanged () if (fr == "jpg") { jpegOpts->show_all(); tiffUncompressed->hide(); + bigTiff->hide(); } else if (fr == "png") { jpegOpts->hide(); tiffUncompressed->hide(); + bigTiff->hide(); } else if (fr == "tif") { jpegOpts->hide(); tiffUncompressed->show_all(); + bigTiff->show_all(); } if (listener) { diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index af9baa58a..9d9f6266e 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -39,6 +39,7 @@ class SaveFormatPanel : public Gtk::Grid, public AdjusterListener, public rtengi protected: Adjuster* jpegQual; Gtk::CheckButton* tiffUncompressed; + Gtk::CheckButton* bigTiff; MyComboBoxText* format; MyComboBoxText* jpegSubSamp; Gtk::Grid* formatOpts; From 8f6d4f31c53cbb51e7aff0dce0763bdb34384b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 2 Mar 2023 09:17:01 +0100 Subject: [PATCH 202/326] Consistently use `Gtk::manage()` in `SaveFormatPanel` --- rtgui/saveformatpanel.cc | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index 773ee9105..d9b04e8fe 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -71,7 +71,7 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) jpegOpts->set_row_spacing(5); setExpandAlignProperties(jpegOpts, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - jpegQual = new Adjuster (M("SAVEDLG_JPEGQUAL"), 0, 100, 1, 100); + jpegQual = Gtk::manage (new Adjuster (M("SAVEDLG_JPEGQUAL"), 0, 100, 1, 100) ); setExpandAlignProperties(jpegQual, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); jpegQual->setAdjusterListener (this); @@ -95,12 +95,12 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) // --------------------- TIFF OPTIONS - tiffUncompressed = new Gtk::CheckButton (M("SAVEDLG_TIFFUNCOMPRESSED")); + tiffUncompressed = Gtk::manage (new Gtk::CheckButton (M("SAVEDLG_TIFFUNCOMPRESSED")) ); setExpandAlignProperties(tiffUncompressed, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); tiffUncompressed->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged)); tiffUncompressed->show_all(); - bigTiff = new Gtk::CheckButton (M("SAVEDLG_BIGTIFF")); + bigTiff = Gtk::manage (new Gtk::CheckButton (M("SAVEDLG_BIGTIFF")) ); setExpandAlignProperties(bigTiff, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); bigTiff->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged)); bigTiff->show_all(); @@ -122,12 +122,8 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) attach (*bigTiff, 0, 3, 1, 1); attach (*savesPP, 0, 4, 1, 2); } -SaveFormatPanel::~SaveFormatPanel () -{ - delete jpegQual; - delete tiffUncompressed; - delete bigTiff; -} + +SaveFormatPanel::~SaveFormatPanel () = default; void SaveFormatPanel::init (SaveFormat &sf) { From 8587fe068db6854b7ebd3c17ec26de49cf9bd1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 3 Mar 2023 08:57:08 +0100 Subject: [PATCH 203/326] Don't perform EXIF hack on BigTIFF --- rtdata/languages/default | 2 +- rtengine/imageio.cc | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index bda477f14..10d0a89c3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2061,7 +2061,7 @@ SAMPLEFORMAT_16;16-bit floating-point SAMPLEFORMAT_32;24-bit floating-point SAMPLEFORMAT_64;32-bit floating-point SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists -SAVEDLG_BIGTIFF;BigTIFF +SAVEDLG_BIGTIFF;BigTIFF (no metadata support) SAVEDLG_FILEFORMAT;File format SAVEDLG_FILEFORMAT_FLOAT; floating-point SAVEDLG_FORCEFORMATOPTS;Force saving options diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 573a391aa..7b3513051 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1392,7 +1392,7 @@ int ImageIO::saveTIFF ( bool applyExifPatch = false; - if (exifRoot) { + if (exifRoot && !big) { rtexif::TagDirectory* cl = (const_cast (exifRoot))->clone (nullptr); // ------------------ remove some unknown top level tags which produce warnings when opening a tiff (might be useless) ----------------- @@ -1475,10 +1475,11 @@ int ImageIO::saveTIFF ( } #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::MOTOROLA; + bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::MOTOROLA; #else - bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::INTEL; + bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::INTEL; #endif + if (iptcdata) { rtexif::Tag iptcTag(nullptr, rtexif::lookupAttrib (rtexif::ifdAttribs, "IPTCData")); iptcTag.initLongArray((char*)iptcdata, iptclen); From e2311cc3daf12891d0f5479b8099575466e7ed83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 3 Mar 2023 09:17:12 +0100 Subject: [PATCH 204/326] Some minor improvements to `ImageIO::saveTIFF()` --- rtengine/imageio.cc | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 7b3513051..ad230bb7d 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -1352,8 +1354,8 @@ int ImageIO::saveTIFF ( bps = getBPS (); } - int lineWidth = width * 3 * bps / 8; - unsigned char* linebuffer = new unsigned char[lineWidth]; + int lineWidth = width * 3 * (bps / 8); + std::vector linebuffer(lineWidth); std::string mode = "w"; @@ -1381,7 +1383,6 @@ int ImageIO::saveTIFF ( #endif if (!out) { - delete [] linebuffer; return IMIO_CANNOTWRITEFILE; } @@ -1485,15 +1486,9 @@ int ImageIO::saveTIFF ( iptcTag.initLongArray((char*)iptcdata, iptclen); if (needsReverse) { unsigned char *ptr = iptcTag.getValue(); - for (int a = 0; a < iptcTag.getCount(); ++a) { - unsigned char cc; - cc = ptr[3]; - ptr[3] = ptr[0]; - ptr[0] = cc; - cc = ptr[2]; - ptr[2] = ptr[1]; - ptr[1] = cc; - ptr += 4; + for (int a = 0; a < iptcTag.getCount(); ++a, ptr += 4) { + std::swap(ptr[0], ptr[3]); + std::swap(ptr[1], ptr[2]); } } TIFFSetField (out, TIFFTAG_RICHTIFFIPTC, iptcTag.getCount(), (long*)iptcTag.getValue()); @@ -1533,32 +1528,25 @@ int ImageIO::saveTIFF ( } for (int row = 0; row < height; row++) { - getScanline (row, linebuffer, bps, isFloat); + getScanline (row, linebuffer.data(), bps, isFloat); if (bps == 16) { if(needsReverse && !uncompressed && isFloat) { for(int i = 0; i < lineWidth; i += 2) { - char temp = linebuffer[i]; - linebuffer[i] = linebuffer[i + 1]; - linebuffer[i + 1] = temp; + std::swap(linebuffer[i], linebuffer[i + 1]); } } } else if (bps == 32) { if(needsReverse && !uncompressed) { for(int i = 0; i < lineWidth; i += 4) { - char temp = linebuffer[i]; - linebuffer[i] = linebuffer[i + 3]; - linebuffer[i + 3] = temp; - temp = linebuffer[i + 1]; - linebuffer[i + 1] = linebuffer[i + 2]; - linebuffer[i + 2] = temp; + std::swap(linebuffer[i], linebuffer[i + 3]); + std::swap(linebuffer[i + 1], linebuffer[i + 2]); } } } - if (TIFFWriteScanline (out, linebuffer, row, 0) < 0) { + if (TIFFWriteScanline (out, linebuffer.data(), row, 0) < 0) { TIFFClose (out); - delete [] linebuffer; return IMIO_CANNOTWRITEFILE; } @@ -1608,8 +1596,6 @@ int ImageIO::saveTIFF ( fclose (file); #endif - delete [] linebuffer; - if (pl) { pl->setProgressStr ("PROGRESSBAR_READY"); pl->setProgress (1.0); From f2b0301be281c621ae036268d9bf02da1b74ad8c Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Fri, 3 Mar 2023 14:30:34 +0100 Subject: [PATCH 205/326] Update README.md The RawTherapee logo shown in GitHub now depends on the user's GitHub color scheme - black text when light, white text when dark. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 21f219a83..64f4d08aa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -![RawTherapee logo](https://raw.githubusercontent.com/Beep6581/RawTherapee/dev/rtdata/images/rt-logo-text-black.svg) + + + + RawTherapee logo + ![RawTherapee screenshot](http://rawtherapee.com/images/carousel/100_rt59_provence_local_maskxxx.jpg) From 92f0a11dc7100fa53dfb1146156925dda8c3a318 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:11:58 -0800 Subject: [PATCH 206/326] Add missing fftw libraries for Windows build (#6702) Add missing fftw library for Windows build --- .github/workflows/windows.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ab81edec6..40c74f5e2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -94,6 +94,8 @@ jobs: - name: Bundle dependencies run: | + echo "Listing shared library dependencies." + ldd "./build/${{matrix.build_type}}/rawtherapee.exe" echo "Getting workspace path." export BUILD_DIR="$(pwd)/build/${{matrix.build_type}}" echo "Build directory is '$BUILD_DIR'." @@ -120,6 +122,7 @@ jobs: "libexpat-1.dll" \ libffi-*.dll \ "libfftw3f-3.dll" \ + "libfftw3f_omp-3.dll" \ "libfontconfig-1.dll" \ "libfreetype-6.dll" \ "libfribidi-0.dll" \ From 4cff5ef35b4e7801387b72521d256672802d370c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Wed, 8 Mar 2023 08:18:38 +0100 Subject: [PATCH 207/326] Fix `settings.ini` formatting (closes #6697) --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 40c74f5e2..49fdf5999 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -206,7 +206,7 @@ jobs: echo "Creating GTK settings.ini." mkdir -p "$BUILD_DIR/share/gtk-3.0/" - echo '[Settings] gtk-button-images=1' > "$BUILD_DIR/share/gtk-3.0/settings.ini" + echo -e '[Settings]\ngtk-button-images=1' > "$BUILD_DIR/share/gtk-3.0/settings.ini" - name: Create installer if: ${{matrix.build_type == 'release' && (github.ref_type == 'tag' || github.ref_name == 'dev')}} From 38ab9af4fc72239ef4132e4f7ca18b67f3e30bd2 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 01:05:38 -0800 Subject: [PATCH 208/326] Mac: option for CI artifact naming --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30e646fd8..92888424c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,9 @@ option(OSX_DEV_BUILD "Generate macOS development builds" OFF) # On macOS, optionally generate the final zip artifact file without version in the name for nightly upload purposes. option(OSX_NIGHTLY "Generate a generically-named zip" OFF) +# On macOS, optionally generate RawTherapee__macOS_.zip for the CI +option(OSX_CONTINUOUS "Generate a generically-named zip for CI" OFF) + # Generate a universal macOS build option(OSX_UNIVERSAL "Generate a universal app" OFF) @@ -94,14 +97,13 @@ option(OSX_UNIVERSAL "Generate a universal app" OFF) if(OSX_UNIVERSAL) if(NOT "${OSX_UNIVERSAL_URL}") if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") - set(OSX_UNIVERSAL_URL "https://kd6kxr.keybase.pub/RawTherapee_macOS_x86_64_latest.zip" CACHE STRING "URL of x86_64 app for lipo") + set(OSX_UNIVERSAL_URL "file:///rawtherapee/latest/RawTherapee_macOS_x86_64_latest.zip" CACHE STRING "URL of x86_64 app for lipo") else() - set(OSX_UNIVERSAL_URL "https://kd6kxr.keybase.pub/RawTherapee_macOS_arm64_latest.zip" CACHE STRING "URL of arm64 app for lipo") + set(OSX_UNIVERSAL_URL "file:///rawtherapee/latest/RawTherapee_macOS_arm64_latest.zip" CACHE STRING "URL of arm64 app for lipo") endif() endif() endif() - # By default we don't use a specific processor target, so PROC_TARGET_NUMBER is # set to 0. Specify other values to optimize for specific processor architecture # as listed in ProcessorTargets.cmake: From a79888c1af937e3f1f5d465ed8ffe637a8f0d992 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 01:08:26 -0800 Subject: [PATCH 209/326] Mac: CI artifact naming --- tools/osx/macosx_bundle.sh | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index a43a1814c..f06ce8aa9 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -120,8 +120,8 @@ minimum_macos_version=${MINIMUM_SYSTEM_VERSION} #Out: /opt LOCAL_PREFIX="$(cmake .. -L -N | grep LOCAL_PREFIX)"; LOCAL_PREFIX="${LOCAL_PREFIX#*=}" -#In: OSX_UNIVERSAL_URL=https:// etc. -#Out: https:// etc. +#In: OSX_UNIVERSAL_URL=file:/// etc. +#Out: file:/// etc. UNIVERSAL_URL="$(cmake .. -L -N | grep OSX_UNIVERSAL_URL)"; UNIVERSAL_URL="${UNIVERSAL_URL#*=}" if [[ -n $UNIVERSAL_URL ]]; then echo "Universal app is ON. The URL is ${UNIVERSAL_URL}" @@ -153,6 +153,13 @@ if [[ -n $NIGHTLY ]]; then echo "Nightly/generically-named zip is ON." fi +# In: OSX_CONTINUOUS:BOOL=ON +# Out: ON +OSX_CONTINUOUS="$(cmake .. -L -N | grep OSX_CONTINUOUS)"; NIGHTLY="${OSX_CONTINUOUS#*=}" && CONTINUOUS="${OSX_CONTINUOUS#*=}" +if [[ -n $CONTINUOUS ]]; then + echo "Continuous/generically-named zip is ON." +fi + APP="${PROJECT_NAME}.app" CONTENTS="${APP}/Contents" RESOURCES="${CONTENTS}/Resources" @@ -434,12 +441,16 @@ function CreateDmg { # Zip disk image for redistribution msg "Zipping disk image for redistribution:" mkdir "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" - ditto {"${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.dmg","rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.txt"} "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" + cp {"${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.dmg","${PROJECT_NAME}.app/Contents/Frameworks/rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.readme.rtf"} "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" zip -r "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/" if [[ -n $NIGHTLY ]]; then cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" fi + if [[ -n $CONTINUOUS ]]; then + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git status|head -1|awk -v N=$3 '{print $3}')_macOS_${arch}_${CMAKE_BUILD_TYPE}.zip" + fi } + CreateDmg msg "Finishing build:" echo "Script complete." From 53b4edd01d6f35c7d500fadfa7bb28bf66369393 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 01:11:22 -0800 Subject: [PATCH 210/326] Mac: removes arch from CI name --- tools/osx/macosx_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index f06ce8aa9..8125f45ee 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -447,7 +447,7 @@ function CreateDmg { cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" fi if [[ -n $CONTINUOUS ]]; then - mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git status|head -1|awk -v N=$3 '{print $3}')_macOS_${arch}_${CMAKE_BUILD_TYPE}.zip" + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git status|head -1|awk -v N=$3 '{print $3}')_macOS_${CMAKE_BUILD_TYPE}.zip" fi } From 60ac617bcf65b20a011cdae593ebf8d409060eff Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 01:42:51 -0800 Subject: [PATCH 211/326] Mac: set the CI artifact name --- .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 7d3e0cbfd..3348d48b9 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -63,7 +63,7 @@ jobs: -DCMAKE_AR=/usr/bin/ar \ -DCMAKE_RANLIB=/usr/bin/ranlib \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ - -DOSX_NIGHTLY=ON \ + -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"' @@ -79,7 +79,7 @@ jobs: zsh date +%s > build/bundlestamp && date -u && cd build export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle - export ARTIFACT=(RawTherapee*latest.zip) + 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 From 3e11f0bcf874071a65eba0cac28161afe6b90d23 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 10:02:52 -0800 Subject: [PATCH 212/326] Mac: use the symbolic ref for branch --- tools/osx/macosx_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 8125f45ee..51c055ee8 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -447,7 +447,7 @@ function CreateDmg { cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" fi if [[ -n $CONTINUOUS ]]; then - mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git status|head -1|awk -v N=$3 '{print $3}')_macOS_${CMAKE_BUILD_TYPE}.zip" + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git symbolic-ref --short -q HEAD)_macOS_${CMAKE_BUILD_TYPE}.zip" fi } From ec19698dc4347318c54fd7e0f6c7d352c3a8629d Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 11:42:47 -0800 Subject: [PATCH 213/326] Mac: use git branch --show-current --- tools/osx/macosx_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 51c055ee8..ace34d70f 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -447,7 +447,7 @@ function CreateDmg { cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" fi if [[ -n $CONTINUOUS ]]; then - mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git symbolic-ref --short -q HEAD)_macOS_${CMAKE_BUILD_TYPE}.zip" + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git branch --show-current)_macOS_${CMAKE_BUILD_TYPE}.zip" fi } From f92dca3e590b65c4feee50b3aa0755811aa1d29f Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 15:07:57 -0800 Subject: [PATCH 214/326] Mac: handle detached HEAD --- tools/osx/macosx_bundle.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index ace34d70f..6b91654a3 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -447,7 +447,11 @@ function CreateDmg { cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" fi if [[ -n $CONTINUOUS ]]; then - mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_$(git branch --show-current)_macOS_${CMAKE_BUILD_TYPE}.zip" + BRANCH=$(git branch --show-current) + if test -z "${BRANCH}" + BRANCH=$(git rev-parse --short HEAD) + fi + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_${BRANCH}_macOS_${CMAKE_BUILD_TYPE}.zip" fi } From ee2ebabb78533da17abaeb3872ce910bc05e950f Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 8 Mar 2023 15:57:07 -0800 Subject: [PATCH 215/326] =?UTF-8?q?Mac:=20add=20missing=20=E2=80=98then?= =?UTF-8?q?=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/osx/macosx_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 6b91654a3..ca381ec14 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -448,7 +448,7 @@ function CreateDmg { fi if [[ -n $CONTINUOUS ]]; then BRANCH=$(git branch --show-current) - if test -z "${BRANCH}" + 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" From 4fef3f3852e539b70bc65f00a81142cfb3c970c3 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Fri, 10 Mar 2023 02:07:43 +0100 Subject: [PATCH 216/326] OM Digital Solutions OM-5 camconst #6699 Co-authored-by: Michael Lenz --- rtengine/camconst.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ac3980bbe..cfee0dcd4 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2185,6 +2185,16 @@ Camera constants: ] }, + { // Quality X + "make_model": ["OM Digital Solutions OM-5"], + "dcraw_matrix": [ 11896, -5110, -1076, -3181, 11378, 2048, -519, 1224, 5166 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 15.0 + "raw_crop" : [ + { "frame" : [8200, 6132], "crop": [0, 0, 8172, 6132] }, + { "frame" : [5240, 3912], "crop": [0, 0, 5240, 3912] }, + { "frame" : [10400, 7792], "crop": [0, 0, 10392, 7792] } + ] + }, + { // Quality B "make_model": [ "Panasonic DC-LX100M2" ], "dcraw_matrix": [ 11577, -4230, -1106, -3967, 12211, 1957, -759, 1762, 5610 ], // DNG v13.2 From 508ca583df991c1b413744b1c86fdfa43f165139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Mon, 13 Mar 2023 18:19:41 -0400 Subject: [PATCH 217/326] Issue #6708 - fix overlapping buffer strcpy - address sanitizer triggered an error on Fujifilm Finepix HS10 --- rtengine/dcraw.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 7a2a5b4d5..15c2f04fb 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -9807,9 +9807,9 @@ void CLASS identify() if (!strncasecmp (model, make, i) && model[i++] == ' ') memmove (model, model+i, 64-i); if (!strncmp (model,"FinePix ",8)) - strcpy (model, model+8); +/* RT */ memmove (model, model+8, 64-8); if (!strncmp (model,"Digital Camera ",15)) - strcpy (model, model+15); +/* RT */ memmove (model, model+15, 64-15); desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; if (!is_raw) goto notraw; From 005bfbc4952fe81c5459b1140011229742171033 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 15 Mar 2023 10:21:18 -0700 Subject: [PATCH 218/326] Mac: add CR3 defalut handling --- tools/osx/Info.plist.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/osx/Info.plist.in b/tools/osx/Info.plist.in index 876d35e3a..2faa69f83 100644 --- a/tools/osx/Info.plist.in +++ b/tools/osx/Info.plist.in @@ -73,6 +73,8 @@ arw CR2 cr2 + CR3 + cr3 CRF crf CRW From 2149a2b35a7300db051519f8a14e993ce3d38a7d Mon Sep 17 00:00:00 2001 From: rubisetcie Date: Fri, 17 Mar 2023 21:47:38 +0100 Subject: [PATCH 219/326] =?UTF-8?q?Fixed=20typo=20"lominosit=C3=A9"=20->?= =?UTF-8?q?=20"luminosit=C3=A9"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtdata/languages/Francais | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index b7b2c7ec7..f4ef5a0db 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -2732,8 +2732,8 @@ TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Canal TP_RGBCURVES_GREEN;V TP_RGBCURVES_LABEL;Courbes RVB -TP_RGBCURVES_LUMAMODE;Mode Lominosité -TP_RGBCURVES_LUMAMODE_TOOLTIP;Mode Lominosité permet de faire varier la contribution des canaux R, V et B à la luminosité de l'image, sans altérer les couleurs de l'image. +TP_RGBCURVES_LUMAMODE;Mode Luminosité +TP_RGBCURVES_LUMAMODE_TOOLTIP;Mode Luminosité permet de faire varier la contribution des canaux R, V et B à la luminosité de l'image, sans altérer les couleurs de l'image. TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;Degré TP_ROTATE_LABEL;Rotation From 1e6cc85fe2bfd2c765d143e63a5a7cdf0ba151d0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 18 Mar 2023 18:15:38 -0700 Subject: [PATCH 220/326] Add missing includes Thanks to Benitoite (https://github.com/Beep6581/RawTherapee/pull/5889#issuecomment-1475033091) --- rtengine/imagedata.cc | 7 ++++--- rtengine/imageio.cc | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4e5022973..73c51b103 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -17,19 +17,20 @@ * along with RawTherapee. If not, see . */ #include +#include +#include +#include #include #include #include #include #include -#include -#include #include "imagedata.h" #include "imagesource.h" -#include "rt_math.h" #include "metadata.h" +#include "rt_math.h" #include "utils.h" #pragma GCC diagnostic warning "-Wextra" diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 5748ef085..0388467be 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -19,6 +19,7 @@ */ #include #include +#include #include #include #include From 69c1caafa10f5996a1213c1c851bf727a356b855 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 19 Mar 2023 07:47:58 +0100 Subject: [PATCH 221/326] Whitebalance - Removed GUI Itcwb from whitebalance and preferences (#6710) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change Preferences for observer whitebalance * Change label white balance preferences * Added Preferences 2 parameters Whitebalance auto correlation * Add Preference Temperature correlation - sort and tooltip * Change to rtengine cmakelist * Apply patch from Lawrence37 * Small comment code * Change defaut order prefrences wba * Added force extra algoritm to Preferences * Harmonize itcwb sorted * Add fields to Preferences Itcwb * Change settings precision Itcwb in Preferences * Change tooltip Itcwb preferences * First stage Itwcwb settings in main with pp3 and selction in preferences * Second stage Itwcwb settings in main with pp3 and selction in preferences * Third stage Itwcwb settings in main with pp3 and selction in preferences * Add itcwb_fgreen student - green optimize * Add Itcwb green range * Itcwb history msg - first tooltips * Remove force-extra because always used * reused force-extra to use entire CIExy for sampling datas * Removed inwanted text in console * Set sensitive for Itcwbframe * Various change - comment .. * Small code review - chnage tooltips * Remove settings itcwb_delta in Rawimagesource.cc to simplify * Remove Itcwb Observer - put a single observer for everything - general - itcwb * Fixed conflicts in colortemp.cc * Various change - fixed bug - simplify * Fixed limits for settings pp3 - chnage tooltip * Clean unused code * Put itcwb_findgreen in GUI * Added checkbox 'Low sampling' to find the settings of 5.9 * Set Observer to Observer 10° - preferences default * Missing setting Low sampling * Show white balance multipliers * Change default settings - Itcwb_sorted * Move observer from preferences to WB * Make observer selectable for camera WB * Ensure observer checkbox is in sync with PP3 * Set default ITCWB low sampling for PP3s from <=5.9 Ensure temperature correlation white balance algorithm 1 is used when opening edits from versions 5.9 and earlier. * Removed unused White-balance frame in Preferences * Comment some GUI sliders checkbox * Removed all GUI itcwb in preferences and whitebalance * Removed forgotten code in preferences * Remove labels tooltips history Itcwb --------- Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> --- rtdata/languages/default | 6 + rtengine/colortemp.cc | 57 +-- rtengine/colortemp.h | 34 +- rtengine/filmnegativeproc.cc | 4 +- rtengine/histmatching.cc | 4 +- rtengine/imagesource.h | 6 +- rtengine/improccoordinator.cc | 68 ++-- rtengine/improccoordinator.h | 5 +- rtengine/improcfun.cc | 8 +- rtengine/iplocallab.cc | 6 +- rtengine/previewimage.cc | 6 +- rtengine/procparams.cc | 75 +++- rtengine/procparams.h | 23 +- rtengine/rawimagesource.cc | 657 ++++++++++++++++++++++++++++++---- rtengine/rawimagesource.h | 6 +- rtengine/rtengine.h | 6 +- rtengine/rtthumbnail.cc | 36 +- rtengine/rtthumbnail.h | 11 +- rtengine/settings.h | 13 +- rtengine/simpleprocess.cc | 6 +- rtengine/stdimagesource.cc | 6 +- rtengine/stdimagesource.h | 4 +- rtgui/batchtoolpanelcoord.cc | 8 +- rtgui/batchtoolpanelcoord.h | 4 +- rtgui/checkbox.cc | 2 +- rtgui/filmnegative.cc | 13 +- rtgui/options.cc | 68 +--- rtgui/paramsedited.cc | 66 ++++ rtgui/paramsedited.h | 12 + rtgui/ppversion.h | 4 +- rtgui/preferences.cc | 5 + rtgui/preferences.h | 12 +- rtgui/thumbnail.cc | 20 +- rtgui/thumbnail.h | 4 +- rtgui/toolpanelcoord.h | 8 +- rtgui/wbprovider.h | 11 +- rtgui/whitebalance.cc | 90 ++++- rtgui/whitebalance.h | 10 +- 38 files changed, 1073 insertions(+), 311 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 10d0a89c3..9fe9975d9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1528,6 +1528,7 @@ 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_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1831,6 +1832,7 @@ PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic PREFERENCES_CHUNKSIZE_RGB;RGB processing PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Avoid artifacts +PREFERENCES_WBA;White Balance PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -4079,6 +4081,10 @@ TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 TP_WBALANCE_LED_HEADER;LED TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Method +TP_WBALANCE_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_PICKER;Pick TP_WBALANCE_SHADE;Shade TP_WBALANCE_SIZE;Size: diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index f6e980f2a..756fdf906 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -171,7 +171,7 @@ static const color_match_type cie_colour_match_jd = {//350nm to 830nm 5 nm J.D -ColorTemp::ColorTemp (double t, double g, double e, const std::string &m) : temp(t), green(g), equal(e), method(m) +ColorTemp::ColorTemp (double t, double g, double e, const std::string &m, StandardObserver o) : temp(t), green(g), equal(e), method(m), observer(o) { clip (temp, green, equal); } @@ -189,12 +189,24 @@ void ColorTemp::clip (double &temp, double &green, double &equal) equal = rtengine::LIM(equal, MINEQUAL, MAXEQUAL); } -ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e), method("Custom") +ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e, StandardObserver observer) : equal(e), method("Custom"), observer(observer) { - mul2temp (mulr, mulg, mulb, equal, temp, green); + mul2temp (mulr, mulg, mulb, equal, observer, temp, green); } -void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const +ColorTemp ColorTemp::convertObserver(StandardObserver observer) const +{ + if (observer == this->observer) { + return *this; + } + double r; + double g; + double b; + getMultipliers(r, g, b); + return ColorTemp(r, g, b, equal, observer); +} + +void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, double& temp, double& green) const { double maxtemp = MAXTEMP, mintemp = MINTEMP; @@ -202,7 +214,7 @@ void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmu temp = (maxtemp + mintemp) / 2; while (maxtemp - mintemp > 1) { - temp2mul (temp, 1.0, equal, tmpr, tmpg, tmpb); + temp2mul (temp, 1.0, equal, observer, tmpr, tmpg, tmpb); if (tmpb / tmpr > bmul / rmul) { maxtemp = temp; @@ -2957,14 +2969,19 @@ void ColorTemp::icieCAT02float(float Xw, float Yw, float Zw, float &iCAM02BB00, } -void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxyz, double &Zxyz) +void ColorTemp::temp2mulxyz (double temp, const std::string &method, StandardObserver observer, double &Xxyz, double &Zxyz) { double x, y, z; // We first test for specially handled methods const auto iterator = spectMap.find(method); - const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; - + const auto &color_match = (observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; +/* if(observer == StandardObserver::TEN_DEGREES){ + printf("General Observer 10°\n"); + } else { + printf("General Observer 2°\n"); + } +*/ if (iterator != spectMap.end()) { spectrum_to_xyz_preset(iterator->second, x, y, z, color_match); } else { @@ -2999,11 +3016,11 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxy Zxyz = (1.0 - x - y) / y; } -void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const +void ColorTemp::temp2mul (double temp, double green, double equal, StandardObserver observer, double& rmul, double& gmul, double& bmul) const { clip(temp, green, equal); double Xwb, Zwb; - temp2mulxyz(temp, method, Xwb, Zwb); + temp2mulxyz(temp, method, observer, Xwb, Zwb); double adj = 1.0; @@ -3170,7 +3187,13 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, float CRI_RT = 0.0, CRI[50]; float CRI_RTs = 0.0, CRIs[8]; - const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; + const auto &color_match = (observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; + //exceptional must be used by advice people + if(observer == StandardObserver::TEN_DEGREES){ + printf("CRI Observer 10°\n"); + } else { + printf("CRI Observer 2°\n"); + } for(int i = 0; i < N_c; i++) { spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i], color_match); @@ -3764,17 +3787,9 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float Refxyz[i].Zref = 0.f; } -/* if (settings->verbose) { + const color_match_type &color_match = (wbpar.observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; - if (settings->itcwb_stdobserver10 == false) {//I will try to change settings by main - printf("Use standard observer 2°\n"); - } else { - printf("Use standard observer 10°\n"); - } - } -*/ - const color_match_type &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; - // const color_match_type &color_match = (settings->itcwb_stdobserver10 == true) ? cie_colour_match_jd : cie_colour_match_jd2; + // const color_match_type &color_match = (wbpar.observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; if (separated) { const double tempw = Txyz[repref].Tem; diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index 78091f51d..0fe56b7cd 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -36,6 +36,10 @@ constexpr double MINEQUAL = 0.8; constexpr double MAXEQUAL = 1.5; constexpr double INITIALBLACKBODY = 4000.0; +enum class StandardObserver { + TWO_DEGREES, + TEN_DEGREES, +}; class ColorTemp { @@ -45,32 +49,36 @@ private: double green; double equal; std::string method; + StandardObserver observer{StandardObserver::TEN_DEGREES}; static void clip (double &temp, double &green); static void clip (double &temp, double &green, double &equal); int XYZtoCorColorTemp(double x0, double y0 , double z0, double &temp) const; - void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const; + void temp2mul (double temp, double green, double equal, StandardObserver observer, double& rmul, double& gmul, double& bmul) const; const static std::map spectMap; public: + static constexpr StandardObserver DEFAULT_OBSERVER = StandardObserver::TEN_DEGREES; ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {} explicit ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} - ColorTemp (double t, double g, double e, const std::string &m); - ColorTemp (double mulr, double mulg, double mulb, double e); + ColorTemp (double t, double g, double e, const std::string &m, StandardObserver o); + ColorTemp (double mulr, double mulg, double mulb, double e, StandardObserver observer); static void tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar); - void update (const double rmul, const double gmul, const double bmul, const double equal, const double tempBias=0.0) + void update (const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, const double tempBias=0.0) { this->equal = equal; - mul2temp (rmul, gmul, bmul, this->equal, temp, green); + this->observer = observer; + mul2temp (rmul, gmul, bmul, this->equal, observer, temp, green); if (tempBias != 0.0 && tempBias >= -1.0 && tempBias <= 1.0) { temp += temp * tempBias; } } - void useDefaults (const double equal) + void useDefaults (const double equal, StandardObserver observer) { temp = 6504; // Values copied from procparams.cc green = 1.0; this->equal = equal; + this->observer = observer; } inline std::string getMethod() const @@ -89,14 +97,20 @@ public: { return equal; } + inline StandardObserver getObserver() const + { + return observer; + } + + ColorTemp convertObserver(StandardObserver observer) const; void getMultipliers (double &mulr, double &mulg, double &mulb) const { - temp2mul (temp, green, equal, mulr, mulg, mulb); + temp2mul (temp, green, equal, observer, mulr, mulg, mulb); } - void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const; - static void temp2mulxyz (double tem, const std::string &method, double &Xxyz, double &Zxyz); + void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, double& temp, double& green) const; + static void temp2mulxyz (double tem, const std::string &method, StandardObserver observer, double &Xxyz, double &Zxyz); static void cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, double &CAM02BB01, double &CAM02BB02, double &CAM02BB10, double &CAM02BB11, double &CAM02BB12, double &CAM02BB20, double &CAM02BB21, double &CAM02BB22, double adap ); static void cieCAT02float(float Xw, float Yw, float Zw, float &CAM02BB00, float &CAM02BB01, float &CAM02BB02, float &CAM02BB10, float &CAM02BB11, float &CAM02BB12, float &CAM02BB20, float &CAM02BB21, float &CAM02BB22, float adap); @@ -104,7 +118,7 @@ public: bool operator== (const ColorTemp& other) const { - return fabs(temp - other.temp) < 1e-10 && fabs(green - other.green) < 1e-10; + return fabs(temp - other.temp) < 1e-10 && fabs(green - other.green) < 1e-10 && observer != other.observer; } bool operator!= (const ColorTemp& other) const { diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index c33dc4a9a..eb029d77a 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -340,7 +340,7 @@ bool rtengine::ImProcFunctions::filmNegativeProcess( imgsrc->getWBMults(currWB, params->raw, scale_mul, autoGainComp, rm, gm, bm); float rm2, gm2, bm2; - imgsrc->getWBMults(rtengine::ColorTemp(3500., 1., 1., "Custom"), params->raw, scale_mul, autoGainComp, rm2, gm2, bm2); + imgsrc->getWBMults(rtengine::ColorTemp(3500., 1., 1., "Custom", currWB.getObserver()), params->raw, scale_mul, autoGainComp, rm2, gm2, bm2); float mg = rtengine::max(rm2, gm2, bm2); rm2 /= mg; gm2 /= mg; @@ -611,7 +611,7 @@ void rtengine::Thumbnail::processFilmNegativeV2( // as in the main image processing. double r, g, b; - ColorTemp(3500., 1., 1., "Custom").getMultipliers(r, g, b); + ColorTemp(3500., 1., 1., "Custom", params.wb.observer).getMultipliers(r, g, b); //iColorMatrix is cam_rgb const double rm = camwbRed / (iColorMatrix[0][0] * r + iColorMatrix[0][1] * g + iColorMatrix[0][2] * b); const double gm = camwbGreen / (iColorMatrix[1][0] * r + iColorMatrix[1][1] * g + iColorMatrix[1][2] * b); diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index d3c5d0190..350dbbfab 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -229,7 +229,7 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) } // namespace -void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, std::vector &outCurve) +void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, StandardObserver observer, std::vector &outCurve) { BENCHFUN @@ -313,7 +313,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st eSensorType sensor_type; double scale; int w = fw / skip, h = fh / skip; - std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false, true)); + std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, observer, false, true)); if (!thumb) { if (settings->verbose) { std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index d6d22c269..1f4c2179a 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -119,9 +119,9 @@ public: virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0; virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, 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 ColorTemp getWB () const = 0; - virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) = 0; + virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) = 0; virtual void WBauto(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 &studgood, 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; - virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) = 0; + virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) = 0; virtual double getDefGain () const { @@ -167,7 +167,7 @@ public: } // for RAW files, compute a tone curve using histogram matching on the embedded thumbnail - virtual void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, std::vector &outCurve) + virtual void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, StandardObserver observer, std::vector &outCurve) { outCurve = { 0.0 }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 9437f1a75..664029a5e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -489,7 +489,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { if (params->wb.method == "autitcgreen") { - imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw); + imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw, params->wb); } } @@ -522,7 +522,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) printf("Applying white balance, color correction & sRBG conversion...\n"); } - currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method); + currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); float studgood = 1000.f; if (!params->wb.enabled) { @@ -531,7 +531,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) currWB = imgsrc->getWB(); lastAwbauto = ""; //reinitialize auto } else if (autowb) { - if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { + if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { double rm, gm, bm; double tempitc = 5000.f; double greenitc = 1.; @@ -547,7 +547,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->wb.method == "autitcgreen") { params->wb.temperature = tempitc; params->wb.green = greenitc; - currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method); + currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method, params->wb.observer); + //printf("tempitc=%f greitc=%f\n", tempitc, greenitc); + currWB.getMultipliers(rm, gm, bm); } @@ -558,15 +560,17 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bias = 0.; } - autoWB.update(rm, gm, bm, params->wb.equal, bias); + autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, bias); 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); + autoWB.useDefaults(params->wb.equal, params->wb.observer); } @@ -574,17 +578,24 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) currWB = autoWB; } + double rw = 1.; + double gw = 1.; + double bw = 1.; if (params->wb.enabled) { - params->wb.temperature = currWB.getTemp(); + currWB = currWB.convertObserver(params->wb.observer); + params->wb.temperature = static_cast(currWB.getTemp()); params->wb.green = currWB.getGreen(); + currWB.getMultipliers(rw, gw, bw); + imgsrc->wbMul2Camera(rw, gw, bw); + // printf("ra=%f ga=%f ba=%f\n", rw, gw, bw); } - if (autowb && awbListener) { + if (awbListener) { if (params->wb.method == "autitcgreen") { - awbListener->WBChanged(params->wb.temperature, params->wb.green, studgood); - } else if (params->wb.method == "autold") { - awbListener->WBChanged(params->wb.temperature, params->wb.green, -1.f); + awbListener->WBChanged(params->wb.temperature, params->wb.green, rw, gw, bw, studgood); + } else { + awbListener->WBChanged(params->wb.temperature, params->wb.green, rw, gw, bw, -1.f); } } @@ -621,7 +632,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) PreviewProps pp(0, 0, fw, fh, scale); // Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications ipf.setScale(scale); - int inpaintopposed = 1;//force getimage to use inpaint-opposed if enable, only once + int inpaintopposed = 1;//force getimage to use inpaint-opposed if enable, only once imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw, inpaintopposed); if ((todo & M_SPOT) && params->spot.enabled && !params->spot.entries.empty()) { @@ -782,7 +793,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->toneCurve.histmatching) { if (!params->toneCurve.fromHistMatching) { - imgsrc->getAutoMatchedToneCurve(params->icm, params->toneCurve.curve); + imgsrc->getAutoMatchedToneCurve(params->icm, params->wb.observer, params->toneCurve.curve); } if (params->toneCurve.autoexp) { @@ -2452,11 +2463,11 @@ bool ImProcCoordinator::updateWaveforms() return true; } -bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, double tempBias) +bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, StandardObserver observer, double tempBias) { if (imgsrc) { - if (lastAwbEqual != equal || lastAwbTempBias != tempBias || lastAwbauto != params->wb.method) { + if (lastAwbEqual != equal || lastAwbObserver != observer || lastAwbTempBias != tempBias || lastAwbauto != params->wb.method) { // Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window double rm, gm, bm; params->wb.method = "autold";//same result as before multiple Auto WB @@ -2469,13 +2480,15 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); if (rm != -1) { - autoWB.update(rm, gm, bm, equal, tempBias); + autoWB.update(rm, gm, bm, equal, observer, tempBias); lastAwbEqual = equal; + lastAwbObserver = observer; lastAwbTempBias = tempBias; lastAwbauto = params->wb.method; } else { lastAwbEqual = -1.; - autoWB.useDefaults(equal); + lastAwbObserver = ColorTemp::DEFAULT_OBSERVER; + autoWB.useDefaults(equal, observer); lastAwbauto = ""; lastAwbTempBias = 0.0; } @@ -2492,12 +2505,13 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou } } -void ImProcCoordinator::getCamWB(double& temp, double& green) +void ImProcCoordinator::getCamWB(double& temp, double& green, StandardObserver observer) { if (imgsrc) { - temp = imgsrc->getWB().getTemp(); - green = imgsrc->getWB().getGreen(); + const ColorTemp color_temp = imgsrc->getWB().convertObserver(observer); + temp = color_temp.getTemp(); + green = color_temp.getGreen(); } } @@ -2519,8 +2533,8 @@ void ImProcCoordinator::getSpotWB(int x, int y, int rect, double& temp, double& int tr = getCoarseBitMask(params->coarse); - ret = imgsrc->getSpotWB(red, green, blue, tr, params->wb.equal); - currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method); + ret = imgsrc->getSpotWB(red, green, blue, tr, params->wb.equal, params->wb.observer); + currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); //double rr,gg,bb; //currWB.getMultipliers(rr,gg,bb); @@ -2626,23 +2640,25 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a imgsrc->preprocess(ppar.raw, ppar.lensProf, ppar.coarse); double dummy = 0.0; imgsrc->demosaic(ppar.raw, false, dummy); - ColorTemp currWB = ColorTemp(validParams->wb.temperature, validParams->wb.green, validParams->wb.equal, validParams->wb.method); + ColorTemp currWB = ColorTemp(validParams->wb.temperature, validParams->wb.green, validParams->wb.equal, validParams->wb.method, validParams->wb.observer); if (validParams->wb.method == "Camera") { currWB = imgsrc->getWB(); } else if (validParams->wb.method == "autold") { - if (lastAwbEqual != validParams->wb.equal || lastAwbTempBias != validParams->wb.tempBias) { + if (lastAwbEqual != validParams->wb.equal || lastAwbObserver != validParams->wb.observer || lastAwbTempBias != validParams->wb.tempBias) { double rm, gm, bm; imgsrc->getAutoWBMultipliers(rm, gm, bm); if (rm != -1.) { - autoWB.update(rm, gm, bm, validParams->wb.equal, validParams->wb.tempBias); + autoWB.update(rm, gm, bm, validParams->wb.equal, validParams->wb.observer, validParams->wb.tempBias); lastAwbEqual = validParams->wb.equal; + lastAwbObserver = validParams->wb.observer; lastAwbTempBias = validParams->wb.tempBias; } else { lastAwbEqual = -1.; + lastAwbObserver = ColorTemp::DEFAULT_OBSERVER; lastAwbTempBias = 0.0; - autoWB.useDefaults(validParams->wb.equal); + autoWB.useDefaults(validParams->wb.equal, validParams->wb.observer); } } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 85f28004a..92cdd91c7 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -80,6 +80,7 @@ protected: ColorTemp currWBitc; double lastAwbEqual; + StandardObserver lastAwbObserver{ColorTemp::DEFAULT_OBSERVER}; double lastAwbTempBias; Glib::ustring lastAwbauto; @@ -433,8 +434,8 @@ public: void setTweakOperator (TweakOperator *tOperator) override; void unsetTweakOperator (TweakOperator *tOperator) override; - bool getAutoWB (double& temp, double& green, double equal, double tempBias) override; - void getCamWB (double& temp, double& green) override; + bool getAutoWB (double& temp, double& green, double equal, StandardObserver observer, double tempBias) override; + void getCamWB (double& temp, double& green, StandardObserver observer) override; void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; bool getFilmNegativeSpot(int x, int y, int spotSize, FilmNegativeParams::RGB &refInput, FilmNegativeParams::RGB &refOutput) override; void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 0e08a28eb..c3e11c076 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -552,9 +552,9 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); - ColorTemp::temp2mulxyz(params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB - ColorTemp::temp2mulxyz(params->colorappearance.tempout, "Custom", Xwout, Zwout); - ColorTemp::temp2mulxyz(params->colorappearance.tempsc, "Custom", Xwsc, Zwsc); + ColorTemp::temp2mulxyz(params->wb.temperature, params->wb.method, params->wb.observer, Xw, Zw); //compute white Xw Yw Zw : white current WB + ColorTemp::temp2mulxyz(params->colorappearance.tempout, "Custom", params->wb.observer, Xwout, Zwout); + ColorTemp::temp2mulxyz(params->colorappearance.tempsc, "Custom", params->wb.observer, Xwsc, Zwsc); //viewing condition for surrsrc if (params->colorappearance.surrsrc == "Average") { @@ -5589,7 +5589,7 @@ double ImProcFunctions::getAutoDistor(const Glib::ustring &fname, int thumb_size return 0.0; } - Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, ri, sensorType, w_raw, h_raw, 1, 1.0, FALSE); + Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, ri, sensorType, w_raw, h_raw, 1, 1.0, ColorTemp::DEFAULT_OBSERVER, FALSE); if (!raw) { delete thumb; diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 243f3595d..b9e82cc5d 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2804,9 +2804,9 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } - ColorTemp::temp2mulxyz(params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB - ColorTemp::temp2mulxyz(tempo, "Custom", Xwout, Zwout); - ColorTemp::temp2mulxyz(5000, "Custom", Xwsc, Zwsc); + ColorTemp::temp2mulxyz(params->wb.temperature, params->wb.method, params->wb.observer, Xw, Zw); //compute white Xw Yw Zw : white current WB + ColorTemp::temp2mulxyz(tempo, "Custom", params->wb.observer, Xwout, Zwout); + ColorTemp::temp2mulxyz(5000, "Custom", params->wb.observer, Xwsc, Zwsc); //viewing condition for surrsrc f = 1.00f; diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index 1afe72c92..afaf0cbca 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -42,20 +42,20 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg") { // int deg = infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., ColorTemp::DEFAULT_OBSERVER, true); if (tpp) { data = tpp->getImage8Data(); } } else if (ext.lowercase() == "png") { - tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., ColorTemp::DEFAULT_OBSERVER, true); if (tpp) { data = tpp->getImage8Data(); } } else if (ext.lowercase() == "tif" || ext.lowercase() == "tiff") { // int deg = infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., ColorTemp::DEFAULT_OBSERVER, true); if (tpp) { data = tpp->getImage8Data(); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9323bd9e7..c47723662 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -27,6 +27,7 @@ #include #include "color.h" +#include "colortemp.h" #include "curves.h" #include "procparams.h" #include "utils.h" @@ -1331,7 +1332,19 @@ WBParams::WBParams() : temperature(6504), green(1.0), equal(1.0), - tempBias(0.0) + tempBias(0.0), + observer(ColorTemp::DEFAULT_OBSERVER), + itcwb_thres(34), + itcwb_precis(3), + itcwb_size(3), + itcwb_delta(2), + itcwb_fgreen(5), + itcwb_rgreen(1), + itcwb_nopurple(true), + itcwb_sorted(false), + itcwb_forceextra(false), + itcwb_sampling(false) + { } @@ -1351,6 +1364,7 @@ bool WBParams::isPanningRelatedChange(const WBParams& other) const && green == other.green && equal == other.equal && tempBias == other.tempBias + && observer == other.observer ) ) ); @@ -1364,7 +1378,19 @@ bool WBParams::operator ==(const WBParams& other) const && temperature == other.temperature && green == other.green && equal == other.equal - && tempBias == other.tempBias; + && tempBias == other.tempBias + && observer == other.observer + && itcwb_thres == other.itcwb_thres + && itcwb_precis == other.itcwb_precis + && itcwb_size == other.itcwb_size + && itcwb_delta == other.itcwb_delta + && itcwb_fgreen == other.itcwb_fgreen + && itcwb_rgreen == other.itcwb_rgreen + && itcwb_nopurple == other.itcwb_nopurple + && itcwb_sorted == other.itcwb_sorted + && itcwb_forceextra == other.itcwb_forceextra + && itcwb_sampling == other.itcwb_sampling; + } bool WBParams::operator !=(const WBParams& other) const @@ -6108,6 +6134,17 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wb.green, "White Balance", "Green", wb.green, keyFile); saveToKeyfile(!pedited || pedited->wb.equal, "White Balance", "Equal", wb.equal, keyFile); saveToKeyfile(!pedited || pedited->wb.tempBias, "White Balance", "TemperatureBias", wb.tempBias, keyFile); + saveToKeyfile(!pedited || pedited->wb.observer, "White Balance", "StandardObserver", Glib::ustring(wb.observer == StandardObserver::TWO_DEGREES ? "TWO_DEGREES" : "TEN_DEGREES"), keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_thres, "White Balance", "Itcwb_thres", wb.itcwb_thres, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_precis, "White Balance", "Itcwb_precis", wb.itcwb_precis, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_size, "White Balance", "Itcwb_size", wb.itcwb_size, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_delta, "White Balance", "Itcwb_delta", wb.itcwb_delta, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_fgreen, "White Balance", "Itcwb_findgreen", wb.itcwb_fgreen, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_rgreen, "White Balance", "Itcwb_rangegreen", wb.itcwb_rgreen, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_nopurple, "White Balance", "Itcwb_nopurple", wb.itcwb_nopurple, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_sorted, "White Balance", "Itcwb_sorted", wb.itcwb_sorted, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_forceextra, "White Balance", "Itcwb_forceextra", wb.itcwb_forceextra, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_sampling, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, keyFile); // Colorappearance saveToKeyfile(!pedited || pedited->colorappearance.enabled, "Color appearance", "Enabled", colorappearance.enabled, keyFile); @@ -8039,6 +8076,17 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Vibrance", "PastSatTog", pedited, vibrance.pastsattog, pedited->vibrance.pastsattog); assignFromKeyfile(keyFile, "Vibrance", "SkinTonesCurve", pedited, vibrance.skintonescurve, pedited->vibrance.skintonescurve); } + if (ppVersion <= 346) { // 5.8 and earlier. + wb.observer = StandardObserver::TWO_DEGREES; + if (pedited) { + pedited->wb.observer = true; + } + } else if (ppVersion <= 349) { // 5.9 + wb.observer = StandardObserver::TEN_DEGREES; + if (pedited) { + pedited->wb.observer = true; + } + } 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); @@ -8049,6 +8097,29 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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); + Glib::ustring standard_observer; + assignFromKeyfile(keyFile, "White Balance", "StandardObserver", pedited, 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_thres", pedited, wb.itcwb_thres, pedited->wb.itcwb_thres); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_precis", pedited, wb.itcwb_precis, pedited->wb.itcwb_precis); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_size", pedited, wb.itcwb_size, pedited->wb.itcwb_size); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_delta", pedited, wb.itcwb_delta, pedited->wb.itcwb_delta); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_findgreen", pedited, wb.itcwb_fgreen, pedited->wb.itcwb_fgreen); + 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_sorted", pedited, wb.itcwb_sorted, pedited->wb.itcwb_sorted); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_forceextra", pedited, wb.itcwb_forceextra, pedited->wb.itcwb_forceextra); + 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); } if (keyFile.has_group("Defringing")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 33d95a619..48b68f598 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -59,6 +59,8 @@ class LocLLmaskexpCurve; class LocCCmaskexpCurve; class LocHHmaskexpCurve; +enum class StandardObserver; + enum RenderingIntent : int { RI_PERCEPTUAL = INTENT_PERCEPTUAL, RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, @@ -634,11 +636,22 @@ struct WBEntry { struct WBParams { bool enabled; - Glib::ustring method; - int temperature; - double green; - double equal; - double tempBias; + Glib::ustring method; + int temperature; + double green; + double equal; + double tempBias; + StandardObserver observer; + int itcwb_thres; + int itcwb_precis; + int itcwb_size; + int itcwb_delta; + int itcwb_fgreen; + int itcwb_rgreen; + bool itcwb_nopurple; + bool itcwb_sorted; + bool itcwb_forceextra; + bool itcwb_sampling; WBParams(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 75757d325..06aa701e8 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -843,28 +843,27 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima int maxx = this->W, maxy = this->H, skip = pp.getSkip(); - bool iscolor = (hrp.method == "Color" || hrp.method == "Coloropp"); - const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; + bool iscolor = (hrp.method == "Color" || hrp.method == "Coloropp"); + const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; bool doHr = (hrp.hrenabled && !iscolor); - if (hrp.hrenabled && iscolor) { - - if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited tne number to 1 - rgbSourceModified = false; - } + if (hrp.hrenabled && iscolor) { + if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited tne number to 1 + rgbSourceModified = false; + } if (!rgbSourceModified) { - if(hrp.method == "Color") { - if (settings->verbose) { - printf ("Applying Highlight Recovery: Color propagation.\n"); - } - HLRecovery_inpaint (red, green, blue, hrp.hlbl); - } else if(hrp.method == "Coloropp" && ctemp.getTemp() >= 0) { - float s[3] = { rm, gm, bm }; - highlight_recovery_opposed(s, ctemp, hrp.hlth); - } + if(hrp.method == "Color") { + if (settings->verbose) { + printf ("Applying Highlight Recovery: Color propagation.\n"); + } + HLRecovery_inpaint (red, green, blue, hrp.hlbl); + } else if(hrp.method == "Coloropp" && ctemp.getTemp() >= 0) { + float s[3] = { rm, gm, bm }; + highlight_recovery_opposed(s, ctemp, hrp.hlth); + } rgbSourceModified = true; } } - + // now apply the wb coefficients if (ctemp.getTemp() >= 0) { double r, g, b; @@ -1297,7 +1296,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) double cam_r = imatrices.rgb_cam[0][0] * camwb_red + imatrices.rgb_cam[0][1] * camwb_green + imatrices.rgb_cam[0][2] * camwb_blue; double cam_g = imatrices.rgb_cam[1][0] * camwb_red + imatrices.rgb_cam[1][1] * camwb_green + imatrices.rgb_cam[1][2] * camwb_blue; double cam_b = imatrices.rgb_cam[2][0] * camwb_red + imatrices.rgb_cam[2][1] * camwb_green + imatrices.rgb_cam[2][2] * camwb_blue; - camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1.); // as shot WB + camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1., ColorTemp::DEFAULT_OBSERVER); // as shot WB if (settings->verbose) { printf("Raw As Shot White balance: temp %f, tint %f\n", camera_wb.getTemp(), camera_wb.getGreen()); @@ -1384,7 +1383,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le const double ref_r = imatrices.rgb_cam[0][0] * refwb_red + imatrices.rgb_cam[0][1] * refwb_green + imatrices.rgb_cam[0][2] * refwb_blue; const double ref_g = imatrices.rgb_cam[1][0] * refwb_red + imatrices.rgb_cam[1][1] * refwb_green + imatrices.rgb_cam[1][2] * refwb_blue; const double ref_b = imatrices.rgb_cam[2][0] * refwb_red + imatrices.rgb_cam[2][1] * refwb_green + imatrices.rgb_cam[2][2] * refwb_blue; - const ColorTemp ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.); + const ColorTemp ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1., ColorTemp::DEFAULT_OBSERVER); if (settings->verbose) { printf("Raw Reference white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green); @@ -4037,6 +4036,475 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) } } + +static void histoxyY_low(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy) +{ + //calculate histogram x y in a range of 190 colors + //this "choice" are guided by generally colors who are in nature skin, sky, etc. in those cases "steps" are small + // of course we can change to be more precise +#ifdef _OPENMP + #pragma omp parallel +#endif + { + LUTu histxythr(histxy.getSize()); + histxythr.clear(); + LUTf xxxthr(xxx.getSize()); + xxxthr.clear(); + LUTf yyythr(yyy.getSize()); + yyythr.clear(); + LUTf YYYthr(YYY.getSize()); + YYYthr.clear(); +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 4) nowait +#endif + for (int y = 0; y < bfhitc ; y++) { + for (int x = 0; x < bfwitc ; x++) { + int nh = -1; + if (xc[y][x] < 0.12f && xc[y][x] > 0.03f && yc[y][x] > 0.1f) { // near Prophoto + if (yc[y][x] < 0.2f) { + nh = 0; + //blue hard + } else if (yc[y][x] < 0.3f) { + nh = 1; + //blue + } else if (yc[y][x] < 0.4f) { + nh = 2; + + } else if (yc[y][x] < 0.5f) { + //blue green + nh = 3; + } else if (yc[y][x] < 0.6f) { + nh = 4; + } else if (yc[y][x] < 0.82f) { + //green + nh = 5; + } + } else if (xc[y][x] < 0.24f && yc[y][x] > 0.05f) { + if (yc[y][x] < 0.2f) { + nh = 6; + } else if (yc[y][x] < 0.3f) { + nh = 7; + } else if (yc[y][x] < 0.4f) { + nh = 8; + } else if (yc[y][x] < 0.5f) { + nh = 9; + } else if (yc[y][x] < 0.6f) { + nh = 10; + } else if (yc[y][x] < 0.75f) { + nh = 11; + } + } else if (xc[y][x] < 0.28f && yc[y][x] > 0.1f) {//blue sky and other + if (yc[y][x] < 0.2f) { + nh = 12; + } else if (yc[y][x] < 0.25f) { + nh = 13; + } else if (yc[y][x] < 0.29f) { + nh = 14; + } else if (yc[y][x] < 0.33f) { + nh = 15; + } else if (yc[y][x] < 0.37f) { + nh = 16; + } else if (yc[y][x] < 0.4f) { + nh = 17; + } else if (yc[y][x] < 0.45f) { + nh = 18; + } else if (yc[y][x] < 0.5f) { + nh = 19; + } else if (yc[y][x] < 0.6f) { + nh = 20; + } else if (yc[y][x] < 0.75f) { + nh = 21; + } + } else if (xc[y][x] < 0.31f && yc[y][x] > 0.1f) {//near neutral others + if (yc[y][x] < 0.2f) { + nh = 22; + } else if (yc[y][x] < 0.24f) { + nh = 23; + } else if (yc[y][x] < 0.29f) { + nh = 24; + } else if (yc[y][x] < 0.32f) { + nh = 25; + } else if (yc[y][x] < 0.36f) { + nh = 26; + } else if (yc[y][x] < 0.4f) { + nh = 27; + } else if (yc[y][x] < 0.5f) { + nh = 28; + } else if (yc[y][x] < 0.7f) { + nh = 29; + } + } else if (xc[y][x] < 0.325f && yc[y][x] > 0.1f) {//neutral 34 + if (yc[y][x] < 0.2f) { + nh = 30; + } else if (yc[y][x] < 0.24f) { + nh = 31; + } else if (yc[y][x] < 0.29f) { + nh = 32; + } else if (yc[y][x] < 0.32f) { + nh = 33; + } else if (yc[y][x] < 0.33f) { + nh = 34; + } else if (yc[y][x] < 0.335f) { + nh = 35; + } else if (yc[y][x] < 0.34f) { + nh = 36; + } else if (yc[y][x] < 0.35f) { + nh = 37; + } else if (yc[y][x] < 0.37f) { + nh = 38; + } else if (yc[y][x] < 0.4f) { + nh = 39; + } else if (yc[y][x] < 0.45f) { + nh = 40; + } else if (yc[y][x] < 0.5f) { + nh = 41; + } else if (yc[y][x] < 0.55f) { + nh = 42; + } else if (yc[y][x] < 0.7f) { + nh = 43; + } + } else if (xc[y][x] < 0.335f && yc[y][x] > 0.1f) {//neutral + if (yc[y][x] < 0.2f) { + nh = 44; + } else if (yc[y][x] < 0.24f) { + nh = 45; + } else if (yc[y][x] < 0.29f) { + nh = 46; + } else if (yc[y][x] < 0.32f) { + nh = 47; + } else if (yc[y][x] < 0.33f) { + nh = 48; + } else if (yc[y][x] < 0.335f) { + nh = 49; + } else if (yc[y][x] < 0.34f) { + nh = 50; + } else if (yc[y][x] < 0.345f) { + nh = 51; + } else if (yc[y][x] < 0.35f) { + nh = 52; + } else if (yc[y][x] < 0.355f) { + nh = 53; + } else if (yc[y][x] < 0.36f) { + nh = 54; + } else if (yc[y][x] < 0.37f) { + nh = 55; + } else if (yc[y][x] < 0.38f) { + nh = 56; + } else if (yc[y][x] < 0.4f) { + nh = 57; + } else if (yc[y][x] < 0.45f) { + nh = 58; + } else if (yc[y][x] < 0.5f) { + nh = 59; + } else if (yc[y][x] < 0.55f) { + nh = 60; + } else if (yc[y][x] < 0.7f) { + nh = 61; + } + } else if (xc[y][x] < 0.340f && yc[y][x] > 0.1f) {//neutral + if (yc[y][x] < 0.2f) { + nh = 62; + } else if (yc[y][x] < 0.24f) { + nh = 63; + } else if (yc[y][x] < 0.29f) { + nh = 64; + } else if (yc[y][x] < 0.32f) { + nh = 65; + } else if (yc[y][x] < 0.325f) { + nh = 66; + } else if (yc[y][x] < 0.33f) { + nh = 67; + } else if (yc[y][x] < 0.335f) { + nh = 68; + } else if (yc[y][x] < 0.34f) { + nh = 69; + } else if (yc[y][x] < 0.345f) { + nh = 70; + } else if (yc[y][x] < 0.35f) { + nh = 71; + } else if (yc[y][x] < 0.355f) { + nh = 72; + } else if (yc[y][x] < 0.36f) { + nh = 73; + } else if (yc[y][x] < 0.37f) { + nh = 74; + } else if (yc[y][x] < 0.38f) { + nh = 75; + } else if (yc[y][x] < 0.4f) { + nh = 76; + } else if (yc[y][x] < 0.45f) { + nh = 77; + } else if (yc[y][x] < 0.5f) { + nh = 78; + } else if (yc[y][x] < 0.55f) { + nh = 79; + } else if (yc[y][x] < 0.7f) { + nh = 80; + } + } else if (xc[y][x] < 0.345f && yc[y][x] > 0.1f) {//neutral 37 + if (yc[y][x] < 0.2f) { + nh = 81; + } else if (yc[y][x] < 0.24f) { + nh = 82; + } else if (yc[y][x] < 0.29f) { + nh = 83; + } else if (yc[y][x] < 0.32f) { + nh = 84; + } else if (yc[y][x] < 0.33f) { + nh = 85; + } else if (yc[y][x] < 0.335f) { + nh = 86; + } else if (yc[y][x] < 0.34f) { + nh = 87; + } else if (yc[y][x] < 0.345f) { + nh = 88; + } else if (yc[y][x] < 0.35f) { + nh = 89; + } else if (yc[y][x] < 0.355f) { + nh = 90; + } else if (yc[y][x] < 0.36f) { + nh = 91; + } else if (yc[y][x] < 0.37f) { + nh = 92; + } else if (yc[y][x] < 0.38f) { + nh = 93; + } else if (yc[y][x] < 0.39f) { + nh = 94; + } else if (yc[y][x] < 0.4f) { + nh = 95; + } else if (yc[y][x] < 0.42f) { + nh = 96; + } else if (yc[y][x] < 0.45f) { + nh = 97; + } else if (yc[y][x] < 0.48f) { + nh = 98; + } else if (yc[y][x] < 0.5f) { + nh = 99; + } else if (yc[y][x] < 0.55f) { + nh = 100; + } else if (yc[y][x] < 0.65f) { + nh = 101; + } + } else if (xc[y][x] < 0.355f && yc[y][x] > 0.1f) {//neutral 37 + if (yc[y][x] < 0.2f) { + nh = 102; + } else if (yc[y][x] < 0.24f) { + nh = 103; + } else if (yc[y][x] < 0.29f) { + nh = 104; + } else if (yc[y][x] < 0.32f) { + nh = 105; + } else if (yc[y][x] < 0.33f) { + nh = 106; + } else if (yc[y][x] < 0.335f) { + nh = 107; + } else if (yc[y][x] < 0.34f) { + nh = 108; + } else if (yc[y][x] < 0.345f) { + nh = 109; + } else if (yc[y][x] < 0.35f) { + nh = 110; + } else if (yc[y][x] < 0.355f) { + nh = 111; + } else if (yc[y][x] < 0.36f) { + nh = 112; + } else if (yc[y][x] < 0.37f) { + nh = 113; + } else if (yc[y][x] < 0.38f) { + nh = 114; + } else if (yc[y][x] < 0.39f) { + nh = 115; + } else if (yc[y][x] < 0.4f) { + nh = 116; + } else if (yc[y][x] < 0.42f) { + nh = 117; + } else if (yc[y][x] < 0.45f) { + nh = 118; + } else if (yc[y][x] < 0.48f) { + nh = 119; + } else if (yc[y][x] < 0.5f) { + nh = 120; + } else if (yc[y][x] < 0.55f) { + nh = 121; + } else if (yc[y][x] < 0.65f) { + nh = 122; + } + } else if (xc[y][x] < 0.365f && yc[y][x] > 0.15f) { //0.4 + if (yc[y][x] < 0.2f) { + nh = 123; + } else if (yc[y][x] < 0.24f) { + nh = 124; + } else if (yc[y][x] < 0.29f) { + nh = 125; + } else if (yc[y][x] < 0.32f) { + nh = 126; + } else if (yc[y][x] < 0.33f) { + nh = 127; + } else if (yc[y][x] < 0.34f) { + nh = 128; + } else if (yc[y][x] < 0.35f) { + nh = 129; + } else if (yc[y][x] < 0.36f) { + nh = 130; + } else if (yc[y][x] < 0.37f) { + nh = 131; + } else if (yc[y][x] < 0.38f) { + nh = 132; + } else if (yc[y][x] < 0.39f) { + nh = 133; + } else if (yc[y][x] < 0.4f) { + nh = 134; + } else if (yc[y][x] < 0.42f) { + nh = 135; + } else if (yc[y][x] < 0.45f) { + nh = 136; + } else if (yc[y][x] < 0.5f) { + nh = 137; + } else if (yc[y][x] < 0.55f) { + nh = 138; + } else if (yc[y][x] < 0.63f) { + nh = 139; + } + } else if (xc[y][x] < 0.405f && yc[y][x] > 0.15f) {//45 + if (yc[y][x] < 0.2f) { + nh = 140; + } else if (yc[y][x] < 0.24f) { + nh = 141; + } else if (yc[y][x] < 0.29f) { + nh = 142; + } else if (yc[y][x] < 0.32f) { + nh = 143; + } else if (yc[y][x] < 0.34f) { + nh = 144; + } else if (yc[y][x] < 0.37f) { + nh = 145; + } else if (yc[y][x] < 0.4f) { + nh = 146; + } else if (yc[y][x] < 0.45f) { + nh = 147; + } else if (yc[y][x] < 0.5f) { + nh = 148; + } else if (yc[y][x] < 0.55f) { + nh = 149; + } else if (yc[y][x] < 0.6f) { + nh = 150; + } + } else if (xc[y][x] < 0.445f && yc[y][x] > 0.15f) {//45 + if (yc[y][x] < 0.2f) { + nh = 151; + } else if (yc[y][x] < 0.24f) { + nh = 152; + } else if (yc[y][x] < 0.29f) { + nh = 153; + } else if (yc[y][x] < 0.32f) { + nh = 154; + } else if (yc[y][x] < 0.34f) { + nh = 155; + } else if (yc[y][x] < 0.37f) { + nh = 156; + } else if (yc[y][x] < 0.4f) { + nh = 157; + } else if (yc[y][x] < 0.45f) { + nh = 158; + } else if (yc[y][x] < 0.5f) { + nh = 159; + } else if (yc[y][x] < 0.55f) { + nh = 160; + } else if (yc[y][x] < 0.58f) { + nh = 161; + } + } else if (xc[y][x] < 0.495f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f) { + nh = 162; + } else if (yc[y][x] < 0.24f) { + nh = 163; + } else if (yc[y][x] < 0.29f) { + nh = 164; + } else if (yc[y][x] < 0.32f) { + nh = 165; + } else if (yc[y][x] < 0.34f) { + nh = 166; + } else if (yc[y][x] < 0.37f) { + nh = 167; + } else if (yc[y][x] < 0.4f) { + nh = 168; + } else if (yc[y][x] < 0.45f) { + nh = 169; + } else if (yc[y][x] < 0.5f) { + nh = 170; + } else if (yc[y][x] < 0.55f) { + nh = 171; + } + } else if (xc[y][x] < 0.545f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f) { + nh = 172; + } else if (yc[y][x] < 0.24f) { + nh = 173; + } else if (yc[y][x] < 0.29f) { + nh = 174; + } else if (yc[y][x] < 0.32f) { + nh = 175; + } else if (yc[y][x] < 0.34f) { + nh = 176; + } else if (yc[y][x] < 0.37f) { + nh = 177; + } else if (yc[y][x] < 0.4f) { + nh = 178; + } else if (yc[y][x] < 0.45f) { + nh = 179; + } else if (yc[y][x] < 0.5f) { + nh = 180; + } + } else if (xc[y][x] < 0.595f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.22f) { + nh = 181; + } else if (yc[y][x] < 0.25f) { + nh = 182; + } else if (yc[y][x] < 0.3f) { + nh = 183; + } else if (yc[y][x] < 0.35f) { + nh = 184; + } else if (yc[y][x] < 0.4f) { + nh = 185; + } else if (yc[y][x] < 0.45f) { + nh = 186; + } + } else if (xc[y][x] < 0.65f && yc[y][x] > 0.12f) { + if (yc[y][x] < 0.25f) { + nh = 187; + } else if (yc[y][x] < 0.3f) { + nh = 188; + } else if (yc[y][x] < 0.35f) { + nh = 189; + } else if (yc[y][x] < 0.45f) { + nh = 190; + } + } else if (xc[y][x] < 0.75f && yc[y][x] > 0.1f) { + nh = 191; + } + if (nh >= 0) { + histxythr[nh]++; + xxxthr[nh] += xc[y][x]; + yyythr[nh] += yc[y][x]; + YYYthr[nh] += Yc[y][x]; + } + } + } +#ifdef _OPENMP + #pragma omp critical +#endif + { + histxy += histxythr; + xxx += xxxthr; + yyy += yyythr; + YYY += YYYthr; + } + } +} + + + + static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy, bool purp) { // calculate histogram x y in a range of 236 colors @@ -4654,7 +5122,7 @@ float static studentXY(const array2D & YYcurr, const array2D & ref void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar, const ToneCurveParams &hrp) { /* - Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com, update 1 - 2023 + Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com, update 2 - 2023 Copyright (c) Ingo Weyrich 3 - 2020 (heckflosse67@gmx.de) This algorithm try to find temperature correlation between 20 to 80 colors between 201 spectral color and about 20 to 55 color found in the image between 236, I just found the idea in the web "correlate with chroma" instead of RGB grey point,but I don't use any algo found on the web. @@ -4693,7 +5161,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double 22) we re-adjust references color for these xyY from 20) 23) then find all Student correlation for each couple green / temp 24) sort these Student values, and choose the minimum - 25) then for the 3 better couple "temp / green" choose the one where green is nearest from 1. + 25) then for the 5 better couple "temp / green" choose the one where green is nearest from 1. Some variables or function are not used, keep in case of I have test with cat02 but result are not stable enough ! why ??, therefore cat02 neutralized @@ -4704,28 +5172,37 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double You can used it in images :flowers, landscape, portrait, skin, where illuminants are "normal" (daylight, blackbody) You must avoid when illuminant is non standard (fluorescent, LED...) and also, when the subject is lost in the image (some target to generate profiles). - You can change parameters in option.cc + You can change parameters in White Balance - Frame adapted to Itcwb Itcwb_thres : 34 by default ==> number of color used in final algorithm - between 10 and max 55 Itcwb_sorted : true by default, can improve algorithm if true, ==> sort value in something near chroma order, instead of histogram number Itcwb_greenrange : 0 amplitude of green variation - between 0 to 2 - Itcwb_greendeltatemp : 1 - delta temp in green iterate loop for "extra" - between 0 to 4 - Itcwb_forceextra : true by default - if true force algorithm "extra" ("extra" is used when camera wbsettings are wrong) to all images - Itcwb_sizereference : 3 by default, can be set to 5 ==> size of reference color compare to size of histogram real color + Itcwb_greendelta : 1 - delta temp in green iterate loop for "extra" - between 0 to 4 + Itcwb_forceextra : false by default - Use all Ciexy diagram instead of sRGB + //Itcwb_sizereference : repalce by int maxnb 3 by default, can be set to 5 ==> size of reference color compare to size of histogram real color itcwb_delta : 1 by default can be set between 0 to 5 ==> delta temp to build histogram xy - if camera temp is not probably good - itcwb_stdobserver10 : true by default - use standard observer 10°, false = standard observer 2° - itcwb_precis : 3 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file + //itcwb_precis : replace by int precision = 3 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file itcwb_nopurple : true default - allow to bypass highlight recovery and inpait opposed when need flowers and not purple due to highlights... + itcwb_fgreen : 5 by default - between 3 to 6 - find the compromise student / green to reach green near of 1 + + In file options. + use standard observer 10°, false = standard observer 2° */ // BENCHFUN - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix("sRGB"); + Glib::ustring profuse; + profuse = "sRGB";//or "Adobe RGB" + if( wbpar.itcwb_forceextra && wbpar.itcwb_sampling == false) {//Adobe RGB + profuse = "ACESp0";//cover all CIE xy diagram + } + + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(profuse); //ACESp0 or sRGB const float wp[3][3] = { {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} }; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix("sRGB"); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(profuse);//ACESp0 or sRGB //inverse matrix user select const float wip[3][3] = { {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, @@ -4766,7 +5243,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {0.680, 1.f}, {0.690, 1.f}, {0.700, 1.f}, - {0.714, 1.f},//usual range + {0.714, 1.f},//usual 2 range {0.727, 1.f}, {0.741, 1.f}, {0.755, 1.f}, @@ -4775,7 +5252,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {0.800, 1.f}, {0.806, 1.f}, {0.813, 1.f}, - {0.820, 1.f}, + {0.820, 1.f},//usual range {0.826, 1.f}, {0.833, 1.f}, {0.840, 1.f}, @@ -4822,13 +5299,13 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double {1.220, 1.f}, {1.230, 1.f}, {1.240, 1.f}, - {1.250, 1.f}, + {1.250, 1.f},// usual range {1.275, 1.f}, {1.300, 1.f}, {1.325, 1.f}, {1.350, 1.f}, {1.375, 1.f}, - {1.400, 1.f},//usual range + {1.400, 1.f},//usual 2 range {1.425, 1.f}, {1.450, 1.f}, {1.475, 1.f}, @@ -4884,20 +5361,25 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double int end; } RangeGreen; - constexpr RangeGreen Rangestandard = {24, 86};//usual green range + constexpr RangeGreen Rangestandard = {33, 80};//usual green range + constexpr RangeGreen Rangestandard2 = {24, 86};//usual 2 green range constexpr RangeGreen Rangeextended = {15, 93}; const RangeGreen Rangemax = {0, N_g}; RangeGreen Rangegreenused; - if (settings->itcwb_greenrange == 0) { + if (wbpar.itcwb_rgreen == 0) { Rangegreenused = Rangestandard; - } else if (settings->itcwb_greenrange == 1) { + } else if (wbpar.itcwb_rgreen == 1) { + Rangegreenused = Rangestandard2; + } else if (wbpar.itcwb_rgreen == 2) { Rangegreenused = Rangeextended; } else { Rangegreenused = Rangemax; } - + if(wbpar.itcwb_sampling == true) { + Rangegreenused = Rangestandard2; + } typedef struct WbTxyz { double Tem; double XX; @@ -5044,8 +5526,10 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double float gmm[N_t]; float bmm[N_t]; - constexpr int siza = 237; //192 untill 01/2023 size of histogram - + int siza = 237; //192 untill 01/2023 size of histogram + if(wbpar.itcwb_sampling == true) { + siza = 192;//old sampling 5.9 and before... + } // tempref and greenref are camera wb values. // I used them by default to select good spectral values !! but they are changed after tempref = rtengine::min(tempref, 12000.0); @@ -5062,12 +5546,12 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double //calculate R G B multiplier in function illuminant and temperature const bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); - for (int tt = 0; tt < N_t; ++tt) { double r, g, b; float rm, gm, bm; - ColorTemp WBiter = ColorTemp(Txyz[tt].Tem, greenitc, 1.f, "Custom"); + ColorTemp WBiter = ColorTemp(Txyz[tt].Tem, greenitc, 1.f, "Custom", wbpar.observer); WBiter.getMultipliers(r, g, b); + rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; @@ -5151,7 +5635,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double array2D yc(bfwitc, bfhitc); array2D Yc(bfwitc, bfhitc); - const int deltarepref = settings->itcwb_delta; + const int deltarepref = 1; //settings->itcwb_delta; for (int nn = 0, drep = -deltarepref; nn <= 2; ++nn, drep += deltarepref) { //three loop to refine color if temp camera is probably not very good @@ -5167,7 +5651,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double const float RR = rmm[rep] * redloc[y][x]; const float GG = gmm[rep] * greenloc[y][x]; const float BB = bmm[rep] * blueloc[y][x]; - Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wp); + Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wp);//use sRGB or ACESp0 } } @@ -5182,12 +5666,18 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double bool purp = true;//if inpaint-opposed or something else enable purp - if (hrp.hrenabled && hrp.method == "Coloropp" && settings->itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) + // if (hrp.hrenabled && hrp.method == "Coloropp" && settings->itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) + if (hrp.hrenabled && hrp.method == "Coloropp" && wbpar.itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) purp = false; } - - histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB - //return histogram x and y for each temp and in a range of 235 colors (siza) + if(wbpar.itcwb_sampling == false) { + //printf("Use high smapling\n"); + histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB + //return histogram x and y for each temp and in a range of 235 colors (siza) + } else { + //printf("Use low smapling - 5.9\n"); + histoxyY_low(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy);//low scaling + } } // free some memory @@ -5255,7 +5745,11 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double int sizcurr2ref = sizcurrref - ntr; const int sizcu30 = sizcurrref - n30; - const int sizcu4 = rtengine::min(sizcu30, 55);// + int nbm = 77;//number max of color used = 1.4 * 55 in case all CIExy diagram + if(profuse == "sRGB" || wbpar.itcwb_sampling == true) { + nbm = 55; + } + const int sizcu4 = rtengine::min(sizcu30, nbm);//size of chroma values if (settings->verbose) { printf("ntr=%i sizcurr2ref=%i sizcu30=%i sizcu4=%i\n", ntr, sizcurr2ref, sizcu30, sizcu4); @@ -5292,12 +5786,21 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double if (settings->verbose) { printf("estimchrom=%f\n", estimchrom); } + bool issorted = wbpar.itcwb_sorted; - if (settings->itcwb_sorted) { //sort in ascending with chroma values + if(wbpar.itcwb_sampling == true) { + issorted = false; + } + + + if (issorted) { //sort in ascending with chroma values std::sort(wbchro, wbchro + sizcu4, wbchro[0]); } - const int maxval = rtengine::LIM(settings->itcwb_thres, 10, 55);//max values of color to find correlation + int maxval = rtengine::LIM(wbpar.itcwb_thres, 10, 55);//max values of color to find correlation + if(wbpar.itcwb_sampling == true) { + maxval = 34; + } sizcurr2ref = rtengine::min(sizcurr2ref, maxval); //keep about the biggest values, @@ -5312,10 +5815,13 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } //calculate deltaE xx to find best values of spectrals data - limited to chroma values - int maxnb = rtengine::LIM(settings->itcwb_sizereference, 1, 5); + // int maxnb = rtengine::LIM(settings->itcwb_sizereference, 1, 5); + // int maxnb = rtengine::LIM(wbpar.itcwb_size, 1, 5); + int maxnb = 3; + //wbpar.itcwb_size to verify if this setting is usefull...diificulties with High gamut and limited patch spectral colors. - if (settings->itcwb_thres > 55) { - maxnb = 201 / settings->itcwb_thres; + if (wbpar.itcwb_thres > 55) {//normally never used + maxnb = 201 / wbpar.itcwb_thres; } for (int nb = 1; nb <= maxnb; ++nb) { //max 5 iterations for Itcwb_thres=33, after trial 3 is good in most cases but in some cases 5 @@ -5423,10 +5929,12 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double Tgstud[i].student = 1000.f;//max value to initialize Tgstud[i].tempref = 57;//5002K position in the list Tgstud[i].greenref = 55;// 1.f position in the list - } - const int dgoodref = rtengine::min(settings->itcwb_greendeltatemp, 4); + int dgoodref = rtengine::LIM(wbpar.itcwb_delta,1, 4); + if(wbpar.itcwb_sampling == true) { + dgoodref = 2; + } const int scantempbeg = rtengine::max(goodref - (dgoodref + 1), 1); const int scantempend = rtengine::min(goodref + dgoodref, N_t - 1); @@ -5436,7 +5944,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double for (int tt = scantempbeg; tt < scantempend; ++tt) { double r, g, b; - ColorTemp WBiter(Txyz[tt].Tem, gree[gr].green, 1.f, "Custom"); + ColorTemp WBiter(Txyz[tt].Tem, gree[gr].green, 1.f, "Custom", wbpar.observer); WBiter.getMultipliers(r, g, b); float rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; float gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; @@ -5508,7 +6016,12 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double // perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% int greengood = 55; - int maxkgood = 5;//we can change ...to test 3, 4, 5. High values perhaps less good student, but it is a compromise... + int maxkgood = wbpar.itcwb_fgreen;//we can change ...to test 3, 4, 5. High values perhaps less good student, but it is a compromise... + maxkgood = rtengine::LIM(maxkgood, 3, 6); + if(wbpar.itcwb_sampling == true) { + maxkgood = 3; // force to 3 with old low sampling + } + int mingood = std::min(std::fabs(Tgstud[0].greenref - 55), std::fabs(Tgstud[1].greenref - 55)); for (int k = 2; k < maxkgood; ++k) { @@ -5558,14 +6071,11 @@ void RawImageSource::WBauto(double & tempref, double & greenref, array2D //put green (tint) in reasonable limits for an Daylight illuminant // avoid too bi or too low values if (wbpar.method == "autitcgreen") { - bool extra = false; + bool extra = true; if (greenref > 0.5 && greenref < 1.3) {// 0.5 and 1.3 arbitraties values greenitc = greenref; - if (settings->itcwb_forceextra) { - extra = true; - } } else { greenitc = 1.; extra = true; @@ -5576,22 +6086,16 @@ void RawImageSource::WBauto(double & tempref, double & greenref, array2D } } -void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) +void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const WBParams & wbpar) { // BENCHFUN //used by auto WB local to calculate red, green, blue in local region - int precision = 5; - - if (settings->itcwb_precis == 5) { + int precision = 3;//must be 3 5 or 9 + if(wbpar.itcwb_sampling == true) { precision = 5; - } else if (settings->itcwb_precis < 5) { - precision = 3; - } else if (settings->itcwb_precis > 5) { - precision = 9; } - 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); @@ -5851,14 +6355,9 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref if (wbpar.method == "autitcgreen") { bool twotimes = false; - int precision = 5; - - if (settings->itcwb_precis == 5) { + int precision = 3;//must be 3 5 or 9 + if(wbpar.itcwb_sampling == true) { precision = 5; - } else if (settings->itcwb_precis < 5) { - precision = 3; - } else if (settings->itcwb_precis > 5) { - precision = 9; } const int bfw = W / precision + ((W % precision) > 0 ? 1 : 0);// 5 arbitrary value can be change to 3 or 9 ; @@ -6106,7 +6605,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) blueAWBMul = bm = imatrices.rgb_cam[2][0] * reds + imatrices.rgb_cam[2][1] * greens + imatrices.rgb_cam[2][2] * blues; } -ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) +ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) { int x; @@ -6314,7 +6813,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &rawData); // raw for cblack void WBauto(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 &studgood, 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; void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; - void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) 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 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, int opposed) override; @@ -154,7 +154,7 @@ public: return camera_wb; } void getAutoWBMultipliers (double &rm, double &gm, double &bm) override; - ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) override; + ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) override; bool isWBProviderReady () override { return rawData; @@ -186,7 +186,7 @@ public: } void getAutoExpHistogram (LUTu & histogram, int& histcompr) override; void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override; - void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, std::vector &outCurve) override; + void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, StandardObserver observer, std::vector &outCurve) override; DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override; void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 989ca3354..f86950457 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -472,7 +472,7 @@ class AutoWBListener { public: virtual ~AutoWBListener() = default; - virtual void WBChanged(double temp, double green, float studgood) = 0; + virtual void WBChanged(double temp, double green, double rw, double gw, double bw, float studgood) = 0; }; class FrameCountListener @@ -619,8 +619,8 @@ public: * @return a pointer to the Crop object that handles the image data trough its own pipeline */ virtual DetailedCrop* createCrop (::EditDataProvider *editDataProvider, bool isDetailWindow) = 0; - virtual bool getAutoWB (double& temp, double& green, double equal, double tempBias) = 0; - virtual void getCamWB (double& temp, double& green) = 0; + virtual bool getAutoWB (double& temp, double& green, double equal, StandardObserver observer, double tempBias) = 0; + virtual void getCamWB (double& temp, double& green, StandardObserver observer) = 0; virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) = 0; virtual bool getFilmNegativeSpot(int x, int y, int spotSize, procparams::FilmNegativeParams::RGB &refInput, procparams::FilmNegativeParams::RGB &refOutput) = 0; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 84c33a734..11dae8018 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -194,7 +194,7 @@ namespace rtengine using namespace procparams; -Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode) +Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool inspectorMode) { StdImageSource imgSrc; @@ -310,8 +310,9 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, tpp->blueAWBMul = avg_b / double (n); tpp->wbEqual = wbEq; tpp->wbTempBias = 0.0; + tpp->wbObserver = wbObserver; - cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); + cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->wbObserver, tpp->autoWBTemp, tpp->autoWBGreen); } tpp->init (); @@ -543,7 +544,7 @@ RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname) return rml; } -Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching) +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching) { RawImage *ri = new RawImage (fname); unsigned int tempImageNum = 0; @@ -982,9 +983,10 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->blueAWBMul = ri->get_rgb_cam (2, 0) * reds + ri->get_rgb_cam (2, 1) * greens + ri->get_rgb_cam (2, 2) * blues; tpp->wbEqual = wbEq; tpp->wbTempBias = 0.0; + tpp->wbObserver = wbObserver; ColorTemp cTemp; - cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); + cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->wbObserver, tpp->autoWBTemp, tpp->autoWBGreen); } if (rotate && ri->get_rotateDegree() > 0) { @@ -1121,18 +1123,19 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT float iso = metadata->getISOSpeed(imgNum); float fcomp = metadata->getExpComp(imgNum); - // check if the WB's equalizer value has changed - if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4) || wbTempBias < (params.wb.tempBias - 5e-4) || wbTempBias > (params.wb.tempBias + 5e-4)) { + // check if the WB's equalizer, temperature bias, or observer value has changed + if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4) || wbTempBias < (params.wb.tempBias - 5e-4) || wbTempBias > (params.wb.tempBias + 5e-4) || wbObserver != params.wb.observer) { wbEqual = params.wb.equal; wbTempBias = params.wb.tempBias; + wbObserver = params.wb.observer; // recompute the autoWB ColorTemp cTemp; - cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen); + cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, wbObserver, autoWBTemp, autoWBGreen); autoWBTemp += autoWBTemp * wbTempBias; } // compute WB multipliers - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method, params.wb.observer); if (!params.wb.enabled) { currWB = ColorTemp(); @@ -1141,9 +1144,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT double cam_r = colorMatrix[0][0] * camwbRed + colorMatrix[0][1] * camwbGreen + colorMatrix[0][2] * camwbBlue; double cam_g = colorMatrix[1][0] * camwbRed + colorMatrix[1][1] * camwbGreen + colorMatrix[1][2] * camwbBlue; double cam_b = colorMatrix[2][0] * camwbRed + colorMatrix[2][1] * camwbGreen + colorMatrix[2][2] * camwbBlue; - currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal); + 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"); + currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom", wbObserver); } double rm, gm, bm; @@ -1588,27 +1591,28 @@ void Thumbnail::getDimensions (int& w, int& h, double& scaleFac) } } -void Thumbnail::getCamWB (double& temp, double& green) +void Thumbnail::getCamWB (double& temp, double& green, StandardObserver observer) { double cam_r = colorMatrix[0][0] * camwbRed + colorMatrix[0][1] * camwbGreen + colorMatrix[0][2] * camwbBlue; double cam_g = colorMatrix[1][0] * camwbRed + colorMatrix[1][1] * camwbGreen + colorMatrix[1][2] * camwbBlue; double cam_b = colorMatrix[2][0] * camwbRed + colorMatrix[2][1] * camwbGreen + colorMatrix[2][2] * camwbBlue; - ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b, 1.0); // we do not take the equalizer into account here, because we want camera's WB + ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b, 1.0, observer); // we do not take the equalizer into account here, because we want camera's WB temp = currWB.getTemp (); green = currWB.getGreen (); } -void Thumbnail::getAutoWB (double& temp, double& green, double equal, double tempBias) +void Thumbnail::getAutoWB (double& temp, double& green, double equal, double tempBias, StandardObserver observer) { - if (equal != wbEqual || tempBias != wbTempBias) { + if (equal != wbEqual || tempBias != wbTempBias || observer != wbObserver) { // compute the values depending on equal ColorTemp cTemp; wbEqual = equal; wbTempBias = tempBias; + wbObserver = observer; // compute autoWBTemp and autoWBGreen - cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen); + cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, wbObserver, autoWBTemp, autoWBGreen); autoWBTemp += autoWBTemp * tempBias; } @@ -1665,7 +1669,7 @@ void Thumbnail::getSpotWB (const procparams::ProcParams& params, int xp, int yp, double gm = colorMatrix[1][0] * reds + colorMatrix[1][1] * greens + colorMatrix[1][2] * blues; double bm = colorMatrix[2][0] * reds + colorMatrix[2][1] * greens + colorMatrix[2][2] * blues; - ColorTemp ct (rm, gm, bm, params.wb.equal); + ColorTemp ct (rm, gm, bm, params.wb.equal, params.wb.observer); rtemp = ct.getTemp (); rgreen = ct.getGreen (); } diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 6ec1dfb34..535613ca2 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -38,6 +38,8 @@ class ustring; namespace rtengine { +enum class StandardObserver; + class Thumbnail { @@ -55,6 +57,7 @@ class Thumbnail double camwbBlue; double redAWBMul, greenAWBMul, blueAWBMul; // multipliers for auto WB double autoWBTemp, autoWBGreen, wbEqual, wbTempBias; // autoWBTemp and autoWBGreen are updated each time autoWB is requested and if wbEqual has been modified + StandardObserver wbObserver; LUTu aeHistogram; int aeHistCompression; bool aeValid; @@ -95,12 +98,12 @@ public: void getDimensions (int& w, int& h, double& scaleFac); static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false); - static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false); - static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); + static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching = false); + static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool inspectorMode = false); static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname); - void getCamWB (double& temp, double& green); - void getAutoWB (double& temp, double& green, double equal, double tempBias); + void getCamWB (double& temp, double& green, StandardObserver observer); + void getAutoWB (double& temp, double& green, double equal, double tempBias, StandardObserver observer); void getAutoWBMultipliers (double& rm, double& gm, double& bm); void getSpotWB (const procparams::ProcParams& params, int x, int y, int rect, double& temp, double& green); void applyAutoExp (procparams::ProcParams& pparams); diff --git a/rtengine/settings.h b/rtengine/settings.h index 6e787a112..e831fa1a4 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -44,7 +44,6 @@ public: bool monitorBPC; ///< Black Point Compensation for the Labimage->Monitor transform (directly, i.e. not soft-proofing and no WCS in between) bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; - bool observer10; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode bool verbose; Glib::ustring darkFramesPath; ///< The default directory for dark frames @@ -93,17 +92,7 @@ public: int previewselection; double cbdlsensi; // bool showtooltip; - - int itcwb_thres; - bool itcwb_sorted; - int itcwb_greenrange; - int itcwb_greendeltatemp; - bool itcwb_forceextra; - int itcwb_sizereference; - int itcwb_delta; - bool itcwb_stdobserver10; - int itcwb_precis; - bool itcwb_nopurple; + bool itcwb_enable; //wavelet levels double edghi; double edglo; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5de3b08b0..78dd84042 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -269,7 +269,7 @@ private: } // set the color temperature - currWB = ColorTemp(params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + currWB = ColorTemp(params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method, params.wb.observer); if (!params.wb.enabled) { currWB = ColorTemp(); @@ -278,7 +278,7 @@ private: } else if (params.wb.method == "autold") { double rm, gm, bm; imgsrc->getAutoWBMultipliers(rm, gm, bm); - currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); + currWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); } calclum = nullptr ; @@ -781,7 +781,7 @@ private: if (params.toneCurve.histmatching) { if (!params.toneCurve.fromHistMatching) { - imgsrc->getAutoMatchedToneCurve(params.icm, params.toneCurve.curve); + imgsrc->getAutoMatchedToneCurve(params.icm, params.wb.observer, params.toneCurve.curve); } if (params.toneCurve.autoexp) { diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index a3f2502f0..411b1de32 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -187,7 +187,7 @@ int StdImageSource::load (const Glib::ustring &fname) plistener->setProgress (1.0); } - wb = ColorTemp (1.0, 1.0, 1.0, 1.0); + wb = ColorTemp (1.0, 1.0, 1.0, 1.0, ColorTemp::DEFAULT_OBSERVER); //this is probably a mistake if embedded profile is not D65 return 0; @@ -348,7 +348,7 @@ void StdImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) blueAWBMul = bm; } -ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector& blue, int tran, double equal) +ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector& blue, int tran, double equal, StandardObserver observer) { int rn, gn, bn; double reds, greens, blues; @@ -360,7 +360,7 @@ ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector& 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, int opposed) override; - void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) 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; } void getAutoWBMultipliers (double &rm, double &gm, double &bm) override; - ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) override; + ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) override; void WBauto(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 &studgood, 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; void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 9e74ddb90..58532f68a 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -586,19 +586,19 @@ void BatchToolPanelCoordinator::unsetTweakOperator (rtengine::TweakOperator *tOp { } -void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green, double equal, double tempBias) +void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias) { if (!selected.empty()) { - selected[0]->getAutoWB (temp, green, equal, tempBias); + selected[0]->getAutoWB (temp, green, equal, observer, tempBias); } } -void BatchToolPanelCoordinator::getCamWB (double& temp, double& green) +void BatchToolPanelCoordinator::getCamWB (double& temp, double& green, rtengine::StandardObserver observer) { if (!selected.empty()) { - selected[0]->getCamWB (temp, green); + selected[0]->getCamWB (temp, green, observer); } } diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h index 0009724e8..f421793ac 100644 --- a/rtgui/batchtoolpanelcoord.h +++ b/rtgui/batchtoolpanelcoord.h @@ -69,8 +69,8 @@ public: ) override; // wbprovider interface - void getAutoWB (double& temp, double& green, double equal, double tempBias) override; - void getCamWB (double& temp, double& green) override; + void getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias) override; + void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) override; // thumbnaillistener interface void procParamsChanged (Thumbnail* thm, int whoChangedIt) override; diff --git a/rtgui/checkbox.cc b/rtgui/checkbox.cc index e05ba061a..265123b23 100644 --- a/rtgui/checkbox.cc +++ b/rtgui/checkbox.cc @@ -80,7 +80,7 @@ void CheckBox::setValue (CheckValue newValue) break; case CheckValue::off: set_inconsistent (false); - set_active(true); + set_active(false); lastActive = false; break; case CheckValue::unchanged: diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 292fa98ae..4f1ae9311 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -33,6 +33,12 @@ const Glib::ustring FilmNegative::TOOL_NAME = "filmnegative"; namespace { +/** + * Observer to use for displaying the temperature and tint equivalent of the + * multipliers. + */ +constexpr rtengine::StandardObserver standard_observer = rtengine::ColorTemp::DEFAULT_OBSERVER; + double toAdjuster(double v) { return CLAMP(std::log2(v), 6, 16) - 6; @@ -154,7 +160,7 @@ RGB getFilmNegativeExponents(const RGB &ref1, const RGB &ref2) // , const RGB &c void temp2rgb(double outLev, double temp, double green, RGB &refOut) { - rtengine::ColorTemp ct = rtengine::ColorTemp(temp, green, 1., "Custom"); + rtengine::ColorTemp ct = rtengine::ColorTemp(temp, green, 1., "Custom", standard_observer); double rm, gm, bm; ct.getMultipliers(rm, gm, bm); @@ -175,7 +181,8 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) refOut.r / maxVal, refOut.g / maxVal, refOut.b / maxVal, - 1.); + 1., + standard_observer); outLev = maxVal; temp = ct.getTemp(); @@ -188,7 +195,7 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) FilmNegative::FilmNegative() : FoldableToolPanel(this, TOOL_NAME, M("TP_FILMNEGATIVE_LABEL"), false, true), EditSubscriber(ET_OBJECTS), - NEUTRAL_TEMP(rtengine::ColorTemp(1., 1., 1., 1.)), + NEUTRAL_TEMP(rtengine::ColorTemp(1., 1., 1., 1., rtengine::ColorTemp::DEFAULT_OBSERVER)), evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(ALLNORAW, "HISTORY_MSG_FILMNEGATIVE_VALUES")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(ALLNORAW, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), evFilmNegativeRefSpot(ProcEventMapper::getInstance()->newEvent(ALLNORAW, "HISTORY_MSG_FILMNEGATIVE_REF_SPOT")), diff --git a/rtgui/options.cc b/rtgui/options.cc index e230dcf8a..7d823eda4 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -595,7 +595,6 @@ void Options::setDefaults() rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.monitorBPC = true; rtSettings.autocielab = false; - rtSettings.observer10 = false; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RTv2_Medium"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RTv2_Large"; // these names appear in the menu "output profile" @@ -623,18 +622,8 @@ 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.itcwb_thres = 34;//between 10 to 55 - rtSettings.itcwb_sorted = true; - rtSettings.itcwb_greenrange = 0;//between 0 to 2 - rtSettings.itcwb_greendeltatemp = 2;//between 0 and 4 - rtSettings.itcwb_forceextra = true; - rtSettings.itcwb_sizereference = 3;//between 1 and 5 - rtSettings.itcwb_delta = 1;//between 0 and 5 - rtSettings.itcwb_stdobserver10 = true; - rtSettings.itcwb_precis = 3;//3 or 5 or 9 - rtSettings.itcwb_nopurple = true; // end locallab + rtSettings.itcwb_enable = true; //wavelet rtSettings.edghi = 3.0;//1.1 and 5. @@ -1767,10 +1756,6 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.autocielab = keyFile.get_boolean("Color Management", "Autocielab"); } - if (keyFile.has_key("Color Management", "Observer10")) { - rtSettings.observer10 = keyFile.get_boolean("Color Management", "Observer10"); - } - if (keyFile.has_key("Color Management", "CRI")) { rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); } @@ -1802,45 +1787,10 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.level123_cbdl = keyFile.get_double("Color Management", "CBDLlevel123"); } - if (keyFile.has_key("Color Management", "Itcwb_thres")) { - rtSettings.itcwb_thres = keyFile.get_integer("Color Management", "Itcwb_thres"); + if (keyFile.has_key("Color Management", "Itcwb_enable")) { + rtSettings.itcwb_enable = keyFile.get_boolean("Color Management", "Itcwb_enable"); } - if (keyFile.has_key("Color Management", "Itcwb_sorted")) { - rtSettings.itcwb_sorted = keyFile.get_boolean("Color Management", "Itcwb_sorted"); - } - - if (keyFile.has_key("Color Management", "Itcwb_forceextra")) { - rtSettings.itcwb_forceextra = keyFile.get_boolean("Color Management", "Itcwb_forceextra"); - } - - if (keyFile.has_key("Color Management", "Itcwb_nopurple")) { - rtSettings.itcwb_nopurple = keyFile.get_boolean("Color Management", "Itcwb_nopurple"); - } - - if (keyFile.has_key("Color Management", "Itcwb_stdobserver10")) { - rtSettings.itcwb_stdobserver10 = keyFile.get_boolean("Color Management", "Itcwb_stdobserver10"); - } - - if (keyFile.has_key("Color Management", "Itcwb_greenrange")) { - rtSettings.itcwb_greenrange = keyFile.get_integer("Color Management", "Itcwb_greenrange"); - } - - if (keyFile.has_key("Color Management", "Itcwb_greendeltatemp")) { - rtSettings.itcwb_greendeltatemp = keyFile.get_integer("Color Management", "Itcwb_greendeltatemp"); - } - - if (keyFile.has_key("Color Management", "Itcwb_sizereference")) { - rtSettings.itcwb_sizereference = keyFile.get_integer("Color Management", "Itcwb_sizereference"); - } - - if (keyFile.has_key("Color Management", "Itcwb_delta")) { - rtSettings.itcwb_delta = keyFile.get_integer("Color Management", "Itcwb_delta"); - } - - if (keyFile.has_key("Color Management", "Itcwb_precis")) { - rtSettings.itcwb_precis = keyFile.get_integer("Color Management", "Itcwb_precis"); - } //if (keyFile.has_key ("Color Management", "Colortoningab")) rtSettings.colortoningab = keyFile.get_double("Color Management", "Colortoningab"); //if (keyFile.has_key ("Color Management", "Decaction")) rtSettings.decaction = keyFile.get_double("Color Management", "Decaction"); @@ -2579,7 +2529,6 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Color Management", "MonitorProfile", rtSettings.monitorProfile); keyFile.set_boolean("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean("Color Management", "Autocielab", rtSettings.autocielab); - keyFile.set_boolean("Color Management", "Observer10", rtSettings.observer10); keyFile.set_boolean("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); keyFile.set_integer("Color Management", "Intent", rtSettings.monitorIntent); keyFile.set_boolean("Color Management", "MonitorBPC", rtSettings.monitorBPC); @@ -2612,16 +2561,7 @@ void Options::saveToFile(Glib::ustring fname) //keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); keyFile.set_double("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); keyFile.set_double("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); - keyFile.set_integer("Color Management", "Itcwb_thres", rtSettings.itcwb_thres); - keyFile.set_boolean("Color Management", "Itcwb_sorted", rtSettings.itcwb_sorted); - keyFile.set_integer("Color Management", "Itcwb_greenrange", rtSettings.itcwb_greenrange); - keyFile.set_integer("Color Management", "Itcwb_greendeltatemp", rtSettings.itcwb_greendeltatemp); - keyFile.set_boolean("Color Management", "Itcwb_forceextra", rtSettings.itcwb_forceextra); - keyFile.set_boolean("Color Management", "Itcwb_nopurple", rtSettings.itcwb_nopurple); - keyFile.set_integer("Color Management", "Itcwb_sizereference", rtSettings.itcwb_sizereference); - keyFile.set_integer("Color Management", "Itcwb_delta", rtSettings.itcwb_delta); - keyFile.set_boolean("Color Management", "Itcwb_stdobserver10", rtSettings.itcwb_stdobserver10); - keyFile.set_integer("Color Management", "Itcwb_precis", rtSettings.itcwb_precis); + keyFile.set_boolean("Color Management", "Itcwb_enable", rtSettings.itcwb_enable); //keyFile.set_double ("Color Management", "Colortoningab", rtSettings.colortoningab); //keyFile.set_double ("Color Management", "Decaction", rtSettings.decaction); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index abd4e8608..c3638cc5f 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -266,6 +266,17 @@ void ParamsEdited::set(bool v) wb.temperature = v; wb.equal = v; wb.tempBias = v; + wb.observer = v; + wb.itcwb_thres = v; + wb.itcwb_precis = v; + wb.itcwb_size = v; + wb.itcwb_delta = v; + wb.itcwb_fgreen = v; + wb.itcwb_rgreen = v; + wb.itcwb_nopurple = v; + wb.itcwb_sorted = v; + wb.itcwb_forceextra = v; + wb.itcwb_sampling = v; //colorShift.a = v; //colorShift.b = v; //lumaDenoise.enabled = v; @@ -967,6 +978,17 @@ void ParamsEdited::initFrom(const std::vector& wb.equal = wb.equal && p.wb.equal == other.wb.equal; wb.temperature = wb.temperature && p.wb.temperature == other.wb.temperature; wb.tempBias = wb.tempBias && p.wb.tempBias == other.wb.tempBias; + wb.observer = wb.observer && p.wb.observer == other.wb.observer; + wb.itcwb_thres = wb.itcwb_thres && p.wb.itcwb_thres == other.wb.itcwb_thres; + wb.itcwb_precis = wb.itcwb_precis && p.wb.itcwb_precis == other.wb.itcwb_precis; + wb.itcwb_size = wb.itcwb_size && p.wb.itcwb_size == other.wb.itcwb_size; + wb.itcwb_delta = wb.itcwb_delta && p.wb.itcwb_delta == other.wb.itcwb_delta; + wb.itcwb_fgreen = wb.itcwb_fgreen && p.wb.itcwb_fgreen == other.wb.itcwb_fgreen; + wb.itcwb_rgreen = wb.itcwb_rgreen && p.wb.itcwb_rgreen == other.wb.itcwb_rgreen; + wb.itcwb_nopurple = wb.itcwb_nopurple && p.wb.itcwb_nopurple == other.wb.itcwb_nopurple; + wb.itcwb_sorted = wb.itcwb_sorted && p.wb.itcwb_sorted == other.wb.itcwb_sorted; + wb.itcwb_forceextra = wb.itcwb_forceextra && p.wb.itcwb_forceextra == other.wb.itcwb_forceextra; + wb.itcwb_sampling = wb.itcwb_sampling && p.wb.itcwb_sampling == other.wb.itcwb_sampling; //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; @@ -2829,6 +2851,50 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wb.tempBias = dontforceSet && options.baBehav[ADDSET_WB_TEMPBIAS] ? toEdit.wb.tempBias + mods.wb.tempBias : mods.wb.tempBias; } + if (wb.observer) { + toEdit.wb.observer = mods.wb.observer; + } + + if (wb.itcwb_thres) { + toEdit.wb.itcwb_thres = mods.wb.itcwb_thres; + } + + if (wb.itcwb_precis) { + toEdit.wb.itcwb_precis = mods.wb.itcwb_precis; + } + + if (wb.itcwb_size) { + toEdit.wb.itcwb_size = mods.wb.itcwb_size; + } + + if (wb.itcwb_delta) { + toEdit.wb.itcwb_delta = mods.wb.itcwb_delta; + } + + if (wb.itcwb_fgreen) { + toEdit.wb.itcwb_fgreen = mods.wb.itcwb_fgreen; + } + + if (wb.itcwb_rgreen) { + toEdit.wb.itcwb_rgreen = mods.wb.itcwb_rgreen; + } + + if (wb.itcwb_nopurple) { + toEdit.wb.itcwb_nopurple = mods.wb.itcwb_nopurple; + } + + if (wb.itcwb_sorted) { + toEdit.wb.itcwb_sorted = mods.wb.itcwb_sorted; + } + + if (wb.itcwb_forceextra) { + toEdit.wb.itcwb_forceextra = mods.wb.itcwb_forceextra; + } + + if (wb.itcwb_sampling) { + toEdit.wb.itcwb_sampling = mods.wb.itcwb_sampling; + } + if (wb.green) { toEdit.wb.green = dontforceSet && options.baBehav[ADDSET_WB_GREEN] ? toEdit.wb.green + mods.wb.green : mods.wb.green; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 66db8346f..d85bec701 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -246,7 +246,19 @@ struct WBParamsEdited { bool temperature; bool green; bool equal; + bool observer; bool tempBias; + bool itcwb_thres; + bool itcwb_precis; + bool itcwb_size; + bool itcwb_delta; + bool itcwb_fgreen; + bool itcwb_rgreen; + bool itcwb_nopurple; + bool itcwb_sorted; + bool itcwb_forceextra; + bool itcwb_sampling; + }; struct DefringeParamsEdited { diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index 162e63f9e..f2455699c 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 349 +#define PPVERSION 350 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 350 2023-03-05 + introduced white balance standard observer 349 2020-10-29 replaced Haze removal Luminance checkbox with an adjuster to blend between luminance and normal mode 348 2018-09-25 diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index b04bee237..8c3290e5c 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -928,6 +928,10 @@ Gtk::Widget* Preferences::getColorManPanel () fcie->add(*gcie); vbColorMan->pack_start (*fcie, Gtk::PACK_SHRINK); + + + //------------- + swColorMan->add(*vbColorMan); return swColorMan; } @@ -1954,6 +1958,7 @@ void Preferences::fillPreferences() monBPC->set_active(moptions.rtSettings.monitorBPC); mcie->set_active(moptions.rtSettings.autocielab); + cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 90ea20da7..039c4d58a 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -135,6 +135,15 @@ class Preferences final : Gtk::CheckButton* cbdaubech; Gtk::SpinButton* hlThresh; Gtk::SpinButton* shThresh; +// Gtk::CheckButton* mwbacorr; + // Gtk::CheckButton* mwbaforc; + // Gtk::CheckButton* mwbanopurp; + +// Gtk::CheckButton* mwbasort; +// Gtk::SpinButton* wbacorrnb; +// Gtk::SpinButton* wbaprecis; +// Gtk::SpinButton* wbasizeref; +// Gtk::SpinButton* wbagreendelta; Gtk::SpinButton* panFactor; Gtk::CheckButton* rememberZoomPanCheckbutton; @@ -240,7 +249,7 @@ class Preferences final : Options moptions; sigc::connection tconn, sconn, fconn, cpfconn, addc, setc, dfconn, ffconn, bpconn, rpconn, ipconn; - sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn, autocielabConn; + sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn, autocielabConn, observer10Conn; Glib::ustring initialTheme; Glib::ustring initialFontFamily; int initialFontSize; @@ -305,6 +314,7 @@ public: void sndEnableToggled (); void langAutoDetectToggled (); void autocielabToggled (); + void observer10Toggled (); void selectStartupDir (); void addExtPressed (); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 30766ebc9..dd7995feb 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -139,20 +139,20 @@ void Thumbnail::_generateThumbnailImage () if (ext == "jpg" || ext == "jpeg") { infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); + 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); + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); if (tpp) { cfs.format = FT_Png; } } else if (ext == "tif" || ext == "tiff") { infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); if (tpp) { cfs.format = FT_Tiff; @@ -173,7 +173,7 @@ void Thumbnail::_generateThumbnailImage () if ( tpp == nullptr ) { quick = false; - tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams->wb.equal, TRUE); + tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE); } cfs.sensortype = sensorType; @@ -216,11 +216,11 @@ const ProcParams& Thumbnail::getProcParamsU () if (pparams->wb.method == "Camera") { double ct; - getCamWB (ct, pparams->wb.green); + getCamWB (ct, pparams->wb.green, pparams->wb.observer); pparams->wb.temperature = ct; } else if (pparams->wb.method == "autold") { double ct; - getAutoWB (ct, pparams->wb.green, pparams->wb.equal, pparams->wb.tempBias); + getAutoWB (ct, pparams->wb.green, pparams->wb.equal, pparams->wb.observer, pparams->wb.tempBias); pparams->wb.temperature = ct; } } @@ -785,10 +785,10 @@ const Glib::DateTime& Thumbnail::getDateTime () const return dateTime; } -void Thumbnail::getAutoWB (double& temp, double& green, double equal, double tempBias) +void Thumbnail::getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias) { if (cfs.redAWBMul != -1.0) { - rtengine::ColorTemp ct(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul, equal); + rtengine::ColorTemp ct(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul, equal, observer); temp = ct.getTemp(); green = ct.getGreen(); } else { @@ -1155,10 +1155,10 @@ bool Thumbnail::imageLoad(bool loading) return false; } -void Thumbnail::getCamWB(double& temp, double& green) const +void Thumbnail::getCamWB(double& temp, double& green, rtengine::StandardObserver observer) const { if (tpp) { - tpp->getCamWB (temp, green); + tpp->getCamWB (temp, green, observer); } else { temp = green = -1.0; } diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 491151028..4d0355747 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -127,8 +127,8 @@ public: const Glib::ustring& getExifString () const; const Glib::ustring& getDateTimeString () const; const Glib::DateTime& getDateTime () const; - void getCamWB (double& temp, double& green) const; - void getAutoWB (double& temp, double& green, double equal, double tempBias); + void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) const; + void getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias); void getSpotWB (int x, int y, int rect, double& temp, double& green); void applyAutoExp (rtengine::procparams::ProcParams& pparams); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 276d9654e..7542343eb 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -398,16 +398,16 @@ public: void updateShowtooltipVisibility (bool showtooltip); // wbprovider interface - void getAutoWB (double& temp, double& green, double equal, double tempBias) override + void getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias) override { if (ipc) { - ipc->getAutoWB(temp, green, equal, tempBias); + ipc->getAutoWB(temp, green, equal, observer, tempBias); } } - void getCamWB (double& temp, double& green) override + void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) override { if (ipc) { - ipc->getCamWB(temp, green); + ipc->getCamWB(temp, green, observer); } } diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h index a56d93cd3..514a71300 100644 --- a/rtgui/wbprovider.h +++ b/rtgui/wbprovider.h @@ -18,12 +18,19 @@ */ #pragma once +namespace rtengine +{ + +enum class StandardObserver; + +} + class WBProvider { public: virtual ~WBProvider() {} - virtual void getAutoWB (double& temp, double& green, double equal, double tempBias) {} - virtual void getCamWB (double& temp, double& green) {} + virtual void getAutoWB (double& temp, double& green, double equal, rtengine::StandardObserver observer, double tempBias) {} + virtual void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) {} virtual void spotWBRequested (int size) {} }; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index f6a26e335..761f2402a 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -22,6 +22,9 @@ #include "rtimage.h" #include "options.h" +#include "eventmapper.h" + +#include "../rtengine/colortemp.h" #define MINTEMP 1500 //1200 #define MAXTEMP 60000 //12000 @@ -242,6 +245,10 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC custom_equal = 1.0; } + auto m = ProcEventMapper::getInstance(); + EvWBObserver10 = m->newEvent(ALLNORAW, "HISTORY_MSG_WBALANCE_OBSERVER10"); + + //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); @@ -336,26 +343,35 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC StudLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); StudLabel->set_tooltip_text(M("TP_WBALANCE_STUDLABEL_TOOLTIP")); + mulLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + mulLabel->set_tooltip_text(M("TP_WBALANCE_MULLABEL_TOOLTIP")); + mulLabel->show(); + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, CENTERTEMP, itempL, itempR, &wbSlider2Temp, &wbTemp2Slider)); green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0, igreenL, igreenR)); equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0, iblueredL, iblueredR)); tempBias = Gtk::manage (new Adjuster(M("TP_WBALANCE_TEMPBIAS"), -0.5, 0.5, 0.01, 0.0, itempbiasL, itempbiasR)); + observer10 = Gtk::manage(new CheckBox(M("TP_WBALANCE_OBSERVER10"), multiImage)); + cache_customTemp (0); cache_customGreen (0); cache_customEqual (0); equal->set_tooltip_markup (M("TP_WBALANCE_EQBLUERED_TOOLTIP")); tempBias->set_tooltip_markup (M("TP_WBALANCE_TEMPBIAS_TOOLTIP")); + observer10->set_tooltip_text(M("TP_WBALANCE_OBSERVER10_TOOLTIP")); temp->show (); green->show (); equal->show (); tempBias->show (); - + observer10->show(); + /* Gtk::Box* boxgreen = Gtk::manage (new Gtk::Box ()); boxgreen->show (); boxgreen->pack_start(*igreenL); boxgreen->pack_start(*green); boxgreen->pack_start(*igreenR);*/ + pack_start(*mulLabel); pack_start(*StudLabel); pack_start (*temp); @@ -363,11 +379,14 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC pack_start (*green); pack_start (*equal); pack_start (*tempBias); + pack_start(*observer10); + temp->setAdjusterListener (this); green->setAdjusterListener (this); equal->setAdjusterListener (this); tempBias->setAdjusterListener (this); + observer10->setCheckBoxListener(this); spotbutton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::spotPressed) ); methconn = method->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::optChanged) ); @@ -394,6 +413,8 @@ void WhiteBalance::enabledChanged() } + + void WhiteBalance::adjusterChanged(Adjuster* a, double newval) { int tVal = (int)temp->getValue(); @@ -456,6 +477,36 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) } } +void WhiteBalance::checkBoxToggled(CheckBox* c, CheckValue newval) +{ + if (!(getEnabled() && listener)) { + return; + } + + if (c == observer10) { + // If camera WB, update the temperature and tint according to observer. + const Gtk::TreeModel::Row row = getActiveMethod(); + unsigned int methodId = findWBEntryId(row[methodColumns.colLabel], WBLT_GUI); + const WBEntry &currMethod = WBParams::getWbEntries()[methodId]; + if (row[methodColumns.colLabel] != M("GENERAL_UNCHANGED") && currMethod.type == WBEntry::Type::CAMERA && wbp) { + double ctemp, cgreen; + wbp->getCamWB(ctemp, cgreen, + observer10->getValue() == CheckValue::off + ? rtengine::StandardObserver::TWO_DEGREES + : rtengine::StandardObserver::TEN_DEGREES); + temp->setValue(temp->getAddMode() ? 0.0 : static_cast(ctemp)); + green->setValue(green->getAddMode() ? 0.0 : cgreen); + } + + listener->panelChanged( + EvWBObserver10, + c->getValue() == CheckValue::on ? M("GENERAL_ENABLED") + : c->getValue() == CheckValue::off + ? M("GENERAL_DISABLED") + : M("GENERAL_UNCHANGED")); + } +} + void WhiteBalance::optChanged () { Gtk::TreeModel::Row row = getActiveMethod(); @@ -472,6 +523,7 @@ void WhiteBalance::optChanged () return; } StudLabel->hide(); + mulLabel->show(); if (opt != row[methodColumns.colId]) { @@ -482,6 +534,7 @@ void WhiteBalance::optChanged () green->setEditedState (UnEdited); equal->setEditedState (UnEdited); tempBias->setEditedState (UnEdited); + observer10->setEdited(false); } else { unsigned int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI); const WBEntry& currMethod = WBParams::getWbEntries()[methodId]; @@ -498,7 +551,10 @@ void WhiteBalance::optChanged () case WBEntry::Type::CAMERA: if (wbp) { double ctemp, cgreen; - wbp->getCamWB (ctemp, cgreen); + wbp->getCamWB(ctemp, cgreen, + observer10->getValue() == CheckValue::off + ? rtengine::StandardObserver::TWO_DEGREES + : rtengine::StandardObserver::TEN_DEGREES); temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); green->setValue (green->getAddMode() ? 0.0 : cgreen); equal->setValue (equal->getAddMode() ? 0.0 : 1.0); @@ -507,6 +563,7 @@ void WhiteBalance::optChanged () temp->setEditedState (UnEdited); green->setEditedState (UnEdited); equal->setEditedState (UnEdited); + observer10->setEdited(false); } } @@ -517,7 +574,7 @@ void WhiteBalance::optChanged () if (batchMode) { temp->setEditedState (UnEdited); green->setEditedState (UnEdited); - // equal remain as is + // equal and observer remain as is } // Recomputing AutoWB will happen in improccoordinator.cc @@ -540,6 +597,7 @@ void WhiteBalance::optChanged () temp->setEditedState (Edited); green->setEditedState (Edited); equal->setEditedState (Edited); + observer10->setEdited(true); } break; @@ -563,6 +621,7 @@ void WhiteBalance::optChanged () temp->setEditedState (Edited); green->setEditedState (Edited); equal->setEditedState (Edited); + observer10->setEdited(true); } break; @@ -578,6 +637,7 @@ void WhiteBalance::optChanged () void WhiteBalance::spotPressed () { StudLabel->hide(); + mulLabel->show(); if (wblistener) { wblistener->spotWBRequested (getSize()); @@ -599,6 +659,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) methconn.block (true); equal->setValue (pp->wb.equal); + observer10->setValue(rtengine::StandardObserver::TEN_DEGREES == pp->wb.observer); tempBias->setValue (pp->wb.tempBias); tempBias->set_sensitive(true); @@ -608,6 +669,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) green->setEditedState (UnEdited); equal->setEditedState (pedited->wb.equal ? Edited : UnEdited); tempBias->setEditedState (pedited->wb.tempBias ? Edited : UnEdited); + observer10->setEdited(pedited->wb.observer); } if (pedited && !pedited->wb.method) { @@ -648,7 +710,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) if (wbp) { double ctemp = -1.0; double cgreen = -1.0; - wbp->getCamWB (ctemp, cgreen); + wbp->getCamWB (ctemp, cgreen, pp->wb.observer); if (ctemp != -1.0) { // Set the camera's temperature value, or 0.0 if in ADD mode @@ -720,6 +782,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) StudLabel->show(); } else { StudLabel->hide(); + mulLabel->show(); } } @@ -744,6 +807,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pedited->wb.green = green->getEditedState (); pedited->wb.equal = equal->getEditedState (); pedited->wb.tempBias = tempBias->getEditedState (); + pedited->wb.observer = observer10->getEdited(); pedited->wb.method = row[methodColumns.colLabel] != M("GENERAL_UNCHANGED"); pedited->wb.enabled = !get_inconsistent(); } @@ -759,6 +823,12 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pp->wb.temperature = temp->getIntValue (); pp->wb.green = green->getValue (); pp->wb.equal = equal->getValue (); + pp->wb.observer = + observer10->getValue() == CheckValue::on + ? rtengine::StandardObserver::TEN_DEGREES + : observer10->getValue() == CheckValue::off + ? rtengine::StandardObserver::TWO_DEGREES + : pp->wb.observer; pp->wb.tempBias = tempBias->getValue (); } @@ -771,7 +841,7 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* if (wbp && defParams->wb.method == "Camera") { double ctemp; double cgreen; - wbp->getCamWB (ctemp, cgreen); + wbp->getCamWB (ctemp, cgreen, defParams->wb.observer); // FIXME: Seems to be always -1.0, called too early? Broken! if (ctemp != -1.0) { @@ -945,14 +1015,20 @@ inline Gtk::TreeRow WhiteBalance::getActiveMethod () return *(method->get_active()); } -void WhiteBalance::WBChanged(double temperature, double greenVal, float studgood) +void WhiteBalance::WBChanged(double temperature, double greenVal, double rw, double gw, double bw, float studgood) { idle_register.add( - [this, temperature, greenVal, studgood]() -> bool + [this, temperature, greenVal, rw, gw, bw, studgood]() -> bool { disableListener(); temp->setValue(temperature); green->setValue(greenVal); + mulLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_MULLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(4), rw), + Glib::ustring::format(std::fixed, std::setprecision(2), gw), + Glib::ustring::format(std::fixed, std::setprecision(4), bw)) + ); StudLabel->set_text( Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL"), Glib::ustring::format(std::fixed, std::setprecision(4), studgood)) diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index f172590c8..56d8b646c 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -21,6 +21,7 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "guiutils.h" #include "toolpanel.h" #include "wbprovider.h" @@ -35,7 +36,7 @@ public: virtual void spotWBRequested(int size) = 0; }; -class WhiteBalance final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoWBListener +class WhiteBalance final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::AutoWBListener { enum WB_LabelType { @@ -45,6 +46,7 @@ class WhiteBalance final : public ToolParamBlock, public AdjusterListener, publi private: Gtk::Label* StudLabel; + Gtk::Label* mulLabel; protected: class MethodColumns : public Gtk::TreeModel::ColumnRecord @@ -60,6 +62,8 @@ protected: add(colId); } }; + + rtengine::ProcEvent EvWBObserver10; static Glib::RefPtr wbPixbufs[rtengine::toUnderlying(rtengine::procparams::WBEntry::Type::CUSTOM) + 1]; Glib::RefPtr refTreeModel; @@ -71,6 +75,7 @@ protected: Adjuster* green; Adjuster* equal; Adjuster* tempBias; + CheckBox* observer10; Gtk::Button* spotbutton; int opt; @@ -114,6 +119,7 @@ public: void spotPressed (); void spotSizeChanged (); void adjusterChanged(Adjuster* a, double newval) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; int getSize (); void setWBProvider (WBProvider* p) { @@ -125,7 +131,7 @@ public: } void setWB (int temp, double green); void resetWB (); - void WBChanged (double temp, double green, float studgood) override; + void WBChanged (double temp, double green, double rw, double gw, double bw, float studgood) override; void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd); void trimValues (rtengine::procparams::ProcParams* pp) override; From 5481a8bbe1f9df2ae71a2aae4ddc67bed1390192 Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 20 Mar 2023 07:38:48 +0100 Subject: [PATCH 222/326] Ciecam - Fixed issue #6713 and add some batch functions (#6717) * Try to solve issue 6713 ans add some batch functions * Missing setAddMode tempout --- rtdata/languages/default | 3 ++- rtgui/addsetids.h | 2 ++ rtgui/batchtoolpanelcoord.cc | 6 ++++-- rtgui/colorappearance.cc | 35 +++++++++++++++++++++-------------- rtgui/colorappearance.h | 2 +- rtgui/paramsedited.cc | 4 ++-- rtgui/preferences.cc | 7 +++++-- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 9fe9975d9..541d94031 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2206,7 +2206,8 @@ TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM is the perceived amount of h TP_COLORAPP_CHROMA_S;Saturation (S) TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -TP_COLORAPP_CIECAT_DEGREE;Adaptation +TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene +TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing TP_COLORAPP_CONTRAST;Contrast (J) TP_COLORAPP_CONTRAST_Q;Contrast (Q) TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 6f68c6ae7..31097931a 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -65,6 +65,8 @@ enum { ADDSET_CAT_CHROMA_S, ADDSET_CAT_CHROMA_M, ADDSET_CAT_HUE, + ADDSET_CAT_DEGREEOUT, + ADDSET_CAT_TEMPOUT, ADDSET_CAT_BADPIX, ADDSET_WB_EQUAL, ADDSET_GRADIENT_DEGREE, diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 58532f68a..297608896 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -148,7 +148,7 @@ void BatchToolPanelCoordinator::initSession () whitebalance->setAdjusterBehavior (false, false, false, false); vibrance->setAdjusterBehavior (false, false); vignetting->setAdjusterBehavior (false, false, false, false); - colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false); + colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); rotate->setAdjusterBehavior (false); resize->setAdjusterBehavior (false); distortion->setAdjusterBehavior (false); @@ -193,7 +193,7 @@ void BatchToolPanelCoordinator::initSession () whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN], options.baBehav[ADDSET_WB_EQUAL], options.baBehav[ADDSET_WB_TEMPBIAS]); vibrance->setAdjusterBehavior (options.baBehav[ADDSET_VIBRANCE_PASTELS], options.baBehav[ADDSET_VIBRANCE_SATURATED]); vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT], options.baBehav[ADDSET_VIGN_RADIUS], options.baBehav[ADDSET_VIGN_STRENGTH], options.baBehav[ADDSET_VIGN_CENTER]); - colorappearance->setAdjusterBehavior (options.baBehav[ADDSET_CAT_DEGREE], options.baBehav[ADDSET_CAT_ADAPTSCENE], options.baBehav[ADDSET_CAT_ADAPTVIEWING], options.baBehav[ADDSET_CAT_BADPIX], options.baBehav[ADDSET_CAT_LIGHT], options.baBehav[ADDSET_CAT_CHROMA], options.baBehav[ADDSET_CAT_CONTRAST], options.baBehav[ADDSET_CAT_RSTPRO], options.baBehav[ADDSET_CAT_BRIGHT], options.baBehav[ADDSET_CAT_CONTRAST_Q], options.baBehav[ADDSET_CAT_CHROMA_S], options.baBehav[ADDSET_CAT_CHROMA_M], options.baBehav[ADDSET_CAT_HUE]); + colorappearance->setAdjusterBehavior (options.baBehav[ADDSET_CAT_DEGREE], options.baBehav[ADDSET_CAT_ADAPTSCENE], options.baBehav[ADDSET_CAT_ADAPTVIEWING], options.baBehav[ADDSET_CAT_BADPIX], options.baBehav[ADDSET_CAT_LIGHT], options.baBehav[ADDSET_CAT_CHROMA], options.baBehav[ADDSET_CAT_CONTRAST], options.baBehav[ADDSET_CAT_RSTPRO], options.baBehav[ADDSET_CAT_BRIGHT], options.baBehav[ADDSET_CAT_CONTRAST_Q], options.baBehav[ADDSET_CAT_CHROMA_S], options.baBehav[ADDSET_CAT_CHROMA_M], options.baBehav[ADDSET_CAT_HUE],options.baBehav[ADDSET_CAT_DEGREEOUT], options.baBehav[ADDSET_CAT_TEMPOUT] ); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]); distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); @@ -289,6 +289,8 @@ void BatchToolPanelCoordinator::initSession () if (options.baBehav[ADDSET_CAT_CONTRAST]) { pparams.colorappearance.contrast = 0; } if (options.baBehav[ADDSET_CAT_CONTRAST_Q]) { pparams.colorappearance.qcontrast = 0; } if (options.baBehav[ADDSET_CAT_HUE]) { pparams.colorappearance.colorh = 0; } + if (options.baBehav[ADDSET_CAT_DEGREEOUT]) { pparams.colorappearance.degreeout = 0; } + if (options.baBehav[ADDSET_CAT_TEMPOUT]) { pparams.colorappearance.tempout = 0; } //if (options.baBehav[ADDSET_CBOOST_AMOUNT]) pparams.colorBoost.amount = 0; //if (options.baBehav[ADDSET_CS_BLUEYELLOW]) pparams.colorShift.a = 0; //if (options.baBehav[ADDSET_CS_GREENMAGENTA]) pparams.colorShift.b = 0; diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index 5531a55c8..41f6952a7 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -662,7 +662,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, TOOL_NAME, M ("TP // Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small.png")); // Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small.png")); - degreeout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 90.)); + degreeout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREEOUT"), 0., 100., 1., 90.)); // degreeout->setDelay(std::max(options.adjusterMinDelay, options.adjusterMaxDelay)); @@ -683,9 +683,9 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, TOOL_NAME, M ("TP ybout->set_tooltip_markup (M ("TP_COLORAPP_YBOUT_TOOLTIP")); tempout->set_tooltip_markup (M ("TP_COLORAPP_TEMP2_TOOLTIP")); - tempout->throwOnButtonRelease(); +// tempout->throwOnButtonRelease(); tempout->addAutoButton (M ("TP_COLORAPP_TEMPOUT_TOOLTIP")); - // I renable tempout with addautobutton to work properly (and all code disabled). There are certainly some redundancies, but it doesn't matter + // I renable tempout with addautobutton to work properly (and all code disabled). There are certainly some redundancies, but it doesn't matter tempout->show(); greenout->show(); ybout->show(); @@ -696,8 +696,8 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, TOOL_NAME, M ("TP tempgreenVBox = Gtk::manage ( new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); tempgreenVBox->set_spacing (2); tempgreenVBox->pack_start (*tempout); - tempgreenVBox->pack_start (*greenout); - tempgreenFrame->add(*tempgreenVBox); + tempgreenVBox->pack_start (*greenout); + tempgreenFrame->add(*tempgreenVBox); p3VBox->pack_start(*tempgreenFrame); p3VBox->pack_start (*ybout); @@ -832,7 +832,7 @@ void ColorAppearance::neutral_pressed () qcontrast->resetValue (false); colorh->resetValue (false); tempout->resetValue (false); - tempout->setAutoValue (true); + tempout->setAutoValue (true); greenout->resetValue (false); ybout->resetValue (false); tempsc->resetValue (false); @@ -893,6 +893,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { degree->setEditedState (pedited->colorappearance.degree ? Edited : UnEdited); degreeout->setEditedState (pedited->colorappearance.degreeout ? Edited : UnEdited); + tempout->setEditedState (pedited->colorappearance.tempout ? Edited : UnEdited); adapscen->setEditedState (pedited->colorappearance.adapscen ? Edited : UnEdited); ybscen->setEditedState (pedited->colorappearance.ybscen ? Edited : UnEdited); adaplum->setEditedState (pedited->colorappearance.adaplum ? Edited : UnEdited); @@ -1131,7 +1132,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) qcontrast->setValue (pp->colorappearance.qcontrast); colorh->setValue (pp->colorappearance.colorh); tempout->setValue (pp->colorappearance.tempout); - tempout->setAutoValue (pp->colorappearance.autotempout); + tempout->setAutoValue (pp->colorappearance.autotempout); greenout->setValue (pp->colorappearance.greenout); ybout->setValue (pp->colorappearance.ybout); tempsc->setValue (pp->colorappearance.tempsc); @@ -1483,12 +1484,14 @@ void ColorAppearance::catmethodChanged() ybout->setValue(18); tempout->setValue (nexttemp); - if(tempout->getAutoValue()) { - tempout->resetValue (false); - } else { - tempout->setValue (nexttemp); - tempout->setAutoValue (true); - } + if(tempout->getAutoValue()) { + tempout->resetValue (false); + tempout->setAutoValue (true); + } else { + tempout->resetValue (false); + tempout->setValue (nexttemp); + tempout->setAutoValue (true); + } greenout->setValue (nextgreen); enableListener(); @@ -1515,6 +1518,7 @@ void ColorAppearance::catmethodChanged() degreeout->resetValue (false); ybout->resetValue (false); tempout->resetValue (false); + tempout->setAutoValue (true); greenout->resetValue (false); enableListener(); } else if (catmethod->get_active_row_number() == 2) { @@ -2311,7 +2315,7 @@ void ColorAppearance::updateCurveBackgroundHistogram( -void ColorAppearance::setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd) +void ColorAppearance::setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd, bool degreeoutadd, bool tempoutadd) { degree->setAddMode (degreeadd); @@ -2327,6 +2331,9 @@ void ColorAppearance::setAdjusterBehavior (bool degreeadd, bool adapscenadd, boo contrast->setAddMode (contrastadd); qcontrast->setAddMode (qcontrastadd); colorh->setAddMode (colorhadd); + degreeout->setAddMode (degreeoutadd); + tempout->setAddMode (tempoutadd); + } void ColorAppearance::trimValues (rtengine::procparams::ProcParams* pp) diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index dcf19b977..714f3e557 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -88,7 +88,7 @@ public: bool isCurveExpanded (); void autoOpenCurve () override; - void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd); + void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd, bool degreeoutadd, bool tempoutadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void updateCurveBackgroundHistogram( const LUTu& histToneCurve, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index c3638cc5f..20450fa24 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -2976,7 +2976,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.degreeout) { - toEdit.colorappearance.degreeout = mods.colorappearance.degreeout; + toEdit.colorappearance.degreeout = dontforceSet && options.baBehav[ADDSET_CAT_DEGREEOUT] ? toEdit.colorappearance.degreeout + mods.colorappearance.degreeout : mods.colorappearance.degreeout; } if (colorappearance.autodegreeout) { @@ -3028,7 +3028,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.tempout) { - toEdit.colorappearance.tempout = mods.colorappearance.tempout; + toEdit.colorappearance.tempout = dontforceSet && options.baBehav[ADDSET_CAT_TEMPOUT] ? toEdit.colorappearance.tempout + mods.colorappearance.tempout : mods.colorappearance.tempout; } if (colorappearance.autotempout) { diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 8c3290e5c..9a5937881 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -291,15 +291,18 @@ Gtk::Widget* Preferences::getBatchProcPanel() mi->set_value(behavColumns.label, M("TP_COLORAPP_LABEL")); appendBehavList (mi, M("TP_COLORAPP_LABEL_SCENE") + " - " + M("TP_COLORAPP_ABSOLUTELUMINANCE"), ADDSET_CAT_ADAPTSCENE, true); appendBehavList (mi, M("TP_COLORAPP_LABEL_VIEWING") + " - " + M("TP_COLORAPP_ABSOLUTELUMINANCE"), ADDSET_CAT_ADAPTVIEWING, true); + appendBehavList(mi, M("TP_COLORAPP_CIECAT_DEGREE"), ADDSET_CAT_DEGREE, true); appendBehavList(mi, M("TP_COLORAPP_LIGHT"), ADDSET_CAT_LIGHT, true); appendBehavList(mi, M("TP_COLORAPP_BRIGHT"), ADDSET_CAT_BRIGHT, true); appendBehavList(mi, M("TP_COLORAPP_CHROMA"), ADDSET_CAT_CHROMA, true); - appendBehavList (mi, M ("TP_COLORAPP_CHROMA_S"), ADDSET_CAT_CHROMA_S, true); - appendBehavList (mi, M ("TP_COLORAPP_CHROMA_M"), ADDSET_CAT_CHROMA_M, true); + appendBehavList(mi, M ("TP_COLORAPP_CHROMA_S"), ADDSET_CAT_CHROMA_S, true); + appendBehavList(mi, M ("TP_COLORAPP_CHROMA_M"), ADDSET_CAT_CHROMA_M, true); appendBehavList(mi, M("TP_COLORAPP_RSTPRO"), ADDSET_CAT_RSTPRO, true); appendBehavList(mi, M("TP_COLORAPP_CONTRAST"), ADDSET_CAT_CONTRAST, true); appendBehavList(mi, M("TP_COLORAPP_CONTRAST_Q"), ADDSET_CAT_CONTRAST_Q, true); appendBehavList(mi, M("TP_COLORAPP_HUE"), ADDSET_CAT_HUE, true); + appendBehavList(mi, M("TP_COLORAPP_CIECAT_DEGREEOUT"), ADDSET_CAT_DEGREEOUT, true); + appendBehavList(mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_CAT_TEMPOUT, true); appendBehavList(mi, M("TP_COLORAPP_BADPIXSL"), ADDSET_CAT_BADPIX, true); mi = behModel->append(); From 6d320534989cf36f7837fb2183da14bea9997a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Mon, 20 Mar 2023 17:22:53 -0400 Subject: [PATCH 223/326] Issue #6721 - Fix memory leak in Crop - Crop::freeAll() didn't free the memory --- rtengine/dcrop.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 8ddaa5f75..fb553c354 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1735,6 +1735,11 @@ void Crop::freeAll() shbuffer = nullptr; } + if (shbuf_real) { + delete [] shbuf_real; + shbuf_real = nullptr; + } + PipetteBuffer::flush(); } From cfabedc4e9b476f37aa5779d828cb211b0289b3f Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 19 Mar 2023 15:37:33 -0700 Subject: [PATCH 224/326] Add pre-dev publishing to Actions workflows --- .github/workflows/appimage.yml | 32 +++++++++++++++++++++++++ .github/workflows/windows.yml | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cc0d16b8f..8fd7608f9 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -10,6 +10,8 @@ on: branches: - dev workflow_dispatch: +env: + publish_pre_dev_labels: '[]' jobs: build: runs-on: ubuntu-18.04 @@ -167,3 +169,33 @@ jobs: files: | ${{env.PUBLISH_NAME}}.AppImage ${{env.PUBLISH_NAME}}-AboutThisBuild.txt + + - name: Prepare for publishing pre-dev + id: prepare-publish-pre-dev + if: ${{github.event_name == 'pull_request' && contains(fromJSON(env.publish_pre_dev_labels), github.event.pull_request.head.label)}} + run: | + echo "Making ref name." + REF_NAME_FILTERED="$(echo '${{github.event.pull_request.head.label}}' | tr ':' '_' | sed 's/[^A-z0-9_.-]//g')" + echo "Ref name is '$REF_NAME_FILTERED'." + + echo "Setting publish name." + PUBLISH_NAME="RawTherapee_${REF_NAME_FILTERED}_${{matrix.build_type}}" + echo "Publish name is '$PUBLISH_NAME'." + + echo "Renaming AppImage." + cp "build/$ARTIFACT_NAME.AppImage" "$PUBLISH_NAME.AppImage" + + echo "Creating version file." + cp "build/AboutThisBuild.txt" "$PUBLISH_NAME-AppImage-AboutThisBuild.txt" + + echo "Recording publish name." + echo "PUBLISH_NAME=$PUBLISH_NAME" >> $GITHUB_ENV + + - name: Publish pre-dev artifacts + uses: softprops/action-gh-release@v1 + if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} + with: + tag_name: pre-dev-github-actions + files: | + ${{env.PUBLISH_NAME}}.AppImage + ${{env.PUBLISH_NAME}}-AppImage-AboutThisBuild.txt diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 49fdf5999..a14c23993 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -10,6 +10,8 @@ on: branches: - dev workflow_dispatch: +env: + publish_pre_dev_labels: '[]' jobs: build: runs-on: windows-2022 @@ -300,3 +302,44 @@ jobs: with: tag_name: nightly-github-actions files: build/${{env.PUBLISH_NAME}}.exe + + - name: Prepare for publishing pre-dev + id: prepare-publish-pre-dev + if: ${{github.event_name == 'pull_request' && contains(fromJSON(env.publish_pre_dev_labels), github.event.pull_request.head.label)}} + run: | + echo "Making ref name." + REF_NAME_FILTERED="$(echo '${{github.event.pull_request.head.label}}' | tr ':' '_' | sed 's/[^A-z0-9_.-]//g')" + echo "Ref name is '$REF_NAME_FILTERED'." + + echo "Setting publish name." + PUBLISH_NAME="RawTherapee_${REF_NAME_FILTERED}_win64_${{matrix.build_type}}" + echo "Publish name is '$PUBLISH_NAME'." + if [ "$ARTIFACT_NAME" != "$PUBLISH_NAME" ]; then + echo "Renaming ZIP file." + cp "build/$ARTIFACT_NAME.zip" "build/$PUBLISH_NAME.zip" + if [ -e "./build/$ARTIFACT_NAME.exe" ]; then + echo "Renaming installer." + mv "./build/$ARTIFACT_NAME.exe" "./build/$PUBLISH_NAME.exe" + fi + fi + echo "Creating version file." + cp "build/$ARTIFACT_NAME/AboutThisBuild.txt" "build/$PUBLISH_NAME-AboutThisBuild.txt" + + echo "Recording publish name." + echo "PUBLISH_NAME=$PUBLISH_NAME" >> "$(cygpath -u $GITHUB_ENV)" + + - name: Publish pre-dev artifacts + uses: softprops/action-gh-release@v1 + if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} + with: + tag_name: pre-dev-github-actions + files: | + build/${{env.PUBLISH_NAME}}.zip + build/${{env.PUBLISH_NAME}}-AboutThisBuild.txt + + - name: Publish pre-dev installer + uses: softprops/action-gh-release@v1 + if: ${{steps.prepare-publish-pre-dev.outcome == 'success' && matrix.build_type == 'release'}} + with: + tag_name: pre-dev-github-actions + files: build/${{env.PUBLISH_NAME}}.exe From da1c258057bbd4fe440b183ba1792a63f676e627 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Wed, 22 Mar 2023 23:03:46 -0700 Subject: [PATCH 225/326] Enable publishing of metadata-exiv2 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 2f0e0b3e5..bbeb09e0d 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:metadata-exiv2"]' jobs: build: runs-on: ubuntu-18.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index dcdec99d7..d50dca59d 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:metadata-exiv2"]' jobs: build: runs-on: windows-2022 From 223b136082ba2d61273058351232a6b37ea7a283 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 25 Mar 2023 12:11:19 -0700 Subject: [PATCH 226/326] Fix Windows workflow Adwaita error Update paths to match those of the Adwaita icon theme library. --- .github/workflows/windows.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index a14c23993..4ab10212c 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -178,15 +178,15 @@ jobs: echo "Copying Adwaita theme." mkdir -p "$BUILD_DIR/share/icons/Adwaita" cd 'share/icons/Adwaita/' - mkdir -p "$BUILD_DIR/share/icons/Adwaita/scalable" + mkdir -p "$BUILD_DIR/share/icons/Adwaita/symbolic" cp -r \ - "scalable/actions" \ - "scalable/devices" \ - "scalable/mimetypes" \ - "scalable/places" \ - "scalable/status" \ - "scalable/ui" \ - "$BUILD_DIR/share/icons/Adwaita/scalable" + "symbolic/actions" \ + "symbolic/devices" \ + "symbolic/mimetypes" \ + "symbolic/places" \ + "symbolic/status" \ + "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 \ From ae4de4701f5b0d8303d67e15822f453f99d3f02a Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 6 Dec 2020 09:37:34 +0100 Subject: [PATCH 227/326] Fix color-cast regression Fix checking of existence of second masked area. Issue #6720. --- rtengine/camconst.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index 64fc4d4ba..5cb56b2ae 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -224,7 +224,7 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model) const auto get_masked_areas = [](int w, int h, const cJSON *ji, CameraConst *cc) -> bool { - std::array, 2> rm; + std::array, 2> rm = {}; if (ji->type != cJSON_Array) { //fprintf(stderr, "\"masked_areas\" must be an array\n"); @@ -505,7 +505,15 @@ bool CameraConst::has_rawMask(int raw_width, int raw_height, int idx) const return false; } - return raw_mask.find(std::make_pair(raw_width, raw_height)) != raw_mask.end() || raw_mask.find(std::make_pair(0, 0)) != raw_mask.end(); + auto it = raw_mask.find(std::make_pair(raw_width, raw_height)); + if (it == raw_mask.end()) { + it = raw_mask.find(std::make_pair(0, 0)); + } + if (it != raw_mask.end()) { + return (it->second[idx][0] | it->second[idx][1] | it->second[idx][2] | it->second[idx][3]) != 0; + } else { + return false; + } } From 294c6167ae5d7bc3b899a96c10b7bc46087be913 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 26 Mar 2023 16:08:13 -0700 Subject: [PATCH 228/326] Add missing DLL to Windows build Exiv2 and dependent libraries were missing. --- .github/workflows/windows.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d50dca59d..b9a4a0b35 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -119,9 +119,12 @@ jobs: "libcairo-2.dll" \ "libcairo-gobject-2.dll" \ "libcairomm-1.0-1.dll" \ + "libcrypto-3-x64.dll" \ + "libcurl-4.dll" \ "libdatrie-1.dll" \ "libdeflate.dll" \ "libepoxy-0.dll" \ + "libexiv2.dll" \ "libexpat-1.dll" \ libffi-*.dll \ "libfftw3f-3.dll" \ @@ -145,6 +148,7 @@ jobs: "libgtkmm-3.0-1.dll" \ "libharfbuzz-0.dll" \ "libiconv-2.dll" \ + "libidn2-0.dll" \ "libintl-8.dll" \ "libjbig-0.dll" \ "libjpeg-8.dll" \ @@ -152,6 +156,7 @@ jobs: "liblensfun.dll" \ "libLerc.dll" \ "liblzma-5.dll" \ + "libnghttp2-14.dll" \ "libpango-1.0-0.dll" \ "libpangocairo-1.0-0.dll" \ "libpangoft2-1.0-0.dll" \ @@ -160,14 +165,18 @@ jobs: "libpcre2-8-0.dll" \ "libpixman-1-0.dll" \ "libpng16-16.dll" \ + "libpsl-5.dll" \ "librsvg-2-2.dll" \ "libsharpyuv-0.dll" \ "libsigc-2.0-0.dll" \ + "libssh2-1.dll" \ + "libssl-3-x64.dll" \ "libstdc++-6.dll" \ "libsystre-0.dll" \ "libthai-0.dll" \ "libtiff-6.dll" \ "libtre-5.dll" \ + "libunistring-5.dll" \ "libwebp-7.dll" \ "libwinpthread-1.dll" \ "libxml2-2.dll" \ From 1abbfceb8e5a241efc12e28cff9f5e9a1d6e0b97 Mon Sep 17 00:00:00 2001 From: Bezierr Date: Mon, 27 Mar 2023 13:23:21 +0200 Subject: [PATCH 229/326] Name added to AUTHORS.txt As suggested by Lawrence37 --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 059bdce17..3d16899a6 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -5,6 +5,7 @@ Project initiator: Development contributors, in last name alphabetical order: + Harald Aust Roel Baars Martin Burri Pierre Cabrera From 533a05cd9d3d17a818fac10d71dbea76fa3ccf2f Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 Apr 2023 16:59:24 -0700 Subject: [PATCH 230/326] Get lens name from Nikon Z series images --- rtengine/imagedata.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 73c51b103..636838548 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -320,7 +320,9 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : //orientation = pos->print(&exif); } - if (find_tag(Exiv2::lensName)) { + if (find_exif_tag("Exif.NikonLd4.LensIDNumber")) { + lens = validateUft8(pos->print(&exif)); + } else if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { From 30025d2ac2e0e30cf4a38fab1485d35e31483056 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 Apr 2023 17:22:10 -0700 Subject: [PATCH 231/326] Get Sony image lens from Sony lens ID tag --- rtengine/imagedata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 636838548..c3b177734 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -320,7 +320,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : //orientation = pos->print(&exif); } - if (find_exif_tag("Exif.NikonLd4.LensIDNumber")) { + if (find_exif_tag("Exif.NikonLd4.LensIDNumber") || find_exif_tag("Exif.Sony2.LensID")) { lens = validateUft8(pos->print(&exif)); } else if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); From 0bbcea8806e0f0e97d8b19953e8f070a595c026d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 Apr 2023 23:43:10 -0700 Subject: [PATCH 232/326] Fix Nikon Z series lens identification --- rtengine/imagedata.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index c3b177734..9bf1b1210 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -320,7 +320,9 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : //orientation = pos->print(&exif); } - if (find_exif_tag("Exif.NikonLd4.LensIDNumber") || find_exif_tag("Exif.Sony2.LensID")) { + if ((find_exif_tag("Exif.NikonLd4.LensID") && pos->toLong()) || + (find_exif_tag("Exif.NikonLd4.LensIDNumber") && pos->toLong()) || + (find_exif_tag("Exif.Sony2.LensID") && pos->toLong())) { lens = validateUft8(pos->print(&exif)); } else if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); From 1dbd9818cf6d0c2b8b77bb29ccc721cc86d096af Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 3 Apr 2023 20:16:39 -0700 Subject: [PATCH 233/326] Set AppImage runner to Ubuntu 20.04 Ubuntu 18.04 is no longer available in GitHub Actions. --- .github/workflows/appimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 8fd7608f9..9ad9a6cbd 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -14,7 +14,7 @@ env: publish_pre_dev_labels: '[]' jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: From 7a48aff7ee38b996d1f9d4b9786d4a2eb8391865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Fri, 7 Apr 2023 21:51:46 -0400 Subject: [PATCH 234/326] Issue #6735 - Remove memory leak when processing Fuji RAF converted to DNG --- rtexif/rtexif.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index a7125fb9a..4848299ad 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -1209,6 +1209,10 @@ Tag::Tag (TagDirectory* p, FILE* f, int base) goto defsubdirs; } } else { + // In some circumstances, `value` may have been allocated, so + // delete it to prevent a leak. See issue + // https://github.com/Beep6581/RawTherapee/issues/6735 + delete [] value; // read value value = new unsigned char [valuesize + 1]; auto readSize = fread (value, 1, valuesize, f); From 19f12f3182d3c2e4a648c607da4a0ac7fb9346ec Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 8 Apr 2023 18:16:23 -0700 Subject: [PATCH 235/326] Allow native commands as external editors If an editor is marked as a native command, it is launched using the older method (native for Windows or Glib otherwise). Non-native commands are launched with Gio. When reading preferences containing the old style external editor settings, all commands are marked as native to avoid breaking them. Fix bug where the send to editor button shows the wrong editor. The bug happens when the other editor option is selected while the user edits the external editors in preferences. When saved, the button shows the first option is selected instead of the other editor option (the last entry). --- rtdata/languages/default | 3 ++- rtgui/editorpanel.cc | 4 ++- rtgui/editorpanel.h | 1 + rtgui/externaleditorpreferences.cc | 39 +++++++++++++++++++++------ rtgui/externaleditorpreferences.h | 10 +++++++ rtgui/extprog.cc | 14 +++++++++- rtgui/extprog.h | 2 +- rtgui/options.cc | 43 +++++++++++++++++++----------- rtgui/options.h | 3 ++- rtgui/preferences.cc | 10 ++++--- 10 files changed, 97 insertions(+), 32 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 8f3a59097..45471bb5c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1883,8 +1883,9 @@ PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output PREFERENCES_EXTERNALEDITOR;External Editor PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable -PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command +PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name +PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Native command PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser PREFERENCES_FLATFIELDFOUND;Found diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index ffe13fea3..420717b7e 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2250,6 +2250,7 @@ void EditorPanel::sendToExternalPressed() } else { struct ExternalEditor editor = options.externalEditors.at(options.externalEditorIndex); external_editor_info = Gio::AppInfo::create_from_commandline(editor.command, editor.name, Gio::APP_INFO_CREATE_NONE); + external_editor_native_command = editor.native_command; sendToExternal(); } } @@ -2415,7 +2416,7 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef setUserOnlyPermission(Gio::File::create_for_path(filename), false); - success = ExtProgStore::openInExternalEditor(filename, external_editor_info); + success = ExtProgStore::openInExternalEditor(filename, external_editor_info, external_editor_native_command); if (!success) { Gtk::MessageDialog msgd (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); @@ -2447,6 +2448,7 @@ void EditorPanel::onAppChooserDialogResponse(int responseId) case Gtk::RESPONSE_OK: getAppChooserDialog()->close(); external_editor_info = getAppChooserDialog()->get_app_info(); + external_editor_native_command = false; sendToExternal(); break; case Gtk::RESPONSE_CANCEL: diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 98a475a7c..309f14e8c 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -253,6 +253,7 @@ private: Gtk::Button* navNext; Gtk::Button* navPrev; Glib::RefPtr external_editor_info; + bool external_editor_native_command; std::unique_ptr app_chooser_dialog; ExternalEditorChangedSignal *externalEditorChangedSignal; sigc::connection externalEditorChangedSignalConnection; diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 79dac52d2..55c9f7956 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -37,6 +37,7 @@ ExternalEditorPreferences::ExternalEditorPreferences(): list_view = Gtk::manage(new Gtk::TreeView()); list_view->set_model(list_model); list_view->append_column(*Gtk::manage(makeAppColumn())); + list_view->append_column(*Gtk::manage(makeNativeCommandColumn())); list_view->append_column(*Gtk::manage(makeCommandColumn())); for (auto &&column : list_view->get_columns()) { @@ -97,12 +98,12 @@ ExternalEditorPreferences::getEditors() const 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(); - editors.push_back(ExternalEditorPreferences::EditorInfo( - rowIter->get_value(model_columns.name), - rowIter->get_value(model_columns.command), - icon_serialized, - rowIter->get_value(model_columns.other_data) - )); + editors.emplace_back( + rowIter->get_value(model_columns.name), + rowIter->get_value(model_columns.command), + icon_serialized, + rowIter->get_value(model_columns.native_command), + rowIter->get_value(model_columns.other_data)); } return editors; @@ -138,6 +139,7 @@ void ExternalEditorPreferences::setEditors( row[model_columns.name] = editor.name; row[model_columns.icon] = icon; row[model_columns.command] = editor.command; + row[model_columns.native_command] = editor.native_command; row[model_columns.other_data] = editor.other_data; } } @@ -194,6 +196,24 @@ Gtk::TreeViewColumn *ExternalEditorPreferences::makeCommandColumn() return col; } +Gtk::TreeViewColumn *ExternalEditorPreferences::makeNativeCommandColumn() +{ + auto toggle_renderer = Gtk::manage(new Gtk::CellRendererToggle()); + auto col = Gtk::manage(new Gtk::TreeViewColumn()); + + col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND")); + col->pack_start(*toggle_renderer); + col->add_attribute(toggle_renderer->property_active(), model_columns.native_command); + + toggle_renderer->signal_toggled().connect([this](const Glib::ustring &path) { + const auto row_iter = list_model->get_iter(path); + bool new_value = !row_iter->get_value(model_columns.native_command); + row_iter->set_value(model_columns.native_command, new_value); + }); + + return col; +} + void ExternalEditorPreferences::onAppChooserDialogResponse( int response_id, RTAppChooserDialog *dialog) { @@ -224,6 +244,7 @@ void ExternalEditorPreferences::onFileChooserDialogResponse( for (const auto &selected : selection) { auto row = *list_model->get_iter(selected); row[model_columns.icon] = Glib::RefPtr(nullptr); + row[model_columns.native_command] = false; row[model_columns.command] = #ifdef WIN32 '"' + dialog->get_filename() + '"'; @@ -313,6 +334,7 @@ void ExternalEditorPreferences::setApp(const Glib::RefPtr app_info row[model_columns.icon] = app_info->get_icon(); row[model_columns.name] = app_info->get_name(); row[model_columns.command] = app_info->get_commandline(); + row[model_columns.native_command] = false; } } @@ -344,8 +366,8 @@ void ExternalEditorPreferences::updateToolbarSensitivity() } ExternalEditorPreferences::EditorInfo::EditorInfo( - Glib::ustring name, Glib::ustring command, Glib::ustring icon_serialized, void *other_data -) : name(name), icon_serialized(icon_serialized), command(command), other_data(other_data) + Glib::ustring name, Glib::ustring command, Glib::ustring icon_serialized, bool native_command, void *other_data +) : name(name), icon_serialized(icon_serialized), command(command), native_command(native_command), other_data(other_data) { } @@ -354,5 +376,6 @@ ExternalEditorPreferences::ModelColumns::ModelColumns() add(name); add(icon); add(command); + add(native_command); add(other_data); } diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index 34658d942..26903371c 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -50,6 +50,7 @@ public: Glib::ustring name = Glib::ustring(), Glib::ustring command = Glib::ustring(), Glib::ustring icon_serialized = Glib::ustring(), + bool native_command = false, void *other_data = nullptr ); /** @@ -65,6 +66,10 @@ public: * Gio::AppInfo::get_commandline() */ Glib::ustring command; + /** + * Use the OS native launcher instead of Gio. + */ + bool native_command; /** * Holds any other data associated with the editor. For example, it can * be used as a tag to uniquely identify the editor. @@ -96,6 +101,7 @@ private: Gtk::TreeModelColumn name; Gtk::TreeModelColumn> icon; Gtk::TreeModelColumn command; + Gtk::TreeModelColumn native_command; Gtk::TreeModelColumn other_data; }; @@ -124,6 +130,10 @@ private: * Constructs the column for displaying an editable commandline. */ Gtk::TreeViewColumn *makeCommandColumn(); + /** + * Constructs the column for displaying the native command toggle. + */ + Gtk::TreeViewColumn *makeNativeCommandColumn(); /** * Called when the user is done interacting with the app chooser dialog. * Closes the dialog and updates the selected entry if an app was chosen. diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 9ec87c548..ea1800638 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -344,8 +344,20 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName, const Glib } -bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo) +bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo, bool nativeCommand) { + if (nativeCommand) { + if (rtengine::settings->verbose) { + std::cout << "Launching external editor as native command." << std::endl; + } + const Glib::ustring command = editorInfo->get_commandline(); + return openInCustomEditor(fileName, &command); + } + + if (rtengine::settings->verbose) { + std::cout << "Launching external editor with Gio." << std::endl; + } + bool success = false; try { diff --git a/rtgui/extprog.h b/rtgui/extprog.h index 6547896ef..5336c4703 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -70,7 +70,7 @@ public: static bool openInGimp (const Glib::ustring& fileName); static bool openInPhotoshop (const Glib::ustring& fileName); static bool openInCustomEditor (const Glib::ustring& fileName, const Glib::ustring* command = nullptr); - static bool openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo); + static bool openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo, bool nativeCommand); }; #define extProgStore ExtProgStore::getInstance() diff --git a/rtgui/options.cc b/rtgui/options.cc index b59e7c203..d6c3f7d25 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -873,6 +873,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_group("External Editor")) { if (keyFile.has_key("External Editor", "Names") || keyFile.has_key("External Editor", "Commands") + || keyFile.has_key("External Editor", "NativeCommands") || keyFile.has_key("External Editor", "IconsSerialized")) { // Multiple external editors. @@ -886,6 +887,11 @@ void Options::readFromFile(Glib::ustring fname) std::vector() : static_cast>( keyFile.get_string_list("External Editor", "Commands")); + const auto & native_commands = + !keyFile.has_key("External Editor", "NativeCommands") ? + std::vector() : + static_cast>( + keyFile.get_boolean_list("External Editor", "NativeCommands")); const auto & icons_serialized = !keyFile.has_key("External Editor", "IconsSerialized") ? std::vector() : @@ -899,6 +905,9 @@ void Options::readFromFile(Glib::ustring fname) for (unsigned i = 0; i < commands.size(); i++) { externalEditors[i].command = commands[i]; } + for (unsigned i = 0; i < native_commands.size(); i++) { + externalEditors[i].native_command = native_commands[i]; + } for (unsigned i = 0; i < icons_serialized.size(); i++) { externalEditors[i].icon_serialized = icons_serialized[i]; } @@ -938,7 +947,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); + externalEditors.emplace_back("GIMP", executable, true, getIconSerialized(executable)); } else { for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); @@ -946,7 +955,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); + externalEditors.emplace_back("GIMP", executable, true, getIconSerialized(executable)); break; } } @@ -961,7 +970,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", getIconSerialized(executable))); + externalEditors.emplace_back("Photoshop", executable, true, getIconSerialized(executable)); } if (keyFile.has_key("External Editor", "CustomEditor")) { @@ -970,20 +979,20 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 3) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("-", "\"" + executable + "\"", "")); + externalEditors.emplace_back("-", executable, true, ""); } } #elif defined __APPLE__ if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "open -a GIMP", "gimp")); - externalEditors.push_back(ExternalEditor("GIMP-dev", "open -a GIMP-dev", "gimp")); + externalEditors.emplace_back("GIMP", "open -a GIMP", true, ""); + externalEditors.emplace_back("GIMP-dev", "open -a GIMP-dev", true, ""); if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", "open -a Photoshop", "")); + externalEditors.emplace_back("Photoshop", "open -a Photoshop", true, ""); if (keyFile.has_key("External Editor", "CustomEditor")) { auto executable = keyFile.get_string("External Editor", "CustomEditor"); @@ -991,20 +1000,21 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 3) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("-", executable, "")); + externalEditors.emplace_back("-", executable, true, ""); } } #else + const Glib::ustring gimp_icon_serialized = "('themed', <['gimp', 'gimp-symbolic']>)"; if (Glib::find_program_in_path("gimp").compare("")) { if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "gimp", "gimp")); + externalEditors.emplace_back("GIMP", "gimp", true, gimp_icon_serialized); } else if (Glib::find_program_in_path("gimp-remote").compare("")) { if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "gimp-remote", "gimp")); + externalEditors.emplace_back("GIMP", "gimp-remote", true, gimp_icon_serialized); } if (keyFile.has_key("External Editor", "CustomEditor")) { @@ -1013,7 +1023,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 3) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("-", executable, "")); + externalEditors.emplace_back("-", executable, true, ""); } } #endif @@ -2328,16 +2338,19 @@ void Options::saveToFile(Glib::ustring fname) { std::vector names; std::vector commands; + std::vector native_commands; std::vector icons_serialized; for (const auto & editor : externalEditors) { names.push_back(editor.name); commands.push_back(editor.command); + native_commands.push_back(editor.native_command); icons_serialized.push_back(editor.icon_serialized); } keyFile.set_string_list("External Editor", "Names", names); keyFile.set_string_list("External Editor", "Commands", commands); + keyFile.set_boolean_list("External Editor", "NativeCommands", native_commands); keyFile.set_string_list("External Editor", "IconsSerialized", icons_serialized); keyFile.set_integer("External Editor", "EditorIndex", externalEditorIndex); @@ -3009,15 +3022,15 @@ Glib::ustring Options::getICCProfileCopyright() return Glib::ustring::compose("Copyright RawTherapee %1, CC0", now.get_year()); } -ExternalEditor::ExternalEditor() {} +ExternalEditor::ExternalEditor() = default; ExternalEditor::ExternalEditor( - const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized -): name(name), command(command), icon_serialized(icon_serialized) {} + const Glib::ustring &name, const Glib::ustring &command, bool native_command, const Glib::ustring &icon_serialized +): name(name), command(command), native_command(native_command), icon_serialized(icon_serialized) {} bool ExternalEditor::operator==(const ExternalEditor &other) const { - return this->name == other.name && this->command == other.command && this->icon_serialized == other.icon_serialized; + return this->name == other.name && this->command == other.command && this->native_command == other.native_command && this->icon_serialized == other.icon_serialized; } bool ExternalEditor::operator!=(const ExternalEditor &other) const diff --git a/rtgui/options.h b/rtgui/options.h index 2c34260aa..78059357e 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -54,9 +54,10 @@ struct ExternalEditor { ExternalEditor(); - ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized); + ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, bool native_command, const Glib::ustring &icon_serialized); Glib::ustring name; Glib::ustring command; + bool native_command; Glib::ustring icon_serialized; bool operator==(const ExternalEditor & other) const; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 7d95ef716..a97cb003d 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1752,7 +1752,7 @@ void Preferences::storePreferences() moptions.externalEditorIndex = -1; for (unsigned i = 0; i < editors.size(); i++) { moptions.externalEditors[i] = (ExternalEditor( - editors[i].name, editors[i].command, editors[i].icon_serialized)); + editors[i].name, editors[i].command, editors[i].native_command, editors[i].icon_serialized)); if (editors[i].other_data) { // The current editor was marked before the list was edited. We // found the mark, so this is the editor that was active. @@ -2034,8 +2034,7 @@ void Preferences::fillPreferences() std::vector editorInfos; for (const auto &editor : moptions.externalEditors) { - editorInfos.push_back(ExternalEditorPreferences::EditorInfo( - editor.name, editor.command, editor.icon_serialized)); + editorInfos.emplace_back(editor.name, editor.command, editor.icon_serialized, editor.native_command); } if (moptions.externalEditorIndex >= 0) { // Mark the current editor so we can track it. @@ -2536,7 +2535,10 @@ void Preferences::workflowUpdate() } if (changed) { // Update the send to external editor widget. - parent->updateExternalEditorWidget(moptions.externalEditorIndex, moptions.externalEditors); + int selected_index = moptions.externalEditorIndex >= 0 + ? moptions.externalEditorIndex + : static_cast(moptions.externalEditors.size()); + parent->updateExternalEditorWidget(selected_index, moptions.externalEditors); } if (moptions.cloneFavoriteTools != options.cloneFavoriteTools || From 186995acf4fbfa28d6743a74ce1683bb410f06dd Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 9 Apr 2023 13:52:09 -0700 Subject: [PATCH 236/326] Improve code quality for external editor settings --- rtgui/externaleditorpreferences.cc | 22 +++++++++++++++------- rtgui/externaleditorpreferences.h | 18 ++++++++++++------ rtgui/preferences.cc | 4 ++-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 55c9f7956..5d9b45c5d 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -91,7 +91,7 @@ ExternalEditorPreferences::ExternalEditorPreferences(): std::vector ExternalEditorPreferences::getEditors() const { - std::vector editors; + std::vector editors; auto children = list_model->children(); @@ -114,7 +114,7 @@ void ExternalEditorPreferences::setEditors( { list_model->clear(); - for (const ExternalEditorPreferences::EditorInfo & editor : editors) { + for (const EditorInfo & editor : editors) { auto row = *list_model->append(); Glib::RefPtr icon; @@ -169,8 +169,8 @@ Gtk::TreeViewColumn *ExternalEditorPreferences::makeAppColumn() col->set_resizable(); col->pack_start(*icon_renderer, false); col->pack_start(*name_renderer); - col->add_attribute(*icon_renderer, "gicon", model_columns.icon); - col->add_attribute(*name_renderer, "text", model_columns.name); + col->add_attribute(icon_renderer->property_gicon(), model_columns.icon); + col->add_attribute(name_renderer->property_text(), model_columns.name); col->set_min_width(20); name_renderer->property_editable() = true; @@ -187,7 +187,7 @@ Gtk::TreeViewColumn *ExternalEditorPreferences::makeCommandColumn() col->set_title(M("PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND")); col->pack_start(*command_renderer); - col->add_attribute(*command_renderer, "text", model_columns.command); + col->add_attribute(command_renderer->property_text(), model_columns.command); command_renderer->property_editable() = true; command_renderer->signal_edited().connect( @@ -366,8 +366,16 @@ void ExternalEditorPreferences::updateToolbarSensitivity() } ExternalEditorPreferences::EditorInfo::EditorInfo( - Glib::ustring name, Glib::ustring command, Glib::ustring icon_serialized, bool native_command, void *other_data -) : name(name), icon_serialized(icon_serialized), command(command), native_command(native_command), other_data(other_data) + const Glib::ustring &name, + const Glib::ustring &command, + const Glib::ustring &icon_serialized, + bool native_command, + EditorTag other_data) : + name(name), + icon_serialized(icon_serialized), + command(command), + native_command(native_command), + other_data(other_data) { } diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index 26903371c..a1e3c7e74 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -42,16 +42,22 @@ class FileChooserDialog; class ExternalEditorPreferences : public Gtk::Box { public: + struct EditorTag { + bool selected; + EditorTag(): selected(false) {} + explicit EditorTag(bool selected): selected(selected) {} + }; + /** * Data struct containing information about an external editor. */ struct EditorInfo { explicit EditorInfo( - Glib::ustring name = Glib::ustring(), - Glib::ustring command = Glib::ustring(), - Glib::ustring icon_serialized = Glib::ustring(), + const Glib::ustring &name = Glib::ustring(), + const Glib::ustring &command = Glib::ustring(), + const Glib::ustring &icon_serialized = Glib::ustring(), bool native_command = false, - void *other_data = nullptr + EditorTag other_data = EditorTag() ); /** * Name of the external editor. @@ -74,7 +80,7 @@ public: * Holds any other data associated with the editor. For example, it can * be used as a tag to uniquely identify the editor. */ - void *other_data; + EditorTag other_data; }; ExternalEditorPreferences(); @@ -102,7 +108,7 @@ private: Gtk::TreeModelColumn> icon; Gtk::TreeModelColumn command; Gtk::TreeModelColumn native_command; - Gtk::TreeModelColumn other_data; + Gtk::TreeModelColumn other_data; }; ModelColumns model_columns; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index a97cb003d..1ae01da2d 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1753,7 +1753,7 @@ void Preferences::storePreferences() for (unsigned i = 0; i < editors.size(); i++) { moptions.externalEditors[i] = (ExternalEditor( editors[i].name, editors[i].command, editors[i].native_command, editors[i].icon_serialized)); - if (editors[i].other_data) { + if (editors[i].other_data.selected) { // The current editor was marked before the list was edited. We // found the mark, so this is the editor that was active. moptions.externalEditorIndex = i; @@ -2038,7 +2038,7 @@ void Preferences::fillPreferences() } if (moptions.externalEditorIndex >= 0) { // Mark the current editor so we can track it. - editorInfos[moptions.externalEditorIndex].other_data = (void *)1; + editorInfos[moptions.externalEditorIndex].other_data.selected = true; } externalEditors->setEditors(editorInfos); From ab79a4fc3e2d5d94fa70f79a9b135a27d90c6a4c Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 9 Apr 2023 17:08:54 -0700 Subject: [PATCH 237/326] Refine lens name reading for Nikon Z and Sony Fall back to other EXIF tags in case Exiv2 cannot interpret the lens ID. --- rtengine/imagedata.cc | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 9bf1b1210..168177876 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -320,10 +320,33 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : //orientation = pos->print(&exif); } - if ((find_exif_tag("Exif.NikonLd4.LensID") && pos->toLong()) || - (find_exif_tag("Exif.NikonLd4.LensIDNumber") && pos->toLong()) || - (find_exif_tag("Exif.Sony2.LensID") && pos->toLong())) { - lens = validateUft8(pos->print(&exif)); + if (!make.compare(0, 5, "NIKON")) { + if (find_exif_tag("Exif.NikonLd4.LensID")) { + if (!pos->toLong()) { // No data, look in LensIDNumber. + const auto p = pos; + if (!find_exif_tag("Exif.NikonLd4.LensIDNumber")) { + pos = p; // Tag not found, so reset pos. + } + } + lens = pos->print(&exif); + if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. + lens.clear(); + } else { + lens = validateUft8(lens); + } + } + } else if (!make.compare(0, 4, "SONY")) { + if (find_exif_tag("Exif.Sony2.LensID") && pos->toLong()) { + lens = pos->print(&exif); + if (lens == std::to_string(pos->toLong())) { // Not know to Exiv2. + lens.clear(); + } else { + lens = validateUft8(lens); + } + } + } + if (!lens.empty()) { + // Already found the lens name. } else if (find_tag(Exiv2::lensName)) { lens = validateUft8(pos->print(&exif)); auto p = pos; From 9893e02aab0f38ec96abebc1d8d5e94b825eaef3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 15 Apr 2023 16:53:58 -0700 Subject: [PATCH 238/326] Move tone equalizer after exposure Place it between the shadows curve (black and shadow compression) and DCP tone curve and look table. Moving it after exposure makes it possible to easily adjust the exposure to the ball-park range before applying the tone equalizer. Keeping it before the tone curves allows it to affect the image before clipping occurs. --- rtengine/improcfun.cc | 134 +++++++++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 42 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index b417f00ce..19a1907da 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1979,7 +1979,9 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer stop.reset(new StopWatch("rgb processing")); } - Imagefloat *tmpImage = nullptr; + const bool split_tiled_parts_1_2 = params->toneEqualizer.enabled; + + std::unique_ptr tmpImage; Imagefloat* editImgFloat = nullptr; PlanarWhateverData* editWhatever = nullptr; @@ -2139,6 +2141,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer const float comp = (max(0.0, expcomp) + 1.0) * hlcompr / 100.0; const float shoulder = ((65536.f / max(1.0f, exp_scale)) * (hlcomprthresh / 200.f)) + 0.1f; const float hlrange = 65536.f - shoulder; + const int tone_curve_black = params->toneCurve.black; const bool isProPhoto = (params->icm.workingProfile == "ProPhoto"); // extracting data from 'params' to avoid cache flush (to be confirmed) ToneCurveMode curveMode = params->toneCurve.curveMode; @@ -2247,8 +2250,8 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer } bool hasgammabw = gammabwr != 1.f || gammabwg != 1.f || gammabwb != 1.f; - if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) { - tmpImage = new Imagefloat(working->getWidth(), working->getHeight()); + if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled) || split_tiled_parts_1_2) { + tmpImage.reset(new Imagefloat(working->getWidth(), working->getHeight())); } // For tonecurve histogram @@ -2263,15 +2266,53 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer // For tonecurve histogram const float lumimulf[3] = {static_cast(lumimul[0]), static_cast(lumimul[1]), static_cast(lumimul[2])}; - std::unique_ptr workimg_copy; - if (params->toneEqualizer.enabled) { - working = working->copy(); - workimg_copy.reset(working); - toneEqualizer(working); - } - #define TS 112 + const auto tiled_part_1 = + [working, + mixchannels, + &hltonecurve, &shtonecurve, + chMixRR, chMixRG, chMixRB, + chMixGR, chMixGG, chMixGB, + chMixBR, chMixBG, chMixBB, + exp_scale, comp, hlrange, tone_curve_black]( + int istart, int jstart, int tH, int tW, + float *rtemp, float *gtemp, float *btemp) { + + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + rtemp[ti * TS + tj] = working->r(i, j); + gtemp[ti * TS + tj] = working->g(i, j); + btemp[ti * TS + tj] = working->b(i, j); + } + } + + if (mixchannels) { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + float r = rtemp[ti * TS + tj]; + float g = gtemp[ti * TS + tj]; + float b = btemp[ti * TS + tj]; + + // if (i==100 & j==100) printf("rgbProc input R= %f G= %f B= %f \n",r,g,b); + float rmix = (r * chMixRR + g * chMixRG + b * chMixRB) / 100.f; + float gmix = (r * chMixGR + g * chMixGG + b * chMixGB) / 100.f; + float bmix = (r * chMixBR + g * chMixBG + b * chMixBB) / 100.f; + + rtemp[ti * TS + tj] = rmix; + gtemp[ti * TS + tj] = gmix; + btemp[ti * TS + tj] = bmix; + } + } + } + + highlightToneCurve(hltonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS, exp_scale, comp, hlrange); + + if (tone_curve_black != 0) { + shadowToneCurve(shtonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS); + } + }; + #ifdef _OPENMP #pragma omp parallel if (multiThread) #endif @@ -2322,6 +2363,41 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer histToneCurveThr.clear(); } + if (split_tiled_parts_1_2) { + +#ifdef _OPENMP + #pragma omp for schedule(dynamic, chunkSize) collapse(2) +#endif + + for (int ii = 0; ii < working->getHeight(); ii += TS) { + for (int jj = 0; jj < working->getWidth(); jj += TS) { + istart = ii; + jstart = jj; + tH = min(ii + TS, working->getHeight()); + tW = min(jj + TS, working->getWidth()); + + + tiled_part_1(istart, jstart, tH, tW, rtemp, gtemp, btemp); + + // Copy tile to image. + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + tmpImage->r(i, j) = rtemp[ti * TS + tj]; + tmpImage->g(i, j) = gtemp[ti * TS + tj]; + tmpImage->b(i, j) = btemp[ti * TS + tj]; + } + } + } + } + } + +#ifdef _OPENMP + #pragma omp single +#endif + if (params->toneEqualizer.enabled) { + toneEqualizer(tmpImage.get()); + } + #ifdef _OPENMP #pragma omp for schedule(dynamic, chunkSize) collapse(2) #endif @@ -2333,38 +2409,16 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer tH = min(ii + TS, working->getHeight()); tW = min(jj + TS, working->getWidth()); - - for (int i = istart, ti = 0; i < tH; i++, ti++) { - for (int j = jstart, tj = 0; j < tW; j++, tj++) { - rtemp[ti * TS + tj] = working->r(i, j); - gtemp[ti * TS + tj] = working->g(i, j); - btemp[ti * TS + tj] = working->b(i, j); - } - } - - if (mixchannels) { + if (split_tiled_parts_1_2) { for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float r = rtemp[ti * TS + tj]; - float g = gtemp[ti * TS + tj]; - float b = btemp[ti * TS + tj]; - - //if (i==100 & j==100) printf("rgbProc input R= %f G= %f B= %f \n",r,g,b); - float rmix = (r * chMixRR + g * chMixRG + b * chMixRB) / 100.f; - float gmix = (r * chMixGR + g * chMixGG + b * chMixGB) / 100.f; - float bmix = (r * chMixBR + g * chMixBG + b * chMixBB) / 100.f; - - rtemp[ti * TS + tj] = rmix; - gtemp[ti * TS + tj] = gmix; - btemp[ti * TS + tj] = bmix; + rtemp[ti * TS + tj] = tmpImage->r(i, j); + gtemp[ti * TS + tj] = tmpImage->g(i, j); + btemp[ti * TS + tj] = tmpImage->b(i, j); } } - } - - highlightToneCurve(hltonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS, exp_scale, comp, hlrange); - - if (params->toneCurve.black != 0.0) { - shadowToneCurve(shtonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS); + } else { + tiled_part_1(istart, jstart, tH, tW, rtemp, gtemp, btemp); } if (dcpProf) { @@ -3515,10 +3569,6 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer } - if (tmpImage) { - delete tmpImage; - } - if (hCurveEnabled) { delete hCurve; } From 3ea40d893e2645fa518642ed0c2fdd5eb26b5e34 Mon Sep 17 00:00:00 2001 From: Simon Segerblom Rex Date: Wed, 5 Apr 2023 17:42:14 +0200 Subject: [PATCH 239/326] dcraw.cc: Fix bug for tiff_ifd.new_sub_file_type This was regressed by bd118a4a40cd67f6d2e48db5655bd11d3aac0ff8. --- rtengine/dcraw.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 7a2a5b4d5..8f57800f9 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6812,17 +6812,17 @@ guess_cfa_pc: linear_table (len); break; case 50713: /* BlackLevelRepeatDim */ - if (tiff_ifd[ifd].new_sub_file_type != 0) continue; + if (tiff_ifd[ifd].new_sub_file_type != 0) break; cblack[4] = get2(); cblack[5] = get2(); if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) cblack[4] = cblack[5] = 1; break; case 61450: - if (tiff_ifd[ifd].new_sub_file_type != 0) continue; + if (tiff_ifd[ifd].new_sub_file_type != 0) break; cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ - if (tiff_ifd[ifd].new_sub_file_type != 0) continue; + if (tiff_ifd[ifd].new_sub_file_type != 0) break; RT_blacklevel_from_constant = ThreeValBool::F; //----------------------------------------------------------------------------- // taken from LibRaw. From 61b05f8504f7f175929881462039312f7f1a8c47 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:32:08 -0700 Subject: [PATCH 240/326] Fix crash with Fujifilm sports finder mode Handle heights and widths larger than raw heights and widths. Add camconst raw crop for certain Fujifilm cameras with sports finder mode on. --- rtengine/camconst.json | 5 ++++- rtengine/dcraw.cc | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ac3980bbe..d8f270aac 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1565,7 +1565,10 @@ Camera constants: { // Quality B "make_model": [ "FUJIFILM X-T30", "FUJIFILM X-T30 II", "FUJIFILM X100V", "FUJIFILM X-T4", "FUJIFILM X-S10" ], "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v11, standard_v2 d65 - "raw_crop": [ 0, 5, 6252, 4176] + "raw_crop": [ + {"frame": [6384, 3348], "crop": [624, 0, 5004, 3347]}, // Sports finder mode. + {"frame": [0, 0], "crop": [0, 5, 6252, 4176]} + ] }, { // Quality B diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 7a2a5b4d5..ce28bc228 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -4422,10 +4422,10 @@ void CLASS crop_masked_pixels() } } else { if (height + top_margin > raw_height) { - top_margin = raw_height - height; + top_margin = raw_height - MIN(height, raw_height); } if (width + left_margin > raw_width) { - left_margin = raw_width - width; + left_margin = raw_width - MIN(width, raw_width); } #ifdef _OPENMP #pragma omp parallel for @@ -10138,8 +10138,8 @@ canon_a5: width = raw_width = 5504; height = raw_height = 3856; } - top_margin = (raw_height - height) >> 2 << 1; - left_margin = (raw_width - width ) >> 2 << 1; + top_margin = (raw_height - MIN(height, raw_height)) >> 2 << 1; + left_margin = (raw_width - MIN(width, raw_width) ) >> 2 << 1; if (width == 2848 || width == 3664) filters = 0x16161616; if (width == 4032 || width == 4952 || width == 6032 || width == 8280) left_margin = 0; if (width == 3328 && (width -= 66)) left_margin = 34; From 91a07a2ac54c28375856133a89ebac9ef39f1e38 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:11:58 -0700 Subject: [PATCH 241/326] Add raw crop for Canon EOS R6 Mark II --- rtengine/camconst.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ac3980bbe..2b92cec89 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1258,6 +1258,18 @@ Camera constants: "ranges" : { "white" : 16382 } }, + { // Quality C + "make_model": "Canon EOS R6m2", + "raw_crop": [ + {"frame": [6188, 4120], "crop": [154, 96, 6028, 4024]}, + {"frame": [3936, 2612], "crop": [156, 96, 3780, 2516]} + ], + "masked_areas": [ + {"frame": [6188, 4120], "areas": [4, 4, 4116, 150, 4, 150, 92, 6184]}, + {"frame": [3936, 2612], "areas": [4, 4, 2608, 150, 4, 150, 92, 3932]} + ] + }, + { // Quality C "make_model": "Canon EOS R7", "dcraw_matrix" : [10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183], From 25082b6fc074a143b8d50dd45f261607871e14fd Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 28 Apr 2023 21:56:27 -0700 Subject: [PATCH 242/326] Add Canon EOS R6 Mark II color matrix --- rtengine/camconst.json | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 2b92cec89..e462c34bd 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1260,6 +1260,7 @@ Camera constants: { // Quality C "make_model": "Canon EOS R6m2", + "dcraw_matrix": [9539, -2795, -1224, -4175, 11998, 2458, -465, 1755, 6048], "raw_crop": [ {"frame": [6188, 4120], "crop": [154, 96, 6028, 4024]}, {"frame": [3936, 2612], "crop": [156, 96, 3780, 2516]} From f5dba61243611dfa580a5cf42164653d8d147d52 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 29 Apr 2023 18:43:38 -0700 Subject: [PATCH 243/326] Allow Lensfun DB dir editing from preferences Also refactor the file chooser button widget to share code with the file chooser entry. Use our own folder icon instead of the system one. --- rtdata/languages/default | 1 + rtgui/guiutils.cc | 387 +++++++++++++++++++++++---------------- rtgui/guiutils.h | 80 +++++--- rtgui/preferences.cc | 58 +++--- rtgui/preferences.h | 7 +- 5 files changed, 314 insertions(+), 219 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 45471bb5c..8fa85f144 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1913,6 +1913,7 @@ PREFERENCES_INTENT_SATURATION;Saturation PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited PREFERENCES_LANG;Language PREFERENCES_LANGAUTODETECT;Use system language +PREFERENCES_LENSFUNDBDIR;Lensfun database directory PREFERENCES_LENSPROFILESDIR;Lens profiles directory PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 18b82fe36..3581097ed 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1299,23 +1299,201 @@ bool MyHScale::on_key_press_event (GdkEventKey* event) } } -MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action): - title_(title), - action_(action), - lbl_("", Gtk::ALIGN_START), - show_hidden_(false) +class MyFileChooserWidget::Impl { - lbl_.set_ellipsize(Pango::ELLIPSIZE_MIDDLE); - lbl_.set_justify(Gtk::JUSTIFY_LEFT); - set_none(); - box_.pack_start(lbl_, true, true); - Gtk::Image *img = Gtk::manage(new Gtk::Image()); - img->set_from_icon_name("folder-open", Gtk::ICON_SIZE_BUTTON); - box_.pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), false, false, 5); - box_.pack_start(*img, false, false); - box_.show_all_children(); - add(box_); - signal_clicked().connect(sigc::mem_fun(*this, &MyFileChooserButton::show_chooser)); +public: + Impl(const Glib::ustring &title, Gtk::FileChooserAction action) : + title_(title), + action_(action) + { + } + + Glib::ustring title_; + Gtk::FileChooserAction action_; + std::string filename_; + std::string current_folder_; + std::vector> file_filters_; + Glib::RefPtr cur_filter_; + std::vector shortcut_folders_; + bool show_hidden_{false}; + sigc::signal selection_changed_; +}; + + +MyFileChooserWidget::MyFileChooserWidget(const Glib::ustring &title, Gtk::FileChooserAction action) : + pimpl(new Impl(title, action)) +{ +} + + +std::unique_ptr MyFileChooserWidget::make_folder_image() +{ + return std::unique_ptr(new RTImage("folder-open-small.png")); +} + +void MyFileChooserWidget::show_chooser(Gtk::Widget *parent) +{ + Gtk::FileChooserDialog dlg(getToplevelWindow(parent), pimpl->title_, pimpl->action_); + dlg.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); + dlg.add_button(M(pimpl->action_ == Gtk::FILE_CHOOSER_ACTION_SAVE ? "GENERAL_SAVE" : "GENERAL_OPEN"), Gtk::RESPONSE_OK); + dlg.set_filename(pimpl->filename_); + for (auto &f : pimpl->file_filters_) { + dlg.add_filter(f); + } + if (pimpl->cur_filter_) { + dlg.set_filter(pimpl->cur_filter_); + } + for (auto &f : pimpl->shortcut_folders_) { + dlg.add_shortcut_folder(f); + } + if (!pimpl->current_folder_.empty()) { + dlg.set_current_folder(pimpl->current_folder_); + } + dlg.set_show_hidden(pimpl->show_hidden_); + int res = dlg.run(); + if (res == Gtk::RESPONSE_OK) { + pimpl->filename_ = dlg.get_filename(); + pimpl->current_folder_ = dlg.get_current_folder(); + on_filename_set(); + pimpl->selection_changed_.emit(); + } +} + + +void MyFileChooserWidget::on_filename_set() +{ + // Sub-classes decide if anything needs to be done. +} + + +sigc::signal &MyFileChooserWidget::signal_selection_changed() +{ + return pimpl->selection_changed_; +} + + +sigc::signal &MyFileChooserWidget::signal_file_set() +{ + return pimpl->selection_changed_; +} + + +std::string MyFileChooserWidget::get_filename() const +{ + return pimpl->filename_; +} + + +bool MyFileChooserWidget::set_filename(const std::string &filename) +{ + pimpl->filename_ = filename; + on_filename_set(); + return true; +} + + +void MyFileChooserWidget::add_filter(const Glib::RefPtr &filter) +{ + pimpl->file_filters_.push_back(filter); +} + + +void MyFileChooserWidget::remove_filter(const Glib::RefPtr &filter) +{ + auto it = std::find(pimpl->file_filters_.begin(), pimpl->file_filters_.end(), filter); + if (it != pimpl->file_filters_.end()) { + pimpl->file_filters_.erase(it); + } +} + + +void MyFileChooserWidget::set_filter(const Glib::RefPtr &filter) +{ + pimpl->cur_filter_ = filter; +} + + +std::vector> MyFileChooserWidget::list_filters() const +{ + return pimpl->file_filters_; +} + + +bool MyFileChooserWidget::set_current_folder(const std::string &filename) +{ + pimpl->current_folder_ = filename; + if (pimpl->action_ == Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) { + set_filename(filename); + } + return true; +} + +std::string MyFileChooserWidget::get_current_folder() const +{ + return pimpl->current_folder_; +} + + +bool MyFileChooserWidget::add_shortcut_folder(const std::string &folder) +{ + pimpl->shortcut_folders_.push_back(folder); + return true; +} + + +bool MyFileChooserWidget::remove_shortcut_folder(const std::string &folder) +{ + auto it = std::find(pimpl->shortcut_folders_.begin(), pimpl->shortcut_folders_.end(), folder); + if (it != pimpl->shortcut_folders_.end()) { + pimpl->shortcut_folders_.erase(it); + } + return true; +} + + +void MyFileChooserWidget::unselect_all() +{ + pimpl->filename_ = ""; + on_filename_set(); +} + + +void MyFileChooserWidget::unselect_filename(const std::string &filename) +{ + if (pimpl->filename_ == filename) { + unselect_all(); + } +} + + +void MyFileChooserWidget::set_show_hidden(bool yes) +{ + pimpl->show_hidden_ = yes; +} + + +class MyFileChooserButton::Impl +{ +public: + Gtk::Box box_; + Gtk::Label lbl_{"", Gtk::ALIGN_START}; +}; + +MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action): + MyFileChooserWidget(title, action), + pimpl(new Impl()) +{ + pimpl->lbl_.set_ellipsize(Pango::ELLIPSIZE_MIDDLE); + pimpl->lbl_.set_justify(Gtk::JUSTIFY_LEFT); + on_filename_set(); + pimpl->box_.pack_start(pimpl->lbl_, true, true); + pimpl->box_.pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), false, false, 5); + pimpl->box_.pack_start(*Gtk::manage(make_folder_image().release()), false, false); + pimpl->box_.show_all_children(); + add(pimpl->box_); + signal_clicked().connect([this]() { + show_chooser(this); + }); if (GTK_MINOR_VERSION < 20) { set_border_width(2); // margin doesn't work on GTK < 3.20 @@ -1324,151 +1502,16 @@ MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileCh set_name("MyFileChooserButton"); } - -void MyFileChooserButton::show_chooser() +void MyFileChooserButton::on_filename_set() { - Gtk::FileChooserDialog dlg(getToplevelWindow(this), title_, action_); - dlg.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); - dlg.add_button(M(action_ == Gtk::FILE_CHOOSER_ACTION_SAVE ? "GENERAL_SAVE" : "GENERAL_OPEN"), Gtk::RESPONSE_OK); - dlg.set_filename(filename_); - for (auto &f : file_filters_) { - dlg.add_filter(f); - } - if (cur_filter_) { - dlg.set_filter(cur_filter_); - } - for (auto &f : shortcut_folders_) { - dlg.add_shortcut_folder(f); - } - if (!current_folder_.empty()) { - dlg.set_current_folder(current_folder_); - } - dlg.set_show_hidden(show_hidden_); - int res = dlg.run(); - if (res == Gtk::RESPONSE_OK) { - filename_ = dlg.get_filename(); - current_folder_ = dlg.get_current_folder(); - lbl_.set_label(Glib::path_get_basename(filename_)); - selection_changed_.emit(); - } -} - - -sigc::signal &MyFileChooserButton::signal_selection_changed() -{ - return selection_changed_; -} - - -sigc::signal &MyFileChooserButton::signal_file_set() -{ - return selection_changed_; -} - - -std::string MyFileChooserButton::get_filename() const -{ - return filename_; -} - - -bool MyFileChooserButton::set_filename(const std::string &filename) -{ - filename_ = filename; - if (Glib::file_test(filename_, Glib::FILE_TEST_EXISTS)) { - lbl_.set_label(Glib::path_get_basename(filename_)); + if (Glib::file_test(get_filename(), Glib::FILE_TEST_EXISTS)) { + pimpl->lbl_.set_label(Glib::path_get_basename(get_filename())); } else { - set_none(); - } - return true; -} - - -void MyFileChooserButton::add_filter(const Glib::RefPtr &filter) -{ - file_filters_.push_back(filter); -} - - -void MyFileChooserButton::remove_filter(const Glib::RefPtr &filter) -{ - auto it = std::find(file_filters_.begin(), file_filters_.end(), filter); - if (it != file_filters_.end()) { - file_filters_.erase(it); + pimpl->lbl_.set_label(Glib::ustring("(") + M("GENERAL_NONE") + ")"); } } -void MyFileChooserButton::set_filter(const Glib::RefPtr &filter) -{ - cur_filter_ = filter; -} - - -std::vector> MyFileChooserButton::list_filters() -{ - return file_filters_; -} - - -bool MyFileChooserButton::set_current_folder(const std::string &filename) -{ - current_folder_ = filename; - if (action_ == Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) { - set_filename(filename); - } - return true; -} - -std::string MyFileChooserButton::get_current_folder() const -{ - return current_folder_; -} - - -bool MyFileChooserButton::add_shortcut_folder(const std::string &folder) -{ - shortcut_folders_.push_back(folder); - return true; -} - - -bool MyFileChooserButton::remove_shortcut_folder(const std::string &folder) -{ - auto it = std::find(shortcut_folders_.begin(), shortcut_folders_.end(), folder); - if (it != shortcut_folders_.end()) { - shortcut_folders_.erase(it); - } - return true; -} - - -void MyFileChooserButton::unselect_all() -{ - filename_ = ""; - set_none(); -} - - -void MyFileChooserButton::unselect_filename(const std::string &filename) -{ - if (filename_ == filename) { - unselect_all(); - } -} - - -void MyFileChooserButton::set_show_hidden(bool yes) -{ - show_hidden_ = yes; -} - - -void MyFileChooserButton::set_none() -{ - lbl_.set_label(Glib::ustring("(") + M("GENERAL_NONE") + ")"); -} - // For an unknown reason (a bug ?), it doesn't work when action = FILE_CHOOSER_ACTION_SELECT_FOLDER ! bool MyFileChooserButton::on_scroll_event (GdkEventScroll* event) { @@ -1493,6 +1536,40 @@ void MyFileChooserButton::get_preferred_width_for_height_vfunc (int height, int } +class MyFileChooserEntry::Impl +{ +public: + Gtk::Entry entry; + Gtk::Button file_chooser_button; +}; + + +MyFileChooserEntry::MyFileChooserEntry(const Glib::ustring &title, Gtk::FileChooserAction action) : + MyFileChooserWidget(title, action), + pimpl(new Impl()) +{ + pimpl->file_chooser_button.set_image(*Gtk::manage(make_folder_image().release())); + pimpl->file_chooser_button.signal_clicked().connect([this]() { + const auto &filename = pimpl->entry.get_text(); + if (Glib::file_test(filename, Glib::FILE_TEST_IS_DIR)) { + set_current_folder(filename); + } + set_filename(filename); + show_chooser(this); + }); + + pack_start(pimpl->entry, true, true); + pack_start(pimpl->file_chooser_button, false, false); +} + + +void MyFileChooserEntry::on_filename_set() +{ + if (pimpl->entry.get_text() != get_filename()) { + pimpl->entry.set_text(get_filename()); + } +} + TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 152b626de..58877aed4 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -396,34 +396,10 @@ protected: }; -/** - * @brief subclass of Gtk::FileChooserButton in order to handle the scrollwheel - */ -class MyFileChooserButton final : public Gtk::Button { -private: - void show_chooser(); - - Glib::ustring title_; - Gtk::FileChooserAction action_; - Gtk::Box box_; - Gtk::Label lbl_; - std::string filename_; - std::string current_folder_; - std::vector> file_filters_; - Glib::RefPtr cur_filter_; - std::vector shortcut_folders_; - bool show_hidden_; - sigc::signal selection_changed_; - -protected: - bool on_scroll_event (GdkEventScroll* event) override; - void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; - void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; - - void set_none(); - +class MyFileChooserWidget +{ public: - explicit MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + virtual ~MyFileChooserWidget() = default; sigc::signal &signal_selection_changed(); sigc::signal &signal_file_set(); @@ -434,7 +410,7 @@ public: void add_filter(const Glib::RefPtr &filter); void remove_filter(const Glib::RefPtr &filter); void set_filter(const Glib::RefPtr &filter); - std::vector> list_filters(); + std::vector> list_filters() const; bool set_current_folder(const std::string &filename); std::string get_current_folder() const; @@ -446,6 +422,54 @@ public: void unselect_filename(const std::string &filename); void set_show_hidden(bool yes); + +protected: + explicit MyFileChooserWidget(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + + static std::unique_ptr make_folder_image(); + + void show_chooser(Gtk::Widget *parent); + virtual void on_filename_set(); + +private: + class Impl; + + std::unique_ptr pimpl; +}; + +/** + * @brief subclass of Gtk::FileChooserButton in order to handle the scrollwheel + */ +class MyFileChooserButton final : public Gtk::Button, public MyFileChooserWidget +{ +private: + class Impl; + + std::unique_ptr pimpl; + +protected: + bool on_scroll_event (GdkEventScroll* event) override; + void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; + void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; + + void on_filename_set() override; + +public: + explicit MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); +}; + +class MyFileChooserEntry : public Gtk::Box, public MyFileChooserWidget +{ +public: + explicit MyFileChooserEntry(const Glib::ustring &title, Gtk::FileChooserAction action = Gtk::FILE_CHOOSER_ACTION_OPEN); + +protected: + void on_filename_set() override; + +private: + class Impl; + + std::unique_ptr pimpl; }; /** diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 1ae01da2d..1e652faf4 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -667,7 +667,19 @@ Gtk::Widget* Preferences::getImageProcessingPanel () dirgrid->attach_next_to(*lensProfilesDirLabel, *cameraProfilesDirLabel, Gtk::POS_BOTTOM, 1, 1); dirgrid->attach_next_to(*lensProfilesDir, *lensProfilesDirLabel, Gtk::POS_RIGHT, 1, 1); - //Pack directories to Image Processing panel + // Lensfun DB dir + Gtk::Label *lensfunDbDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSFUNDBDIR") + ":")); + setExpandAlignProperties(lensfunDbDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + lensfunDbDir = Gtk::manage(new MyFileChooserEntry(M("PREFERENCES_LENSFUNDBDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(lensfunDbDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Label* lensfunDbDirRestartNeededLabel = Gtk::manage(new Gtk::Label(Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")")); + setExpandAlignProperties(lensfunDbDirRestartNeededLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + dirgrid->attach_next_to(*lensfunDbDirLabel, *lensProfilesDirLabel, Gtk::POS_BOTTOM, 1, 1); + dirgrid->attach_next_to(*lensfunDbDir, *lensfunDbDirLabel, Gtk::POS_RIGHT, 1, 1); + dirgrid->attach_next_to(*lensfunDbDirRestartNeededLabel, *lensfunDbDir, Gtk::POS_RIGHT, 1, 1); + + //Pack directories to Image Processing panel cdf->add(*dirgrid); vbImageProcessing->pack_start (*cdf, Gtk::PACK_SHRINK, 4 ); @@ -1315,10 +1327,7 @@ Gtk::Widget* Preferences::getFileBrowserPanel() sdlast = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_DIRLAST"))); sdhome = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_DIRHOME"))); sdother = Gtk::manage(new Gtk::RadioButton(M("PREFERENCES_DIROTHER") + ": ")); - startupdir = Gtk::manage(new Gtk::Entry()); - - Gtk::Button* sdselect = Gtk::manage(new Gtk::Button()); - sdselect->set_image (*Gtk::manage (new RTImage ("folder-open-small.png"))); + startupdir = Gtk::manage(new MyFileChooserEntry(M("PREFERENCES_DIRSELECTDLG"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::RadioButton::Group opts = sdcurrent->get_group(); sdlast->set_group(opts); @@ -1332,14 +1341,11 @@ Gtk::Widget* Preferences::getFileBrowserPanel() Gtk::Box* otherbox = Gtk::manage(new Gtk::Box()); otherbox->pack_start(*sdother, Gtk::PACK_SHRINK); otherbox->pack_start(*startupdir); - otherbox->pack_end(*sdselect, Gtk::PACK_SHRINK, 4); vbsd->pack_start(*otherbox, Gtk::PACK_SHRINK, 0); fsd->add(*vbsd); vbFileBrowser->pack_start (*fsd, Gtk::PACK_SHRINK, 4); - sdselect->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::selectStartupDir)); - //--- @@ -1839,7 +1845,7 @@ void Preferences::storePreferences() moptions.startupDir = STARTUPDIR_LAST; } else if (sdother->get_active()) { moptions.startupDir = STARTUPDIR_CUSTOM; - moptions.startupPath = startupdir->get_text(); + moptions.startupPath = startupdir->get_filename(); } moptions.parseExtensions.clear(); @@ -1868,8 +1874,9 @@ void Preferences::storePreferences() moptions.rtSettings.darkFramesPath = darkFrameDir->get_filename(); moptions.rtSettings.flatFieldsPath = flatFieldDir->get_filename(); moptions.clutsDir = clutsDir->get_filename(); - moptions.rtSettings.cameraProfilesPath = cameraProfilesDir->get_filename(); - moptions.rtSettings.lensProfilesPath = lensProfilesDir->get_filename(); + moptions.rtSettings.cameraProfilesPath = cameraProfilesDir->get_filename(); + moptions.rtSettings.lensProfilesPath = lensProfilesDir->get_filename(); + moptions.rtSettings.lensfunDbDirectory = lensfunDbDir->get_filename(); moptions.baBehav.resize(ADDSET_PARAM_NUM); @@ -2065,7 +2072,7 @@ void Preferences::fillPreferences() sdhome->set_active(); } else if (moptions.startupDir == STARTUPDIR_CUSTOM) { sdother->set_active(); - startupdir->set_text(moptions.startupPath); + startupdir->set_current_folder(moptions.startupPath); } extensionModel->clear(); @@ -2125,10 +2132,12 @@ void Preferences::fillPreferences() flatFieldChanged(); clutsDir->set_current_folder(moptions.clutsDir); - - cameraProfilesDir->set_current_folder(moptions.rtSettings.cameraProfilesPath); - - lensProfilesDir->set_current_folder(moptions.rtSettings.lensProfilesPath); + + cameraProfilesDir->set_current_folder(moptions.rtSettings.cameraProfilesPath); + + lensProfilesDir->set_current_folder(moptions.rtSettings.lensProfilesPath); + + lensfunDbDir->set_current_folder(moptions.rtSettings.lensfunDbDirectory); addc.block(true); setc.block(true); @@ -2257,23 +2266,6 @@ void Preferences::cancelPressed() hide(); } -void Preferences::selectStartupDir() -{ - - Gtk::FileChooserDialog dialog(getToplevelWindow(this), M("PREFERENCES_DIRSELECTDLG"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); - //dialog.set_transient_for(*this); - - //Add response buttons to the dialog: - dialog.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); - dialog.add_button(M("GENERAL_OPEN"), Gtk::RESPONSE_OK); - - int result = dialog.run(); - - if (result == Gtk::RESPONSE_OK) { - startupdir->set_text(dialog.get_filename()); - } -} - void Preferences::aboutPressed() { diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 6e31761a4..821842773 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -92,7 +92,7 @@ class Preferences final : Gtk::ComboBoxText* languages; Gtk::CheckButton* ckbLangAutoDetect; Gtk::Entry* dateformat; - Gtk::Entry* startupdir; + MyFileChooserEntry* startupdir; Gtk::RadioButton* sdcurrent; Gtk::RadioButton* sdlast; Gtk::RadioButton* sdhome; @@ -115,8 +115,9 @@ class Preferences final : MyFileChooserButton* darkFrameDir; MyFileChooserButton* flatFieldDir; MyFileChooserButton* clutsDir; - MyFileChooserButton* cameraProfilesDir; - MyFileChooserButton* lensProfilesDir; + MyFileChooserButton* cameraProfilesDir; + MyFileChooserButton* lensProfilesDir; + MyFileChooserEntry* lensfunDbDir; Gtk::Label *dfLabel; Gtk::Label *ffLabel; From 45a3b36b3aadbaa3adbbedbc47738467c5bd6501 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 30 Apr 2023 12:30:46 -0700 Subject: [PATCH 244/326] Fix file chooser entry not updating Save file name while it is typed in the text entry. Add placeholder text for Lensfun database directory to indicate automatic detection if left blank. --- rtgui/guiutils.cc | 21 +++++++++++++++++++-- rtgui/guiutils.h | 3 +++ rtgui/preferences.cc | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 3581097ed..a0317d226 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1548,13 +1548,18 @@ MyFileChooserEntry::MyFileChooserEntry(const Glib::ustring &title, Gtk::FileChoo MyFileChooserWidget(title, action), pimpl(new Impl()) { + const auto on_text_changed = [this]() { + set_filename(pimpl->entry.get_text()); + }; + pimpl->entry.get_buffer()->signal_deleted_text().connect([on_text_changed](guint, guint) { on_text_changed(); }); + pimpl->entry.get_buffer()->signal_inserted_text().connect([on_text_changed](guint, const gchar *, guint) { on_text_changed(); }); + pimpl->file_chooser_button.set_image(*Gtk::manage(make_folder_image().release())); pimpl->file_chooser_button.signal_clicked().connect([this]() { - const auto &filename = pimpl->entry.get_text(); + const auto &filename = get_filename(); if (Glib::file_test(filename, Glib::FILE_TEST_IS_DIR)) { set_current_folder(filename); } - set_filename(filename); show_chooser(this); }); @@ -1563,6 +1568,18 @@ MyFileChooserEntry::MyFileChooserEntry(const Glib::ustring &title, Gtk::FileChoo } +Glib::ustring MyFileChooserEntry::get_placeholder_text() const +{ + return pimpl->entry.get_placeholder_text(); +} + + +void MyFileChooserEntry::set_placeholder_text(const Glib::ustring &text) +{ + pimpl->entry.set_placeholder_text(text); +} + + void MyFileChooserEntry::on_filename_set() { if (pimpl->entry.get_text() != get_filename()) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 58877aed4..8bc047bf7 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -463,6 +463,9 @@ class MyFileChooserEntry : public Gtk::Box, public MyFileChooserWidget public: explicit MyFileChooserEntry(const Glib::ustring &title, Gtk::FileChooserAction action = Gtk::FILE_CHOOSER_ACTION_OPEN); + Glib::ustring get_placeholder_text() const; + void set_placeholder_text(const Glib::ustring &text); + protected: void on_filename_set() override; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 1e652faf4..da8272442 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -671,6 +671,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () Gtk::Label *lensfunDbDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSFUNDBDIR") + ":")); setExpandAlignProperties(lensfunDbDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); lensfunDbDir = Gtk::manage(new MyFileChooserEntry(M("PREFERENCES_LENSFUNDBDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + lensfunDbDir->set_placeholder_text(Glib::ustring::compose("(%1)", M("GENERAL_AUTO"))); setExpandAlignProperties(lensfunDbDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); Gtk::Label* lensfunDbDirRestartNeededLabel = Gtk::manage(new Gtk::Label(Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")")); setExpandAlignProperties(lensfunDbDirRestartNeededLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); From 8c98925f3d744d9cd9b4b044d9b7b2824e958994 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 12 May 2023 22:44:04 -0700 Subject: [PATCH 245/326] Get lens name from EXIF group for ILCE/NEX cameras Fix incorrect lens name read in certain cases from Sony cameras (see https://discuss.pixls.us/t/call-for-testing-rawtherapee-metadata-handling-with-exiv2-includes-cr3-support/36240/87). --- rtengine/imagedata.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 168177876..71d5c5693 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -336,9 +336,20 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } } } else if (!make.compare(0, 4, "SONY")) { - if (find_exif_tag("Exif.Sony2.LensID") && pos->toLong()) { + // ExifTool prefers LensType2 over LensType (called + // Exif.Sony2.LensID by Exiv2). Exiv2 doesn't support LensType2 yet, + // so we let Exiv2 try it's best. For non ILCE/NEX cameras which + // likely don't have LensType2, we use Exif.Sony2.LensID because + // Exif.Photo.LensModel may be incorrect (see + // https://discuss.pixls.us/t/call-for-testing-rawtherapee-metadata-handling-with-exiv2-includes-cr3-support/36240/36). + if ( + // Camera model is neither a ILCE nor NEX. + (!find_exif_tag("Exif.Image.Model") || + (pos->toString().compare(0, 4, "ILCE") && pos->toString().compare(0, 3, "NEX"))) && + // LensID exists. + find_exif_tag("Exif.Sony2.LensID") && pos->toLong()) { lens = pos->print(&exif); - if (lens == std::to_string(pos->toLong())) { // Not know to Exiv2. + if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. lens.clear(); } else { lens = validateUft8(lens); From 81a3ba558e65e0464edd49d67fcc771814db2fd5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 12 May 2023 22:50:53 -0700 Subject: [PATCH 246/326] Update Exiv2 to v0.28.0 for AppImage --- .github/workflows/appimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 292ce862f..d50628902 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -34,7 +34,7 @@ jobs: - name: Install Exiv2 run: | - EXIV2_VERSION='v0.27.6' + EXIV2_VERSION='v0.28.0' echo "Cloning Exiv2 $EXIV2_VERSION." git clone --depth 1 --branch "$EXIV2_VERSION" https://github.com/Exiv2/exiv2.git ext/exiv2 From e4690e73a33a069a72da2619189a16f44c1174ba Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 12 May 2023 23:14:58 -0700 Subject: [PATCH 247/326] Add missing build dependency for AppImage --- .github/workflows/appimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index d50628902..fae43ed25 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -30,7 +30,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 + 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 - name: Install Exiv2 run: | From 0ac49e4d9a111ac03b275ef0718a0ed44162ca43 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 May 2023 15:31:14 -0700 Subject: [PATCH 248/326] Support Exiv2 >= v0.28.0 The various Datum classes no longer have the toLong method and must be replaced with toInt64. ErrorCode is an enum class instead of an enum. Error classes are reduced to Exiv2::Error. --- rtengine/imagedata.cc | 65 ++++++++++++++++++++++++++----------------- rtengine/imageio.cc | 15 +++++++++- rtengine/metadata.cc | 36 ++++++++++++++++++++---- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 71d5c5693..4ff918c21 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -50,6 +50,19 @@ const std::string& validateUft8(const std::string& str, const std::string& on_er return on_error; } +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 { @@ -269,7 +282,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : const int length = 12; if (pos->count() >= index + length) { for (int i = 0; i < length; ++i) { - serial += static_cast(pos->toLong(index + i)); + serial += static_cast(to_long(pos, index + i)); } serial = validateUft8(serial); } @@ -313,7 +326,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : "Rotate 270 CW", "Unknown" }; - auto idx = pos->toLong(); + auto idx = to_long(pos); if (idx >= 0 && idx < long(ormap.size())) { orientation = ormap[idx]; } @@ -322,14 +335,14 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : if (!make.compare(0, 5, "NIKON")) { if (find_exif_tag("Exif.NikonLd4.LensID")) { - if (!pos->toLong()) { // No data, look in LensIDNumber. + if (!to_long(pos)) { // No data, look in LensIDNumber. const auto p = pos; if (!find_exif_tag("Exif.NikonLd4.LensIDNumber")) { pos = p; // Tag not found, so reset pos. } } lens = pos->print(&exif); - if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. + if (lens == std::to_string(to_long(pos))) { // Not known to Exiv2. lens.clear(); } else { lens = validateUft8(lens); @@ -347,9 +360,9 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : (!find_exif_tag("Exif.Image.Model") || (pos->toString().compare(0, 4, "ILCE") && pos->toString().compare(0, 3, "NEX"))) && // LensID exists. - find_exif_tag("Exif.Sony2.LensID") && pos->toLong()) { + find_exif_tag("Exif.Sony2.LensID") && to_long(pos)) { lens = pos->print(&exif); - if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. + if (lens == std::to_string(to_long(pos))) { // Not known to Exiv2. lens.clear(); } else { lens = validateUft8(lens); @@ -363,7 +376,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); - } else if (p->count() == 1 && lens == std::to_string(p->toLong())) { + } else if (p->count() == 1 && lens == std::to_string(to_long(p))) { if (find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); } else if (find_exif_tag("Exif.Photo.LensModel")) { @@ -421,11 +434,11 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } if (find_exif_tag("Exif.Image.Rating")) { - rating = pos->toLong(); + rating = to_long(pos); } else { auto it = meta.xmpData().findKey(Exiv2::XmpKey("Xmp.xmp.Rating")); if (it != meta.xmpData().end() && it->size()) { - rating = it->toLong(); + rating = to_long(it); } } @@ -501,8 +514,8 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : || find_exif_tag("Exif.PentaxDng.Quality") ) && ( - pos->toLong() == 7 - || pos->toLong() == 8 + to_long(pos) == 7 + || to_long(pos) == 8 ) ) { isPixelShift = true; @@ -513,23 +526,23 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } if (make == "SONY") { - if (find_exif_tag("Exif.SubImage1.BitsPerSample") && pos->toLong() == 14) { - if (find_exif_tag("Exif.SubImage1.SamplesPerPixel") && pos->toLong() == 4 && - find_exif_tag("Exif.SubImage1.PhotometricInterpretation") && pos->toLong() == 32892 && - find_exif_tag("Exif.SubImage1.Compression") && pos->toLong() == 1) { + if (find_exif_tag("Exif.SubImage1.BitsPerSample") && to_long(pos) == 14) { + if (find_exif_tag("Exif.SubImage1.SamplesPerPixel") && to_long(pos) == 4 && + find_exif_tag("Exif.SubImage1.PhotometricInterpretation") && to_long(pos) == 32892 && + find_exif_tag("Exif.SubImage1.Compression") && to_long(pos) == 1) { isPixelShift = true; } - } else if (bps != exif.end() && bps->toLong() == 14 && - spp != exif.end() && spp->toLong() == 4 && - c != exif.end() && c->toLong() == 1 && + } else if (bps != exif.end() && to_long(bps) == 14 && + spp != exif.end() && to_long(spp) == 4 && + c != exif.end() && to_long(c) == 1 && find_exif_tag("Exif.Image.Software") && pos->toString() == "make_arq") { isPixelShift = true; } } else if (make == "FUJIFILM") { - if (bps != exif.end() && bps->toLong() == 16 && - spp != exif.end() && spp->toLong() == 4 && - c != exif.end() && c->toLong() == 1 && + if (bps != exif.end() && to_long(bps) == 16 && + spp != exif.end() && to_long(spp) == 4 && + c != exif.end() && to_long(c) == 1 && find_exif_tag("Exif.Image.Software") && pos->toString() == "make_arq") { isPixelShift = true; @@ -548,22 +561,22 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : { sampleformat = SAMPLEFORMAT_UINT; } else { - sampleformat = sf->toLong(); + sampleformat = to_long(sf); } if (bps == exif.end() || spp == exif.end() || pi == exif.end()) { return; } - bitspersample = bps->toLong(); - samplesperpixel = spp->toLong(); + bitspersample = to_long(bps); + samplesperpixel = to_long(spp); - photometric = pi->toLong(); + photometric = to_long(pi); if (photometric == PHOTOMETRIC_LOGLUV) { if (c == exif.end()) { compression = COMPRESSION_NONE; } else { - compression = c->toLong(); + compression = to_long(c); } } diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 0388467be..1c8e9016d 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -86,6 +86,19 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) return f; } +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 +} + } void ImageIO::setMetadata(Exiv2Metadata info) @@ -1185,7 +1198,7 @@ int ImageIO::saveTIFF ( } it = exif.findKey(Exiv2::ExifKey("Exif.Image.ResolutionUnit")); if (it != exif.end()) { - res_unit = it->toLong(); + res_unit = to_long(it); } } TIFFSetField(out, TIFFTAG_XRESOLUTION, x_res); diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 28a9c1742..0a55c1424 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -31,6 +31,13 @@ #include "../rtgui/pathutils.h" +#if EXIV2_TEST_VERSION(0,28,0) +using Exiv2Error = Exiv2::Error; +#else +using Exiv2Error = Exiv2::AnyError; +#endif + + namespace rtengine { extern const Settings *settings; @@ -39,9 +46,13 @@ std::unique_ptr Exiv2Metadata::cache_(nullptr); namespace { -class Error: public Exiv2::AnyError { +class Error: public Exiv2Error { public: - Error(const std::string &msg): msg_(msg) {} + Error(const std::string &msg): +#if EXIV2_TEST_VERSION(0,28,0) + Exiv2Error(Exiv2::ErrorCode::kerGeneralError), +#endif + msg_(msg) {} const char *what() const throw() { return msg_.c_str(); } int code() const throw() { return 0; } @@ -71,7 +82,7 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname, image->readMetadata(); if (!image->good() || (check_exif && image->exifData().empty())) { #if EXIV2_TEST_VERSION(0,27,0) - auto error_code = Exiv2::kerErrorMessage; + auto error_code = Exiv2::ErrorCode::kerErrorMessage; #else auto error_code = 1; #endif @@ -95,6 +106,19 @@ 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 @@ -297,7 +321,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag dst->writeMetadata(); return; } catch (Exiv2::Error &exc) { - if (exc.code() == 37) { + if (exc.code() == Exiv2::ErrorCode::kerTooLargeJpegSegment) { std::string msg = exc.what(); if (msg.find("XMP") != std::string::npos && !dst->xmpData().empty()) { @@ -519,8 +543,8 @@ void Exiv2Metadata::getDimensions(int &w, int &h) const auto itw = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth")); auto ith = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageLength")); if (itw != exif.end() && ith != exif.end()) { - w = itw->toLong(); - h = ith->toLong(); + w = to_long(itw); + h = to_long(ith); } else { w = h = -1; } From bcf9b86dcfc18a15f3f863407f613c9f4f75775e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 May 2023 17:36:22 -0700 Subject: [PATCH 249/326] Add Sony ZV-1 color matrix and black level --- rtengine/camconst.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 936a413e7..393438918 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -3139,6 +3139,12 @@ Camera constants: "dcraw_matrix": [ 6344, -1612, -462, -4863, 12477, 2681, -865, 1786, 6899 ] // DNG }, + { // Quality C + "make_model": "Sony ZV-1", + "dcraw_matrix": [ 8280, -2987, -703, -3531, 11645, 2133, -550, 1542, 5312 ], // DNG v15.2 + "ranges": { "black": 800 } + }, + { // Quality C, No proper color data, beta samples, frame set to official jpeg, "make_model": [ "XIAOYI M1", "YI TECHNOLOGY M1" ], "dcraw_matrix": [ 7158,-1911,-606,-3603,10669,2530,-659,1236,5530 ], // XIAO YI DNG D65 From 572a75f02a25111fbc1b2163c4ae3c801ef9a879 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 May 2023 11:06:23 -0700 Subject: [PATCH 250/326] Fix lens model reading for Sony ILMEs and ZV-E10 Use lens model from the EXIF group for these cameras. --- rtengine/imagedata.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4ff918c21..430559f3d 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -356,11 +356,11 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : // Exif.Photo.LensModel may be incorrect (see // https://discuss.pixls.us/t/call-for-testing-rawtherapee-metadata-handling-with-exiv2-includes-cr3-support/36240/36). if ( - // Camera model is neither a ILCE nor NEX. + // Camera model is neither a ILCE, ILME, nor NEX. (!find_exif_tag("Exif.Image.Model") || - (pos->toString().compare(0, 4, "ILCE") && pos->toString().compare(0, 3, "NEX"))) && - // LensID exists. - find_exif_tag("Exif.Sony2.LensID") && to_long(pos)) { + (pos->toString().compare(0, 4, "ILCE") && pos->toString().compare(0, 4, "ILME") && pos->toString().compare(0, 3, "NEX"))) && + // LensID exists. 0xFFFF could be one of many lenses. + find_exif_tag("Exif.Sony2.LensID") && to_long(pos) && to_long(pos) != 0xFFFF) { lens = pos->print(&exif); if (lens == std::to_string(to_long(pos))) { // Not known to Exiv2. lens.clear(); From 68ae17a64082cb520c7ef3a2fc546acd7f9f6a17 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 May 2023 12:14:33 -0700 Subject: [PATCH 251/326] Add PDAF pattern for Sony ZV-1 --- rtengine/camconst.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 393438918..352dc26e1 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -3139,10 +3139,13 @@ Camera constants: "dcraw_matrix": [ 6344, -1612, -462, -4863, 12477, 2681, -865, 1786, 6899 ] // DNG }, - { // Quality C + { // Quality A "make_model": "Sony ZV-1", "dcraw_matrix": [ 8280, -2987, -703, -3531, 11645, 2133, -550, 1542, 5312 ], // DNG v15.2 - "ranges": { "black": 800 } + "ranges": { "black": 800 }, // White level from EXIF. + "raw_crop": [ 0, 0, 5496, 3672 ], + "pdaf_pattern": [0, 24, 48, 72, 88, 120], + "pdaf_offset": 17 }, { // Quality C, No proper color data, beta samples, frame set to official jpeg, From c557b320c24adc83f3934d0c81acd82a87f7c221 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 May 2023 18:18:27 -0700 Subject: [PATCH 252/326] Refresh cached image data if sidecar is changed --- rtgui/cacheimagedata.cc | 17 +++++++++++++++++ rtgui/cacheimagedata.h | 3 +++ rtgui/cachemanager.cc | 17 ++++++++++++++++- rtgui/cachemanager.h | 2 ++ rtgui/thumbnail.cc | 16 +++++++++++++--- rtgui/thumbnail.h | 5 ++++- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 365b8f1b7..bfc4e920a 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -26,6 +26,15 @@ #include "../rtengine/procparams.h" #include "../rtengine/settings.h" + +namespace +{ + +const Glib::ustring INI_GROUP_XMP_SIDECAR = "XmpSidecar"; +const Glib::ustring INI_XMP_SIDECAR_MD5 = "MD5"; + +} + CacheImageData::CacheImageData() : supported(false), format(FT_Invalid), @@ -108,6 +117,12 @@ int CacheImageData::load (const Glib::ustring& fname) } } + if (keyFile.has_group(INI_GROUP_XMP_SIDECAR)) { + if (keyFile.has_key(INI_GROUP_XMP_SIDECAR, INI_XMP_SIDECAR_MD5)) { + xmpSidecarMd5 = keyFile.get_string(INI_GROUP_XMP_SIDECAR, INI_XMP_SIDECAR_MD5); + } + } + timeValid = keyFile.has_group ("DateTime"); if (timeValid) { @@ -268,6 +283,8 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); keyFile.set_integer ("General", "Rating", rating); + keyFile.set_string(INI_GROUP_XMP_SIDECAR, INI_XMP_SIDECAR_MD5, xmpSidecarMd5); + // remove the old implementation of Rank and InTrash from cache if (keyFile.has_key ("General", "Rank")) { keyFile.remove_key("General", "Rank"); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index cb02b9169..8c0fa6513 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -39,6 +39,9 @@ public: bool inTrashOld; // old implementation of inTrash bool recentlySaved; + // XMP sidecar info. + Glib::ustring xmpSidecarMd5; + // time/date info bool timeValid; short year; diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index 5e540b604..4d865ce76 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -97,6 +97,10 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) } const auto cacheName = getCacheFileName ("data", fname, ".txt", md5); + const auto xmpSidecarMd5 = + rtengine::settings->metadata_xmp_sync != rtengine::Settings::MetadataXmpSync::NONE + ? getMD5(Thumbnail::xmpSidecarPath(fname)) + : ""; // let's see if we have it in the cache { @@ -106,6 +110,11 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) if (error == 0 && imageData.supported) { + if (xmpSidecarMd5 != imageData.xmpSidecarMd5) { + updateImageInfo(fname, imageData, xmpSidecarMd5); + imageData.save(cacheName); + } + thumbnail.reset (new Thumbnail (this, fname, &imageData)); if (!thumbnail->isSupported ()) { @@ -117,7 +126,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) // if not, create a new one if (!thumbnail) { - thumbnail.reset (new Thumbnail (this, fname, md5)); + thumbnail.reset (new Thumbnail (this, fname, md5, xmpSidecarMd5)); if (!thumbnail->isSupported ()) { thumbnail.reset (); @@ -413,3 +422,9 @@ void CacheManager::applyCacheSizeLimitation () const } } +void CacheManager::updateImageInfo(const Glib::ustring &fname, CacheImageData &imageData, const Glib::ustring &xmpSidecarMd5) const +{ + Thumbnail::infoFromImage(fname, imageData); + imageData.xmpSidecarMd5 = xmpSidecarMd5; +} + diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h index 61602aeba..a7ab14f0a 100644 --- a/rtgui/cachemanager.h +++ b/rtgui/cachemanager.h @@ -27,6 +27,7 @@ #include "../rtengine/noncopyable.h" +class CacheImageData; class Thumbnail; class CacheManager : @@ -42,6 +43,7 @@ private: void deleteFiles (const Glib::ustring& fname, const std::string& md5, bool purgeData, bool purgeProfile) const; void applyCacheSizeLimitation () const; + void updateImageInfo(const Glib::ustring &fname, CacheImageData &imageData, const Glib::ustring &xmpSidecarMd5) const; public: static CacheManager* getInstance (); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index ce262206f..a2941aaa5 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -148,7 +148,7 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageDat tpp = nullptr; } -Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, const std::string& md5) : +Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, const std::string& md5, const std::string &xmpSidecarMd5) : fname(fname), cachemgr(cm), ref(1), @@ -166,6 +166,7 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, const std::st cfs.md5 = md5; + cfs.xmpSidecarMd5 = xmpSidecarMd5; loadProcParams (); _generateThumbnailImage (); cfs.recentlySaved = false; @@ -176,6 +177,11 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, const std::st tpp = nullptr; } +Glib::ustring Thumbnail::xmpSidecarPath(const Glib::ustring &imagePath) +{ + return rtengine::Exiv2Metadata::xmpSidecarPath(imagePath); +} + void Thumbnail::_generateThumbnailImage () { @@ -852,7 +858,12 @@ ThFileType Thumbnail::getType () const int Thumbnail::infoFromImage (const Glib::ustring& fname) { - rtengine::FramesMetaData* idata = rtengine::FramesMetaData::fromFile (fname); + return infoFromImage(fname, cfs); +} + +int Thumbnail::infoFromImage(const Glib::ustring &fname, CacheImageData &cfs) +{ + std::unique_ptr idata(rtengine::FramesMetaData::fromFile (fname)); if (!idata) { return 0; @@ -915,7 +926,6 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname) idata->getDimensions(cfs.width, cfs.height); - delete idata; return deg; } diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index e071fdd9f..9ead1e5e8 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -93,9 +93,12 @@ class Thumbnail public: Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); - Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5); + Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5, const std::string &xmpSidecarMd5); ~Thumbnail (); + static int infoFromImage(const Glib::ustring &fname, CacheImageData &cfs); + static Glib::ustring xmpSidecarPath(const Glib::ustring &imagePath); + bool hasProcParams () const; const rtengine::procparams::ProcParams& getProcParams (); const rtengine::procparams::ProcParams& getProcParamsU (); // Unprotected version From a1bbc93538b1a1a8737702b6c79a203fc346e77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Sun, 21 May 2023 18:25:42 -0400 Subject: [PATCH 253/326] Fix missing explicit include (#6704) * Fix missing explicit include - Also avoid rtgui include * Fix more missing explicit include --- rtengine/alpha.h | 2 +- rtengine/dcrop.cc | 3 +++ rtengine/iccstore.cc | 1 + rtengine/init.cc | 3 ++- rtengine/profilestore.cc | 3 +++ rtengine/profilestore.h | 1 + rtgui/editcallbacks.h | 2 ++ rtgui/options.cc | 4 ++++ 8 files changed, 17 insertions(+), 2 deletions(-) diff --git a/rtengine/alpha.h b/rtengine/alpha.h index 1fe2a7a7c..314dac642 100644 --- a/rtengine/alpha.h +++ b/rtengine/alpha.h @@ -19,7 +19,7 @@ #ifndef _ALPHA_H_ #define _ALPHA_H_ -#include +#include #include #define CHECK_BOUNDS 0 diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 8ddaa5f75..a6a1f1f50 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -18,6 +18,9 @@ * along with RawTherapee. If not, see . */ +#include +#include + #include "cieimage.h" #include "color.h" #include "curves.h" diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 2f443522c..e44243fd3 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include +#include #include #include diff --git a/rtengine/init.cc b/rtengine/init.cc index 4ec3f0ec5..0c1bd4f6b 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -17,7 +17,8 @@ * along with RawTherapee. If not, see . */ #include -#include "../rtgui/profilestorecombobox.h" +#include +#include #include "color.h" #include "rtengine.h" #include "iccstore.h" diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index f83ddd385..5cc039187 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -17,6 +17,9 @@ * along with RawTherapee. If not, see . */ +#include +#include + #include #include diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index e8e48c17f..d65c01751 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include diff --git a/rtgui/editcallbacks.h b/rtgui/editcallbacks.h index 134ea6477..61d392de5 100644 --- a/rtgui/editcallbacks.h +++ b/rtgui/editcallbacks.h @@ -18,6 +18,8 @@ */ #pragma once +#include + #include "editid.h" #include "cursormanager.h" #include "../rtengine/coord.h" diff --git a/rtgui/options.cc b/rtgui/options.cc index d6c3f7d25..e89fcd647 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -19,7 +19,11 @@ #include "options.h" #include #include +#include +#include #include +#include +#include #include #include #include "multilangmgr.h" From fcbe2182fde376521bc10ea76da710f334e4025e Mon Sep 17 00:00:00 2001 From: Shiho Midorikawa Date: Thu, 25 May 2023 03:13:07 +0900 Subject: [PATCH 254/326] Remove return value from ExifManager::createJPEGMarker --- rtexif/rtexif.cc | 6 ++---- rtexif/rtexif.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index a48db5229..111f11668 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3243,7 +3243,7 @@ std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) -int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize) +void ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize) { // write tiff header @@ -3324,11 +3324,9 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro offs += 2; sset4 (8, buffer + offs, order); - int endOffs = cl->write (8, buffer + 6); + cl->write (8, buffer + 6); delete cl; - - return endOffs; } int ExifManager::createPNGMarker(const TagDirectory* root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize) diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index beb21131a..0b44bc47a 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -379,7 +379,7 @@ public: /// @param forthis The byte order will be taken from the given directory. /// @return The ownership of the return tags is passed to the caller. static std::vector getDefaultTIFFTags (TagDirectory* forthis); - static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize); + static void createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize); static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); static int createPNGMarker(const TagDirectory *root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char *iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); }; From 8accebe4161c581c76dda4edee027b95ec109ea9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 28 May 2023 18:15:27 -0700 Subject: [PATCH 255/326] Fix incorrect sampled L*a*b* values Use LCMS to convert values back into L*a*b*. The pipette buffer has the output or working profile applied with LCMS. Performing the inverse operation fixes the incorrect values shown in the navigator, histogram indicator bars, and lockable color pickers. --- rtengine/improcfun.cc | 20 ++++++++++++++ rtengine/improcfun.h | 2 ++ rtgui/cropwindow.cc | 10 +++---- rtgui/histogrampanel.cc | 52 +++++++++++++++++++++++++---------- rtgui/histogrampanel.h | 8 +++--- rtgui/lockablecolorpicker.cc | 23 ++++++++++++++-- rtgui/lockablecolorpicker.h | 17 ++++++++++-- rtgui/navigator.cc | 25 ++++++++++++++--- rtgui/navigator.h | 4 +-- rtgui/pointermotionlistener.h | 19 ++++++++++++- 10 files changed, 144 insertions(+), 36 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c3e11c076..5d527c818 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5667,6 +5667,11 @@ void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib:: } void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings) const +{ + rgb2lab(src, x, y, w, h, L, a, b, icm, consider_histogram_settings, multiThread); +} + +void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings, bool multiThread) { // Adapted from ImProcFunctions::lab2rgb const int src_width = src.getWidth(); @@ -5779,6 +5784,21 @@ void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, flo } } +void ImProcFunctions::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) +{ + float l_channel[1]; + float a_channel[1]; + float b_channel[1]; + rtengine::Image8 buf(1, 1); + buf.r(0, 0) = red; + buf.g(0, 0) = green; + buf.b(0, 0) = blue; + ImProcFunctions::rgb2lab(buf, 0, 0, 1, 1, l_channel, a_channel, b_channel, icm, consider_histogram_settings, false); + L = l_channel[0]; + a = a_channel[0]; + b = b_channel[0]; +} + void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace) { TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(workingSpace); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 36c571291..3fddbd753 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -116,6 +116,7 @@ class ImProcFunctions bool multiThread; void calcVignettingParams(int oW, int oH, const procparams::VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul); + static void rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings, bool multithread); void transformLuminanceOnly(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH); void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer); @@ -497,6 +498,7 @@ enum class BlurType { Image8* lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true); void rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true) const; + 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; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index c7d7348b3..0cd6f3f6c 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -403,7 +403,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) // Add a new Color Picker rtengine::Coord imgPos; screenCoordToImage(x, y, imgPos.x, imgPos.y); - LockableColorPicker *newPicker = new LockableColorPicker(this, &cropHandler.colorParams->outputProfile, &cropHandler.colorParams->workingProfile); + LockableColorPicker *newPicker = new LockableColorPicker(this, cropHandler.colorParams.get()); colorPickers.push_back(newPicker); hoveredPicker = newPicker; updateHoveredPicker(&imgPos); @@ -1095,10 +1095,10 @@ void CropWindow::pointerMoved (int bstate, int x, int y) printf("Using \"%s\" output\n", outputProfile.c_str()); if(outputProfile==options.rtSettings.srgb) printf("OK SRGB2"); */ - pmlistener->pointerMoved (false, cropHandler.colorParams->outputProfile, cropHandler.colorParams->workingProfile, mx, my, -1, -1, -1); + pmlistener->pointerMoved (false, *cropHandler.colorParams, mx, my, -1, -1, -1); if (pmhlistener) { - pmhlistener->pointerMoved (false, cropHandler.colorParams->outputProfile, cropHandler.colorParams->workingProfile, mx, my, -1, -1, -1); + pmhlistener->pointerMoved (false, *cropHandler.colorParams, mx, my, -1, -1, -1); } } else { @@ -1145,11 +1145,11 @@ void CropWindow::pointerMoved (int bstate, int x, int y) // Updates the Navigator // TODO: possible double color conversion if rval, gval, bval come from cropHandler.cropPixbuftrue ? see issue #4583 - pmlistener->pointerMoved (true, cropHandler.colorParams->outputProfile, cropHandler.colorParams->workingProfile, mx, my, rval, gval, bval, isRaw); + pmlistener->pointerMoved (true, *cropHandler.colorParams, mx, my, rval, gval, bval, isRaw); if (pmhlistener) { // Updates the HistogramRGBArea - pmhlistener->pointerMoved (true, cropHandler.colorParams->outputProfile, cropHandler.colorParams->workingProfile, mx, my, rval, gval, bval); + pmhlistener->pointerMoved (true, *cropHandler.colorParams, mx, my, rval, gval, bval); } } } diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 6bda0812e..821f6f0be 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -22,10 +22,11 @@ #include "options.h" #include #include -#include "../rtengine/array2D.h" -#include "../rtengine/LUT.h" #include "rtimage.h" +#include "../rtengine/array2D.h" #include "../rtengine/color.h" +#include "../rtengine/improcfun.h" +#include "../rtengine/LUT.h" using namespace rtengine; @@ -34,12 +35,20 @@ constexpr float HistogramArea::MIN_BRIGHT; using ScopeType = Options::ScopeType; + +namespace +{ + +const rtengine::procparams::ColorManagementParams DEFAULT_CMP; + +} + // // // HistogramPanel HistogramPanel::HistogramPanel () : pointer_moved_delayed_call( - [this](bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int r, int g, int b) + [this](bool validPos, const rtengine::procparams::ColorManagementParams *cmp, int r, int g, int b) { bool update_hist_area; @@ -52,9 +61,9 @@ HistogramPanel::HistogramPanel () : } else { // do something to show vertical bars if (histogramRGBArea) { - histogramRGBArea->updateBackBuffer(r, g, b, profile, profileW); + histogramRGBArea->updateBackBuffer(r, g, b, cmp); } - update_hist_area = histogramArea->updatePointer(r, g, b, profile, profileW); + update_hist_area = histogramArea->updatePointer(r, g, b, cmp); } if (histogramRGBArea) { histogramRGBArea->queue_draw(); @@ -623,9 +632,9 @@ void HistogramPanel::setHistRGBInvalid () 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) +void HistogramPanel::pointerMoved(bool validPos, const rtengine::procparams::ColorManagementParams &cmp, int x, int y, int r, int g, int b, bool isRaw) { - pointer_moved_delayed_call(validPos, profile, profileW, r, g, b); + pointer_moved_delayed_call(validPos, &cmp, r, g, b); } /* @@ -797,7 +806,7 @@ void HistogramRGBArea::setShow(bool show) showMode = show; } -void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW) +void HistogramRGBArea::updateBackBuffer(int r, int g, int b, const rtengine::procparams::ColorManagementParams *cmp) { if (!get_realized () || !showMode || !( options.histogramScopeType == ScopeType::HISTOGRAM @@ -856,19 +865,25 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin || 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); + ImProcFunctions::rgb2lab( + static_cast(r), + static_cast(g), + static_cast(b), + Lab_L, Lab_a, Lab_b, + cmp != nullptr ? *cmp : DEFAULT_CMP, + true); if (needLuma) { // Luma cc->set_source_rgb(1.0, 1.0, 1.0); - drawBar(cc, Lab_L, 100.0, winw, winh, s); + drawBar(cc, Lab_L, 32768., winw, winh, s); } if (needChroma && options.histogramScopeType == ScopeType::HISTOGRAM) { // Chroma - double chromaval = sqrt(Lab_a * Lab_a + Lab_b * Lab_b) / 1.8; + double chromaval = sqrt(Lab_a * Lab_a + Lab_b * Lab_b) / (255. * 188); cc->set_source_rgb(0.9, 0.9, 0.0); - drawBar(cc, chromaval, 100.0, winw, winh, s); + drawBar(cc, chromaval, 1.0, winw, winh, s); } } } @@ -1443,7 +1458,7 @@ void HistogramArea::updateBackBuffer () setDirty(false); } -bool HistogramArea::updatePointer(int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW) +bool HistogramArea::updatePointer(int r, int g, int b, const rtengine::procparams::ColorManagementParams *cmp) { if (!needPointer || !(scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS)) { return false; @@ -1456,7 +1471,16 @@ bool HistogramArea::updatePointer(int r, int g, int b, const Glib::ustring &prof 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); + ImProcFunctions::rgb2lab( + static_cast(r), + static_cast(g), + static_cast(b), + L, pointer_a, pointer_b, + cmp != nullptr ? *cmp : DEFAULT_CMP, + true); + L /= 327.68f; + pointer_a /= 327.68f; + pointer_b /= 327.68f; updateBackBuffer(); return true; } diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index 26b744546..7f165bb15 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -99,7 +99,7 @@ public: HistogramRGBArea(); ~HistogramRGBArea() override; - void updateBackBuffer (int r, int g, int b, const Glib::ustring &profile = "", const Glib::ustring &profileW = ""); + void updateBackBuffer(int r, int g, int b, const rtengine::procparams::ColorManagementParams *cmp = nullptr); bool getShow (); void setShow(bool show); void setParent (Gtk::Grid* p) @@ -206,7 +206,7 @@ public: 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 = ""); + bool updatePointer(int r, int g, int b, const rtengine::procparams::ColorManagementParams *cmp = nullptr); void update( const LUTu& histRed, const LUTu& histGreen, @@ -260,7 +260,7 @@ public: class HistogramPanel final : public Gtk::Grid, public PointerMotionListener, public DrawModeListener, public rtengine::NonCopyable { private: - DelayedCall pointer_moved_delayed_call; + DelayedCall pointer_moved_delayed_call; protected: @@ -343,7 +343,7 @@ public: histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, vectorscopeScale, vectorscopeHC, vectorscopeHS, waveformScale, waveformRed, waveformGreen, waveformBlue, waveformLuma); } // 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; + void pointerMoved (bool validPos, const rtengine::procparams::ColorManagementParams &cmp, int x, int y, int r, int g, int b, bool isRaw = false) override; // TODO should be protected void setHistRGBInvalid (); diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 0a08bb945..c87239b9c 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -20,15 +20,23 @@ #include "lockablecolorpicker.h" #include "options.h" #include "../rtengine/color.h" +#include "../rtengine/improcfun.h" #include "../rtengine/rt_math.h" #include "../rtengine/utils.h" #include "imagearea.h" #include "multilangmgr.h" #include "navigator.h" -LockableColorPicker::LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile) +namespace +{ + +const rtengine::procparams::ColorManagementParams DEFAULT_CMP; + +} + +LockableColorPicker::LockableColorPicker (CropWindow* cropWindow, rtengine::procparams::ColorManagementParams *color_management_params) : cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(0, 0), size(Size::S15), - outputProfile(oProfile), workingProfile(wProfile), validity(Validity::OUTSIDE), + color_management_params(color_management_params), validity(Validity::OUTSIDE), r(0.f), g(0.f), b(0.f), rpreview(0.f), gpreview(0.f), bpreview(0.f), hue(0.f), sat(0.f), val(0.f), L(0.f), a(0.f), bb(0.f) {} @@ -277,7 +285,16 @@ void LockableColorPicker::setRGB (const float R, const float G, const float B, c bpreview = previewB; rtengine::Color::rgb2hsv01(r, g, b, hue, sat, val); - rtengine::Color::rgb2lab01(*outputProfile, *workingProfile, r, g, b, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works? + rtengine::ImProcFunctions::rgb2lab( + static_cast(255 * r), + static_cast(255 * g), + static_cast(255 * b), + L, a, bb, + color_management_params != nullptr ? *color_management_params : DEFAULT_CMP, + true); + L /= 327.68f; + a /= 327.68f; + bb /= 327.68f; if (validity != Validity::OUTSIDE) { setDirty(true); diff --git a/rtgui/lockablecolorpicker.h b/rtgui/lockablecolorpicker.h index baeea41ef..b18a56028 100644 --- a/rtgui/lockablecolorpicker.h +++ b/rtgui/lockablecolorpicker.h @@ -24,6 +24,18 @@ class CropWindow; +namespace rtengine +{ + +namespace procparams +{ + +class ColorManagementParams; + +} + +} + class LockablePickerToolListener { public: @@ -60,8 +72,7 @@ private: rtengine::Coord position; // Coordinate in image space rtengine::Coord anchorOffset; Size size; - Glib::ustring *outputProfile; - Glib::ustring *workingProfile; + rtengine::procparams::ColorManagementParams *color_management_params; Validity validity; float r, g, b; // red green blue in [0;1] range float rpreview, gpreview, bpreview; @@ -72,7 +83,7 @@ private: public: - LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile); + LockableColorPicker (CropWindow* cropWindow, rtengine::procparams::ColorManagementParams *color_management_params); void draw (const Cairo::RefPtr &cr); diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc index 42f605fa2..042f57a00 100644 --- a/rtgui/navigator.cc +++ b/rtgui/navigator.cc @@ -21,18 +21,26 @@ #include "previewwindow.h" #include "toolpanel.h" #include "../rtengine/color.h" +#include "../rtengine/improcfun.h" #include "../rtengine/rt_math.h" #include "options.h" using namespace rtengine; +namespace +{ + +const rtengine::procparams::ColorManagementParams DEFAULT_CMP; + +} + Navigator::Navigator() : pointer_moved_delayed_call(50, 100), currentRGBUnit(options.navRGBUnit), currentHSVUnit(options.navHSVUnit) { pointer_moved_delayed_call.setFunction( - [this](bool validPos, Glib::ustring profile, Glib::ustring profileW, int x, int y, int r, int g, int b, bool isRaw) + [this](bool validPos, const rtengine::procparams::ColorManagementParams *cmp, int x, int y, int r, int g, int b, bool isRaw) { if (!validPos) { setInvalid (x, y); @@ -61,7 +69,16 @@ Navigator::Navigator() : S->set_text (s2); V->set_text (s3); - Color::rgb2lab01(profile, profileW, r / 255.f, g / 255.f, b / 255.f, LAB_l, LAB_a, LAB_b, options.rtSettings.HistogramWorking); // TODO: Really sure this function works? + ImProcFunctions::rgb2lab( + static_cast(r), + static_cast(g), + static_cast(b), + LAB_l, LAB_a, LAB_b, + cmp != nullptr ? *cmp : DEFAULT_CMP, + true); + LAB_l /= 327.68f; + LAB_a /= 327.68f; + LAB_b /= 327.68f; getLABText (LAB_l, LAB_a, LAB_b, s1, s2, s3); LAB_L->set_text (s1); LAB_A->set_text (s2); @@ -328,9 +345,9 @@ void Navigator::getLABText (float l, float a, float b, Glib::ustring &sL, Glib:: } // if !validPos then x/y contain the full image size -void Navigator::pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw) +void Navigator::pointerMoved (bool validPos, const rtengine::procparams::ColorManagementParams &cmp, int x, int y, int r, int g, int b, bool isRaw) { - pointer_moved_delayed_call(validPos, profile, profileW, x, y, r, g, b, isRaw); + pointer_moved_delayed_call(validPos, &cmp, x, y, r, g, b, isRaw); } void Navigator::cycleUnitsRGB (GdkEventButton *event) { diff --git a/rtgui/navigator.h b/rtgui/navigator.h index 4c2a3fd32..c16bf7ac7 100644 --- a/rtgui/navigator.h +++ b/rtgui/navigator.h @@ -34,7 +34,7 @@ class Navigator final : typedef const double (*TMatrix)[3]; private: - DelayedCall pointer_moved_delayed_call; + DelayedCall pointer_moved_delayed_call; Options::NavigatorUnit currentRGBUnit; Options::NavigatorUnit currentHSVUnit; @@ -61,7 +61,7 @@ public: // pointermotionlistener interface // void pointerMoved (bool validPos, int x, int y, int r, int g, int b); - void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool raw = false) override; + void pointerMoved(bool validPos, const rtengine::procparams::ColorManagementParams &cmp, int x, int y, int r, int g, int b, bool raw = false) override; void setInvalid (int fullWidth = -1, int fullHeight = -1); void getRGBText (int r, int g, int b, Glib::ustring &sR, Glib::ustring &sG, Glib::ustring &sB, bool isRaw = false) override; diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h index 26ca994b0..f9fda419c 100644 --- a/rtgui/pointermotionlistener.h +++ b/rtgui/pointermotionlistener.h @@ -18,6 +18,23 @@ */ #pragma once +#include +#include + + +namespace rtengine +{ + +namespace procparams +{ + +class ColorManagementParams; + +} + +} + + class PointerMotionListener { protected: @@ -26,7 +43,7 @@ protected: public: virtual ~PointerMotionListener() = default; - virtual 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) = 0; + virtual void pointerMoved(bool validPos, const rtengine::procparams::ColorManagementParams &cmp, int x, int y, int r, int g, int b, bool isRaw = false) = 0; virtual void getRGBText (int r, int g, int b, Glib::ustring &sR, Glib::ustring &sG, Glib::ustring &sB, bool isRaw = false) { sR = "--"; sG = "--"; sB = "--"; } virtual void getHSVText (float h, float s, float v, Glib::ustring &sH, Glib::ustring &sS, Glib::ustring &sV) { sH = "--"; sS = "--"; sV = "--"; } virtual void getLABText (float l, float a, float b, Glib::ustring &sL, Glib::ustring &sA, Glib::ustring &sB) { sL = "--"; sA = "--"; sB = "--"; } From 24f0bff0ab26b47b5a123d6de9e4f363ef2391b7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 29 May 2023 15:49:58 -0700 Subject: [PATCH 256/326] Fix L*a*b* curves histogram and pipette scaling Use correct horizontal scale for chroma histogram. Fix pipette values for chroma, a*, and b*. --- rtengine/improcfun.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c3e11c076..f984e8d71 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4176,9 +4176,6 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, } - const float histLFactor = pW != 1 ? histLCurve.getSize() / 100.f : 1.f; - const float histCFactor = pW != 1 ? histCCurve.getSize() / 48000.f : 1.f; - float adjustr = 1.0f; // if(params->labCurve.avoidclip ){ @@ -4200,6 +4197,9 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, adjustr = 1.8f; } + const float histLFactor = pW != 1 ? histLCurve.getSize() / 100.f : 1.f; + const float histCFactor = pW != 1 ? histCCurve.getSize() * adjustr / 65536.f : 1.f; + // reference to the params structure has to be done outside of the parallelization to avoid CPU cache problem const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated const int chromaticity = params->labCurve.chromaticity; @@ -4359,11 +4359,11 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, if (editPipette) { if (editID == EUID_Lab_aCurve) { // Lab a pipette - float chromapipa = lold->a[i][j] + (32768.f * 1.28f); - editWhatever->v(i, j) = LIM01 ((chromapipa) / (65536.f * 1.28f)); + float chromapipa = lold->a[i][j] + 32768.f; + editWhatever->v(i, j) = LIM01 ((chromapipa) / (65536.f)); } else if (editID == EUID_Lab_bCurve) { //Lab b pipette - float chromapipb = lold->b[i][j] + (32768.f * 1.28f); - editWhatever->v(i, j) = LIM01 ((chromapipb) / (65536.f * 1.28f)); + float chromapipb = lold->b[i][j] + 32768.f; + editWhatever->v(i, j) = LIM01 ((chromapipb) / (65536.f)); } } @@ -4602,7 +4602,7 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, // I have placed C=f(C) after all C treatments to assure maximum amplitude of "C" if (editPipette && editID == EUID_Lab_CCurve) { float chromapip = sqrt(SQR(atmp) + SQR(btmp) + 0.001f); - editWhatever->v(i, j) = LIM01 ((chromapip) / (48000.f)); + editWhatever->v(i, j) = LIM01 ((chromapip) / (65536.f / adjustr)); }//Lab C=f(C) pipette if (ccut) { @@ -4669,7 +4669,7 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, if (editPipette && editID == EUID_Lab_LCCurve) { float chromapiplc = sqrt(SQR(atmp) + SQR(btmp) + 0.001f); - editWhatever->v(i, j) = LIM01 ((chromapiplc) / (48000.f)); + editWhatever->v(i, j) = LIM01 ((chromapiplc) / (65536.f / adjustr)); }//Lab L=f(C) pipette From 362564c60f36b4fd31c23d5ae7d2ce8de579c2d2 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 29 May 2023 17:14:44 -0700 Subject: [PATCH 257/326] Automatically detect DLLs for Windows packages Use ldd to find dependencies in /mingw64/bin. --- .github/workflows/windows.yml | 67 +++-------------------------------- 1 file changed, 5 insertions(+), 62 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4ab10212c..fb0a45028 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -98,6 +98,10 @@ jobs: run: | echo "Listing shared library dependencies." ldd "./build/${{matrix.build_type}}/rawtherapee.exe" + echo "Finding DLLs to include." + DLLS=($(ldd "./build/${{matrix.build_type}}/rawtherapee.exe" | grep '/mingw64/bin/' | awk '{print($1)'})) + echo "Required DLLs are: ${DLLS[*]}" + echo "Getting workspace path." export BUILD_DIR="$(pwd)/build/${{matrix.build_type}}" echo "Build directory is '$BUILD_DIR'." @@ -110,68 +114,7 @@ jobs: "gdbus.exe" \ "gspawn-win64-helper.exe" \ "gspawn-win64-helper-console.exe" \ - "libatk-1.0-0.dll" \ - "libatkmm-1.6-1.dll" \ - "libbrotlicommon.dll" \ - "libbrotlidec.dll" \ - "libbz2-1.dll" \ - "libcairo-2.dll" \ - "libcairo-gobject-2.dll" \ - "libcairomm-1.0-1.dll" \ - "libdatrie-1.dll" \ - "libdeflate.dll" \ - "libepoxy-0.dll" \ - "libexpat-1.dll" \ - libffi-*.dll \ - "libfftw3f-3.dll" \ - "libfftw3f_omp-3.dll" \ - "libfontconfig-1.dll" \ - "libfreetype-6.dll" \ - "libfribidi-0.dll" \ - "libgcc_s_seh-1.dll" \ - "libgdk_pixbuf-2.0-0.dll" \ - "libgdk-3-0.dll" \ - "libgdkmm-3.0-1.dll" \ - "libgio-2.0-0.dll" \ - "libgiomm-2.4-1.dll" \ - "libglib-2.0-0.dll" \ - "libglibmm-2.4-1.dll" \ - "libgmodule-2.0-0.dll" \ - "libgobject-2.0-0.dll" \ - "libgomp-1.dll" \ - "libgraphite2.dll" \ - "libgtk-3-0.dll" \ - "libgtkmm-3.0-1.dll" \ - "libharfbuzz-0.dll" \ - "libiconv-2.dll" \ - "libintl-8.dll" \ - "libjbig-0.dll" \ - "libjpeg-8.dll" \ - "liblcms2-2.dll" \ - "liblensfun.dll" \ - "libLerc.dll" \ - "liblzma-5.dll" \ - "libpango-1.0-0.dll" \ - "libpangocairo-1.0-0.dll" \ - "libpangoft2-1.0-0.dll" \ - "libpangomm-1.4-1.dll" \ - "libpangowin32-1.0-0.dll" \ - "libpcre2-8-0.dll" \ - "libpixman-1-0.dll" \ - "libpng16-16.dll" \ - "librsvg-2-2.dll" \ - "libsharpyuv-0.dll" \ - "libsigc-2.0-0.dll" \ - "libstdc++-6.dll" \ - "libsystre-0.dll" \ - "libthai-0.dll" \ - "libtiff-6.dll" \ - "libtre-5.dll" \ - "libwebp-7.dll" \ - "libwinpthread-1.dll" \ - "libxml2-2.dll" \ - "libzstd.dll" \ - "zlib1.dll" \ + ${DLLS[*]} \ "$BUILD_DIR" cd - From 376d680b16da38436d70e206d19593446f43a111 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 4 Jun 2023 16:32:41 -0700 Subject: [PATCH 258/326] Add basic camconst entry for Canon EOS R8 The camera seems to have the same characteristics as the Canon EOS R6m2. The raw crops for the R6m2 are derived from standard and CRAW images for full-frame and 1.6 crop. The raw crops for the R8 are from standard and CRAW images for full-frame only, but for both standard and Dual Pixel. The Dual Pixel R8 images require 10 pixels cropped from the right side instead of 6. Thus, the full-frame crop needs adjustment. --- rtengine/camconst.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 352dc26e1..c4bf9b14a 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1259,10 +1259,10 @@ Camera constants: }, { // Quality C - "make_model": "Canon EOS R6m2", + "make_model": ["Canon EOS R6m2", "Canon EOS R8"], "dcraw_matrix": [9539, -2795, -1224, -4175, 11998, 2458, -465, 1755, 6048], "raw_crop": [ - {"frame": [6188, 4120], "crop": [154, 96, 6028, 4024]}, + {"frame": [6188, 4120], "crop": [154, 96, 6024, 4024]}, {"frame": [3936, 2612], "crop": [156, 96, 3780, 2516]} ], "masked_areas": [ From be2d5ce11face17acb3c9f0ab6e9b56ff13d4dae Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 5 Jun 2023 06:40:57 +0200 Subject: [PATCH 259/326] Local adjustments - denoise improvments (#6705) * Init improvment LA denoise * First display luma chroma residual noise * Clean code denoise iplocallab.cc * Change windows.yml with old version january 2023 * Clean code - change calculation denoise - GUI * Improve labels tooltip denoise * Clean code * Change tooltip * Set auto denoise - main - chroma auto to 50% when LA denoise is used * Change GUI denoise with expanders * Change labels * Change reference remianing noise in percentage * Change tooltip and labels * Change values in preview remaining noise * Clean comment code - chnage tooltips * Change windows.yml and appimage.yml publish_pre_dev labels * Update windows.yml * Restore windows.yml * Restore windows.yml and clean code * Revert change Noise Reduction link with Local denoise * Revert all changes on Noise-reduction linked with Local adjustments --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 14 +- rtengine/FTblockDN.cc | 13 +- rtengine/dcrop.cc | 61 +++-- rtengine/improccoordinator.cc | 14 +- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 8 +- rtengine/iplocallab.cc | 471 +++++++++++++-------------------- rtengine/rtengine.h | 12 + rtengine/simpleprocess.cc | 11 +- rtgui/locallab.cc | 35 +++ rtgui/locallab.h | 7 + rtgui/locallabtools.cc | 128 +++++++-- rtgui/locallabtools.h | 13 +- 15 files changed, 445 insertions(+), 347 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 9ad9a6cbd..6b286b68b 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' jobs: build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4ab10212c..e01e4bd75 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' jobs: build: runs-on: windows-2022 diff --git a/rtdata/languages/default b/rtdata/languages/default index 45471bb5c..4c99d113b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2839,13 +2839,15 @@ 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 RT-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;Luma-chro detail threshold +TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold TP_LOCALLAB_DIVGR;Gamma TP_LOCALLAB_DUPLSPOTNAME;Copy TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3110,7 +3112,7 @@ 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;This 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_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. @@ -3169,6 +3171,12 @@ 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_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_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 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 @@ -3185,7 +3193,7 @@ TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denois 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_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 diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 400dea05b..7477c5d08 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -1203,7 +1203,7 @@ BENCHFUN if (!memoryAllocationFailed) { if (kall == 0) { - Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb); + Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb, 0, levwav); chresidtemp = chresid; chmaxresidtemp = chmaxresid; } @@ -1240,12 +1240,13 @@ BENCHFUN if (!memoryAllocationFailed) { if (kall == 0) { - Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb); + Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb, 0, levwav); chresid += chresidtemp; chmaxresid += chmaxresidtemp; 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); } bdecomp->reconstruct(labdn->b[0]); @@ -2158,16 +2159,18 @@ float ImProcFunctions::MadRgb(const float * DataList, const int datalen) -void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb) +void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb, int beg, int end) { float resid = 0.f; float maxresid = 0.f; - +// int maxlev = WaveletCoeffs_ab.maxlevel(); + // end = maxlev; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) reduction(+:resid) reduction(max:maxresid) num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int lvl = 0; lvl < WaveletCoeffs_ab.maxlevel(); ++lvl) { + // for (int lvl = 0; lvl < WaveletCoeffs_ab.maxlevel(); ++lvl) { + for (int lvl = beg; lvl < end; ++lvl) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator for (int dir = 1; dir < 4; ++dir) { const int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a6a1f1f50..bce6f2291 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -600,7 +600,6 @@ void Crop::update(int todo) params.dirpyrDenoise.redchro = maxr; params.dirpyrDenoise.bluechro = maxb; parent->denoiseInfoStore.valid = true; - if (parent->adnListener) { parent->adnListener->chromaChanged(params.dirpyrDenoise.chroma, params.dirpyrDenoise.redchro, params.dirpyrDenoise.bluechro); } @@ -848,7 +847,7 @@ void Crop::update(int todo) if ((todo & (M_AUTOEXP | M_RGBCURVE)) && params.locallab.enabled && !params.locallab.spots.empty()) { - + //I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here. parent->ipf.rgb2lab(*baseCrop, *laboCrop, params.icm.workingProfile); @@ -945,16 +944,7 @@ void Crop::update(int todo) auto& locwavCurveden = parent->locwavCurveden; auto& lmasklocal_curve2 = parent->lmasklocal_curve; auto& loclmasCurve_wav = parent->loclmasCurve_wav; -// const int sizespot = (int)params.locallab.spots.size(); -/* float *huerefp = nullptr; - huerefp = new float[sizespot]; - float *chromarefp = nullptr; - chromarefp = new float[sizespot]; - float *lumarefp = nullptr; - lumarefp = new float[sizespot]; - float *fabrefp = nullptr; - fabrefp = new float[sizespot]; -*/ + for (int sp = 0; sp < (int)params.locallab.spots.size(); sp++) { locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); locRETtransCurve.Set(params.locallab.spots.at(sp).localTtranscurve); @@ -1048,6 +1038,7 @@ void Crop::update(int todo) if (black < 0. && params.locallab.spots.at(sp).expMethod == "pde" ) { black *= 1.5; } + std::vector localldenoiselc; double cont = params.locallab.spots.at(sp).contrast; double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; @@ -1063,6 +1054,7 @@ void Crop::update(int todo) float stdtme = parent->stdtms[sp]; float meanretie = parent->meanretis[sp]; float stdretie = parent->stdretis[sp]; + float fab = 1.f; float minCD; float maxCD; @@ -1073,7 +1065,14 @@ void Crop::update(int todo) float Tmin; float Tmax; int lastsav; - + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; /* huerefp[sp] = huere; chromarefp[sp] = chromare; lumarefp[sp] = lumare; @@ -1142,9 +1141,20 @@ 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); - // fabrefp[sp] = fab; - + meantme, stdtme, meanretie, stdretie, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); + + LocallabListener::locallabDenoiseLC denoiselc; + denoiselc.highres = highresi; + denoiselc.nres = nresi; + denoiselc.highres46 = highresi46; + denoiselc.nres46 = nresi46; + denoiselc.Lhighres = Lhighresi; + denoiselc.Lnres = Lnresi; + denoiselc.Lhighres46 = Lhighresi46; + denoiselc.Lnres46 = Lnresi46; + localldenoiselc.push_back(denoiselc); + if (parent->previewDeltaE || parent->locallColorMask == 5 || parent->locallvibMask == 4 || parent->locallExpMask == 5 || parent->locallSHMask == 4 || parent->localllcMask == 4 || parent->localltmMask == 4 || parent->localllogMask == 4 || parent->locallsoftMask == 6 || parent->localllcMask == 4 || parent->locallcieMask == 4) { params.blackwhite.enabled = false; params.colorToning.enabled = false; @@ -1174,6 +1184,20 @@ void Crop::update(int todo) } */ + denoiselc.highres = highresi; + denoiselc.nres = nresi; + denoiselc.highres46 = highresi46; + denoiselc.nres46 = nresi46; + denoiselc.Lhighres = Lhighresi; + denoiselc.Lnres = Lnresi; + denoiselc.Lhighres46 = Lhighresi46; + denoiselc.Lnres46 = Lnresi46; + localldenoiselc.push_back(denoiselc); + + + if (parent->locallListener) { + parent->locallListener->denChanged(localldenoiselc, params.locallab.selspot); + } } else { parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, @@ -1229,8 +1253,11 @@ 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, + 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 lastorigCrop->CopyFrom(labnCrop); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 664029a5e..2ab6383bf 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1169,7 +1169,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float stdtm = stdtms[sp] = stdtme; float meanreti = meanretis[sp] = meanretie; float stdreti = stdretis[sp] = stdretie; - huerefp[sp] = huer; chromarefp[sp] = chromar; lumarefp[sp] = lumar; @@ -1203,6 +1202,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float Tmax; int lastsav; + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; + 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, @@ -1256,7 +1264,8 @@ 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, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); fabrefp[sp] = fab; @@ -1296,7 +1305,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) retiMinMax.Tmin = Tmin; retiMinMax.Tmax = Tmax; locallretiminmax.push_back(retiMinMax); - // 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); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 92cdd91c7..50c14ef9e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -365,6 +365,7 @@ protected: std::vector stdtms; std::vector meanretis; std::vector stdretis; + bool lastspotdup; bool previewDeltaE; int locallColorMask; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 36c571291..8b05a7bb4 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -360,7 +360,8 @@ 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 &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46); 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); @@ -399,7 +400,8 @@ enum class BlurType { void DeNoise_Local(int call, const struct local_params& lp, LabImage* originalmask, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk); void DeNoise_Local2(const struct local_params& lp, LabImage* originalmask, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk); - void DeNoise(int call, float * slidL, float * slida, float * slidb, 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); + void 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); void 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); @@ -462,7 +464,7 @@ enum class BlurType { void ShrinkAll_info(const float* const* WavCoeffs_a, const float* const* WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); - void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); + void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb, int beg, int end); void calcautodn_info(float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); float Mad(const float * DataList, int datalen); float MadRgb(const float * DataList, int datalen); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b9e82cc5d..adc762710 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -10872,7 +10872,8 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in } -void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * slidb, 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) +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 //local denoise @@ -10943,7 +10944,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - // if (call == 1 && GW >= mDEN && GH >= mDEN) { if (call == 1 && ((GW >= mDEN && GH >= mDEN && isnois) || lp.quamet == 2)) { @@ -10965,6 +10965,9 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl tmp1.a[ir][jr] = original->a[ir][jr]; tmp1.b[ir][jr] = original->b[ir][jr]; } + if(lp.nlstr > 0) { + NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); + } float gamma = lp.noisegam; rtengine::GammaValues g_a; //gamma parameters @@ -11003,14 +11006,13 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl if (!Ldecomp.memory_allocation_failed()) { #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) + // #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); int Hlvl_L = Ldecomp.level_H(lvl); const float* const* WavCoeffs_L = Ldecomp.level_coeffs(lvl); - madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); } } @@ -11019,67 +11021,36 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float mxsl = 0.f; // float mxsfl = 0.f; - if (aut == 0) { - if (levred == 7) { - edge = 2; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); + edge = 2; + vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); + vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); + vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[4] = 0.8f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); - vari[5] = 0.8f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); - vari[6] = 0.8f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); - } else if (levred == 4) { - edge = 3; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - vari[0] = SQR(slidL[0]); - vari[1] = SQR(slidL[1]); - vari[2] = SQR(slidL[2]); - vari[3] = SQR(slidL[3]); - vari[4] = SQR(slidL[4]); - vari[5] = SQR(slidL[5]); - vari[6] = SQR(slidL[6]); - float mxslid34 = rtengine::max(slidL[3], slidL[4]); - float mxslid56 = rtengine::max(slidL[5], slidL[6]); - mxsl = rtengine::max(mxslid34, mxslid56); - - } + vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); + vari[4] = 1.f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); + vari[5] = 1.5f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); + vari[6] = 2.5f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); { float kr3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noiselc < 30.f && aut == 0) || (mxsl < 30.f && aut == 1)) { + if (lp.noiselc < 30.f) { kr3 = 0.f; - } else if ((lp.noiselc < 50.f && aut == 0) || (mxsl < 50.f && aut == 1)) { + } else if (lp.noiselc < 50.f) { kr3 = 0.5f; - } else if ((lp.noiselc < 70.f && aut == 0) || (mxsl < 70.f && aut == 1)) { + } else if (lp.noiselc < 70.f) { kr3 = 0.7f; } else { kr3 = 1.f; } - } else if (aut == 2) { - kr3 = 1.f; - } vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); - - if (levred == 7) { - vari[4] = rtengine::max(0.000001f, vari[4]); - vari[5] = rtengine::max(0.000001f, vari[5]); - vari[6] = rtengine::max(0.000001f, vari[6]); - } + vari[4] = rtengine::max(0.000001f, vari[4]); + vari[5] = rtengine::max(0.000001f, vari[5]); + vari[6] = rtengine::max(0.000001f, vari[6]); float* noisevarlum = new float[GH * GW]; float* noisevarhue = new float[GH * GW]; @@ -11218,75 +11189,25 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { - float maxcfine = 0.f; float maxccoarse = 0.f; - if (aut == 0) { - if (levred == 7) { - edge = 2; - variC[0] = SQR(noisecfr); - variC[1] = SQR(noisecfr); - variC[2] = SQR(noisecfr); + edge = 2; + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); + variC[3] = SQR(1.2f * noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(1.2f * noiseccr); + variC[6] = SQR(1.5f * noiseccr); - variC[3] = SQR(noisecfr); - variC[4] = SQR(noisecfr); - variC[5] = SQR(noiseccr); - variC[6] = SQR(noiseccr); + variCb[0] = SQR(noisecfb); + variCb[1] = SQR(noisecfb); + variCb[2] = SQR(noisecfb); + variCb[3] = SQR(noisecfb); + variCb[4] = SQR(noisecfb); + variCb[5] = SQR(1.2f * noiseccb); + variCb[6] = SQR(1.5f * noiseccb); - variCb[0] = SQR(noisecfb); - variCb[1] = SQR(noisecfb); - variCb[2] = SQR(noisecfb); - - variCb[3] = SQR(noisecfb); - variCb[4] = SQR(noisecfb); - variCb[5] = SQR(noiseccb); - variCb[6] = SQR(noiseccb); - - } else if (levred == 4) { - edge = 3; - variC[0] = SQR(lp.noisecf / 10.f); - variC[1] = SQR(lp.noisecf / 10.f); - variC[2] = SQR(lp.noisecf / 10.f); - variC[3] = SQR(lp.noisecf / 10.f); - - variCb[0] = SQR(lp.noisecf / 10.f); - variCb[1] = SQR(lp.noisecf / 10.f); - variCb[2] = SQR(lp.noisecf / 10.f); - variCb[3] = SQR(lp.noisecf / 10.f); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - variC[0] = SQR(slida[0]); - variC[1] = SQR(slida[1]); - variC[2] = SQR(slida[2]); - variC[3] = SQR(slida[3]); - variC[4] = SQR(slida[4]); - variC[5] = SQR(slida[5]); - variC[6] = SQR(slida[6]); - float maxc01 = rtengine::max(slida[0], slida[1]); - float maxc23 = rtengine::max(slida[2], slida[3]); - float max03 = rtengine::max(maxc01, maxc23); - float maxrf = rtengine::max(max03, slida[4]); - float maxrc = rtengine::max(slida[5], slida[6]); - - variCb[0] = SQR(slidb[0]); - variCb[1] = SQR(slidb[1]); - variCb[2] = SQR(slidb[2]); - variCb[3] = SQR(slidb[3]); - variCb[4] = SQR(slidb[4]); - variCb[5] = SQR(slidb[5]); - variCb[6] = SQR(slidb[6]); - float maxb01 = rtengine::max(slidb[0], slidb[1]); - float maxb23 = rtengine::max(slidb[2], slidb[3]); - float maxb03 = rtengine::max(maxb01, maxb23); - float maxbf = rtengine::max(maxb03, slidb[4]); - maxcfine = rtengine::max(maxrf, maxbf); - - float maxbc = rtengine::max(slidb[5], slidb[6]); - maxccoarse = rtengine::max(maxrc, maxbc); - - } { float minic = 0.000001f; @@ -11299,52 +11220,51 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float k2 = 0.f; float k3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noisecf < 0.2f && aut == 0) || (maxcfine < 0.2f && aut == 1)) { + if (lp.noisecf < 0.2f) { k1 = 0.05f; k2 = 0.f; k3 = 0.f; - } else if ((lp.noisecf < 0.3f && aut == 0) || (maxcfine < 0.3f && aut == 1)) { + } else if (lp.noisecf < 0.3f) { k1 = 0.1f; k2 = 0.0f; k3 = 0.f; - } else if ((lp.noisecf < 0.5f && aut == 0) || (maxcfine < 0.5f && aut == 1)) { + } else if (lp.noisecf < 0.5f) { k1 = 0.2f; k2 = 0.1f; k3 = 0.f; - } else if ((lp.noisecf < 0.8f && aut == 0) || (maxcfine < 0.8f && aut == 1)) { + } else if (lp.noisecf < 0.8f) { k1 = 0.3f; k2 = 0.25f; k3 = 0.f; - } else if ((lp.noisecf < 1.f && aut == 0) || (maxcfine < 1.f && aut == 1)) { + } else if (lp.noisecf < 1.f) { k1 = 0.4f; k2 = 0.25f; k3 = 0.1f; - } else if ((lp.noisecf < 2.f && aut == 0) || (maxcfine < 2.f && aut == 1)) { + } else if (lp.noisecf < 2.f) { k1 = 0.5f; k2 = 0.3f; k3 = 0.15f; - } else if ((lp.noisecf < 3.f && aut == 0) || (maxcfine < 3.f && aut == 1)) { + } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; - } else if ((lp.noisecf < 4.f && aut == 0) || (maxcfine < 4.f && aut == 1)) { + } else if (lp.noisecf < 4.f) { k1 = 0.7f; k2 = 0.5f; k3 = 0.4f; - } else if ((lp.noisecf < 5.f && aut == 0) || (maxcfine < 5.f && aut == 1)) { + } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; - } else if ((lp.noisecf < 6.f && aut == 0) || (maxcfine < 10.f && aut == 1)) { + } else if (lp.noisecf < 6.f) { k1 = 0.85f; k2 = 0.7f; k3 = 0.6f; - } else if ((lp.noisecf < 8.f && aut == 0) || (maxcfine < 20.f && aut == 1)) { + } else if (lp.noisecf < 8.f) { k1 = 0.9f; k2 = 0.8f; k3 = 0.7f; - } else if ((lp.noisecf < 10.f && aut == 0) || (maxcfine < 50.f && aut == 1)) { + } else if (lp.noisecf < 10.f) { k1 = 1.f; k2 = 1.f; k3 = 0.9f; @@ -11352,14 +11272,8 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } else { k1 = 1.f; k2 = 1.f; - k3 = 1.f; + k3 = 1.5f; } - } else if (aut == 2) { - k1 = 1.f; - k2 = 1.f; - k3 = 1.f; - } - variC[0] = rtengine::max(minic, variC[0]); variC[1] = rtengine::max(minic, k1 * variC[1]); @@ -11371,27 +11285,26 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[2] = rtengine::max(minic, k2 * variCb[2]); variCb[3] = rtengine::max(minic, k3 * variCb[3]); - if (levred == 7) { float k4 = 0.f; float k5 = 0.f; float k6 = 0.f; - if ((lp.noisecc < 0.2f && aut == 0) || (maxccoarse < 0.2f && aut == 1)) { + if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.02f; - } else if ((lp.noisecc < 0.5f && aut == 0) || (maxccoarse < 0.5f && aut == 1)) { + } else if (lp.noisecc < 0.5f) { k4 = 0.15f; k5 = 0.05f; - } else if ((lp.noisecc < 1.f && aut == 0) || (maxccoarse < 1.f && aut == 1)) { + } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if ((lp.noisecc < 3.f && aut == 0) || (maxccoarse < 3.f && aut == 1)) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; k5 = 0.6f; } else { @@ -11404,11 +11317,11 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[4] = rtengine::max(0.000001f, k4 * variCb[4]); variCb[5] = rtengine::max(0.000001f, k5 * variCb[5]); - if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 4.f && aut == 1)) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if ((lp.noisecc < 5.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k6 = 0.7f; } else { k6 = 1.f; @@ -11417,7 +11330,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variC[6] = rtengine::max(0.00001f, k6 * variC[6]); variCb[6] = rtengine::max(0.00001f, k6 * variCb[6]); - } float* noisevarchrom = new float[GH * GW]; //noisevarchrom in function chroma @@ -11425,7 +11337,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float nvch = 0.6f;//high value float nvcl = 0.1f;//low value - if ((lp.noisecf > 100.f && aut == 0) || (maxcfine > 100.f && (aut == 1 || aut == 2))) { + if (lp.noisecf > 100.f) { nvch = 0.8f; nvcl = 0.4f; } @@ -11534,7 +11446,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - if(gamma > 1.f) { #ifdef _OPENMP # pragma omp parallel for schedule(dynamic,16) if (multiThread) @@ -11552,10 +11463,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - 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) { LabImage tmp3(GW, GH); @@ -11634,7 +11541,82 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl masklum.free(); masklumch.free(); } - DeNoise_Local(call, lp, originalmaskbl, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); + +// re read wavelet decomposition to calaculate noise residual + float chresid = 0.f; + float chresidtemp = 0.f; + float chmaxresid = 0.f; + float chmaxresidtemp = 0.f; + float chresid46 = 0.f; + float chresidtemp46 = 0.f; + float chmaxresid46 = 0.f; + float chmaxresidtemp46 = 0.f; + float Lresid = 0.f; + float Lmaxresid = 0.f; + float Lresid46 = 0.f; + float Lmaxresid46 = 0.f; + + +//calculate and display residual noise luma and chroma +// various coefficient from 1 to 5 - tries to take into account the difference between calculate Noise and percepted noise + wavelet_decomposition Ldecompinf(tmp1.L[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + wavelet_decomposition adecompinf(tmp1.a[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + wavelet_decomposition bdecompinf(tmp1.b[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + + Noise_residualAB(adecompinf, chresid, chmaxresid, false, 0, 3); + chresidtemp = chresid; + chmaxresidtemp = chmaxresid; + Noise_residualAB(bdecompinf, chresid, chmaxresid, false, 0, 3); + chresid += chresidtemp; + chmaxresid += chmaxresidtemp; + int nbmaddir = 4; + chresid = sqrt(chresid / ( 3 * nbmaddir * 2)); + highresi = chresid + 0.5f * (sqrt(chmaxresid) - chresid); //evaluate sigma + nresi = chresid; + highresi /= 1.4f;//arbitrary coefficient + nresi /= 1.4f; + + // printf("nresi03=%f highresi=%f \n", (double) nresi, (double) highresi); + + + Noise_residualAB(adecompinf, chresid46, chmaxresid46, false, 4, 6); + nbmaddir = 3; + chresidtemp46 = chresid46; + chmaxresidtemp46 = chmaxresid46; + Noise_residualAB(bdecompinf, chresid46, chmaxresid46, false, 4, 6); + chresid46 += chresidtemp46; + chmaxresid46 += chmaxresidtemp46; + chresid46 = sqrt(chresid46 / ( 3 * nbmaddir * 2)); + highresi46 = chresid46 + 0.5f * (sqrt(chmaxresid46) - chresid46); //evaluate sigma + nresi46 = chresid46; + highresi46 /= 2.f;//arbitrary coefficient + nresi46 /= 2.f; + + // printf("nresi46=%f highresi=%f \n", (double) nresi46, (double) highresi46); + + + Noise_residualAB(Ldecompinf, Lresid, Lmaxresid, false, 0, 3); + nbmaddir = 4; + Lresid = sqrt(Lresid / (3 * nbmaddir)); + Lhighresi = Lresid + 0.5f * (sqrt(Lmaxresid) - Lresid); //evaluate sigma + Lnresi = Lresid; + Lnresi /= 2.f;//arbitrary coefficient + Lhighresi /= 2.f; + // printf("Lresi03=%f Lhighresi=%f levwavL=%i\n", (double) Lnresi, (double) Lhighresi, levwavL); + + Noise_residualAB(Ldecompinf, Lresid46, Lmaxresid46, false, 4, 6); + nbmaddir = 3; + Lresid46 = sqrt(Lresid46 / (3 * nbmaddir)); + Lhighresi46 = Lresid46 + 0.5f * (sqrt(Lmaxresid46) - Lresid46); //evaluate sigma + Lnresi46 = Lresid46; + Lhighresi46 /= 5.f;//arbitrary coefficient + Lnresi46 /= 5.f; + // printf("Lresi46=%f Lhighresi=%f levwavL=%i\n", (double) Lnresi46, (double) Lhighresi46, levwavL); + +// end calculate + + DeNoise_Local(call, lp, originalmaskbl, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); + } else { DeNoise_Local(call, lp, original, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); } @@ -11731,69 +11713,40 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float vari[levred]; float mxsl = 0.f; - // float mxsfl = 0.f; - if (aut == 0) { - if (levred == 7) { + { edge = 2; vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[4] = 0.8f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); - vari[5] = 0.8f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); - vari[6] = 0.8f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); - } else if (levred == 4) { - edge = 3; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - vari[0] = SQR(slidL[0]); - vari[1] = SQR(slidL[1]); - vari[2] = SQR(slidL[2]); - vari[3] = SQR(slidL[3]); - vari[4] = SQR(slidL[4]); - vari[5] = SQR(slidL[5]); - vari[6] = SQR(slidL[6]); - float mxslid34 = rtengine::max(slidL[3], slidL[4]); - float mxslid56 = rtengine::max(slidL[5], slidL[6]); - mxsl = rtengine::max(mxslid34, mxslid56); - - } + vari[4] = 1.f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); + vari[5] = 1.5f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); + vari[6] = 2.5f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); + } { float kr3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noiselc < 30.f && aut == 0) || (mxsl < 30.f && aut == 1)) { + { + if (lp.noiselc < 30.f) { kr3 = 0.f; - } else if ((lp.noiselc < 50.f && aut == 0) || (mxsl < 50.f && aut == 1)) { + } else if (lp.noiselc < 50.f) { kr3 = 0.5f; - } else if ((lp.noiselc < 70.f && aut == 0) || (mxsl < 70.f && aut == 1)) { + } else if (lp.noiselc < 70.f) { kr3 = 0.7f; } else { kr3 = 1.f; } - } else if (aut == 2) { - kr3 = 1.f; - } + } vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); - - if (levred == 7) { - vari[4] = rtengine::max(0.000001f, vari[4]); - vari[5] = rtengine::max(0.000001f, vari[5]); - vari[6] = rtengine::max(0.000001f, vari[6]); - } + vari[4] = rtengine::max(0.000001f, vari[4]); + vari[5] = rtengine::max(0.000001f, vari[5]); + vari[6] = rtengine::max(0.000001f, vari[6]); // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL float* noisevarlum = new float[bfh * bfw]; @@ -11930,77 +11883,28 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { - float maxcfine = 0.f; float maxccoarse = 0.f; - if (aut == 0) { - if (levred == 7) { + { edge = 2; variC[0] = SQR(noisecfr); variC[1] = SQR(noisecfr); variC[2] = SQR(noisecfr); - - variC[3] = SQR(noisecfr); + variC[3] = SQR(1.2f * noisecfr); variC[4] = SQR(noisecfr); - variC[5] = SQR(noiseccr); - variC[6] = SQR(noiseccr); + variC[5] = SQR(1.2f * noiseccr); + variC[6] = SQR(1.5f * noiseccr); variCb[0] = SQR(noisecfb); variCb[1] = SQR(noisecfb); variCb[2] = SQR(noisecfb); - variCb[3] = SQR(noisecfb); variCb[4] = SQR(noisecfb); - variCb[5] = SQR(noiseccb); - variCb[6] = SQR(noiseccb); + variCb[5] = SQR(1.2f * noiseccb); + variCb[6] = SQR(1.5f * noiseccb); - } else if (levred == 4) { - edge = 3; - variC[0] = SQR(lp.noisecf / 10.f); - variC[1] = SQR(lp.noisecf / 10.f); - variC[2] = SQR(lp.noisecf / 10.f); - variC[3] = SQR(lp.noisecf / 10.f); - - variCb[0] = SQR(lp.noisecf / 10.f); - variCb[1] = SQR(lp.noisecf / 10.f); - variCb[2] = SQR(lp.noisecf / 10.f); - variCb[3] = SQR(lp.noisecf / 10.f); - - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - variC[0] = SQR(slida[0]); - variC[1] = SQR(slida[1]); - variC[2] = SQR(slida[2]); - variC[3] = SQR(slida[3]); - variC[4] = SQR(slida[4]); - variC[5] = SQR(slida[5]); - variC[6] = SQR(slida[6]); - float maxc01 = rtengine::max(slida[0], slida[1]); - float maxc23 = rtengine::max(slida[2], slida[3]); - float max03 = rtengine::max(maxc01, maxc23); - float maxrf = rtengine::max(max03, slida[4]); - float maxrc = rtengine::max(slida[5], slida[6]); - - variCb[0] = SQR(slidb[0]); - variCb[1] = SQR(slidb[1]); - variCb[2] = SQR(slidb[2]); - variCb[3] = SQR(slidb[3]); - variCb[4] = SQR(slidb[4]); - variCb[5] = SQR(slidb[5]); - variCb[6] = SQR(slidb[6]); - float maxb01 = rtengine::max(slidb[0], slidb[1]); - float maxb23 = rtengine::max(slidb[2], slidb[3]); - float maxb03 = rtengine::max(maxb01, maxb23); - float maxbf = rtengine::max(maxb03, slidb[4]); - maxcfine = rtengine::max(maxrf, maxbf); - - float maxbc = rtengine::max(slidb[5], slidb[6]); - maxccoarse = rtengine::max(maxrc, maxbc); - - } + } { float minic = 0.000001f; @@ -12013,52 +11917,51 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float k2 = 0.f; float k3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noisecf < 0.2f && aut == 0) || (maxcfine < 0.2f && aut == 1)) { + if (lp.noisecf < 0.2f) { k1 = 0.05f; k2 = 0.f; k3 = 0.f; - } else if ((lp.noisecf < 0.3f && aut == 0) || (maxcfine < 0.3f && aut == 1)) { + } else if (lp.noisecf < 0.3f) { k1 = 0.1f; k2 = 0.0f; k3 = 0.f; - } else if ((lp.noisecf < 0.5f && aut == 0) || (maxcfine < 0.5f && aut == 1)) { + } else if (lp.noisecf < 0.5f) { k1 = 0.2f; k2 = 0.1f; k3 = 0.f; - } else if ((lp.noisecf < 0.8f && aut == 0) || (maxcfine < 0.8f && aut == 1)) { + } else if (lp.noisecf < 0.8f) { k1 = 0.3f; k2 = 0.25f; k3 = 0.f; - } else if ((lp.noisecf < 1.f && aut == 0) || (maxcfine < 1.f && aut == 1)) { + } else if (lp.noisecf < 1.f) { k1 = 0.4f; k2 = 0.25f; k3 = 0.1f; - } else if ((lp.noisecf < 2.f && aut == 0) || (maxcfine < 2.f && aut == 1)) { + } else if (lp.noisecf < 2.f) { k1 = 0.5f; k2 = 0.3f; k3 = 0.15f; - } else if ((lp.noisecf < 3.f && aut == 0) || (maxcfine < 3.f && aut == 1)) { + } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; - } else if ((lp.noisecf < 4.f && aut == 0) || (maxcfine < 4.f && aut == 1)) { + } else if (lp.noisecf < 4.f) { k1 = 0.7f; k2 = 0.5f; k3 = 0.4f; - } else if ((lp.noisecf < 5.f && aut == 0) || (maxcfine < 5.f && aut == 1)) { + } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; - } else if ((lp.noisecf < 6.f && aut == 0) || (maxcfine < 10.f && aut == 1)) { + } else if (lp.noisecf < 6.f) { k1 = 0.85f; k2 = 0.7f; k3 = 0.6f; - } else if ((lp.noisecf < 8.f && aut == 0) || (maxcfine < 20.f && aut == 1)) { + } else if (lp.noisecf < 8.f) { k1 = 0.9f; k2 = 0.8f; k3 = 0.7f; - } else if ((lp.noisecf < 10.f && aut == 0) || (maxcfine < 50.f && aut == 1)) { + } else if (lp.noisecf < 10.f) { k1 = 1.f; k2 = 1.f; k3 = 0.9f; @@ -12066,13 +11969,8 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } else { k1 = 1.f; k2 = 1.f; - k3 = 1.f; + k3 = 1.5f; } - } else if (aut == 2) { - k1 = 1.f; - k2 = 1.f; - k3 = 1.f; - } variC[0] = rtengine::max(minic, variC[0]); variC[1] = rtengine::max(minic, k1 * variC[1]); @@ -12084,27 +11982,27 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[2] = rtengine::max(minic, k2 * variCb[2]); variCb[3] = rtengine::max(minic, k3 * variCb[3]); - if (levred == 7) { + { float k4 = 0.f; float k5 = 0.f; float k6 = 0.f; - if ((lp.noisecc < 0.2f && aut == 0) || (maxccoarse < 0.2f && aut == 1)) { + if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.02f; - } else if ((lp.noisecc < 0.5f && aut == 0) || (maxccoarse < 0.5f && aut == 1)) { + } else if (lp.noisecc < 0.5f) { k4 = 0.15f; k5 = 0.05f; - } else if ((lp.noisecc < 1.f && aut == 0) || (maxccoarse < 1.f && aut == 1)) { + } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if ((lp.noisecc < 3.f && aut == 0) || (maxccoarse < 3.f && aut == 1)) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; k5 = 0.6f; } else { @@ -12118,11 +12016,11 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[4] = rtengine::max(0.000001f, k4 * variCb[4]); variCb[5] = rtengine::max(0.000001f, k5 * variCb[5]); - if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 4.f && aut == 1)) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if ((lp.noisecc < 5.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k6 = 0.7f; } else { k6 = 1.f; @@ -12137,7 +12035,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float nvch = 0.6f;//high value float nvcl = 0.1f;//low value - if ((lp.noisecf > 30.f && aut == 0) || (maxcfine > 100.f && (aut == 1 || aut == 2))) { + if (lp.noisecf > 30.f) { nvch = 0.8f; nvcl = 0.4f; } @@ -12377,6 +12275,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } } + } } @@ -13363,7 +13262,9 @@ 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& 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 + ) { //general call of others functions : important return hueref, chromaref, lumaref @@ -14410,12 +14311,9 @@ void ImProcFunctions::Lab_Local( //local denoise if (lp.activspot && lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi ||lp.nlstr > 0 || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used - float slidL[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float slida[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float slidb[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; constexpr int aut = 0; - DeNoise(call, slidL, slida, slidb, aut, noiscfactiv, lp, originalmaskbl.get(), bufmaskblurbl.get(), levred, huerefblur, lumarefblur, chromarefblur, original, transformed, cx, cy, sk, locwavCurvehue, locwavhueutili); - + DeNoise(call, aut, noiscfactiv, lp, originalmaskbl.get(), bufmaskblurbl.get(), levred, huerefblur, lumarefblur, chromarefblur, original, transformed, cx, cy, sk, locwavCurvehue, locwavhueutili, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; @@ -19275,6 +19173,7 @@ 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); } } + } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index f86950457..1d7994ace 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -438,9 +438,21 @@ public: double Tmax; }; + struct locallabDenoiseLC { + double highres; + double nres; + double highres46; + double nres46; + double Lhighres; + double Lnres; + double Lhighres46; + double Lnres46; + }; + 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 refChanged2(float *huerefp, float *chromarefp, float *lumarefp, float *fabrefp, int selspot) = 0; }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 78dd84042..96cd68d43 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1175,6 +1175,14 @@ private: float Tsigma; float Tmin; float Tmax; + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; // 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, @@ -1229,7 +1237,8 @@ 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 + meantme, stdtme, meanretie, stdretie, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46 ); if (sp + 1u < params.locallab.spots.size()) { diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 8e8e999d3..e7725a005 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -703,6 +703,19 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited expreti.updateMinMax(cdma, cdmin, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } + // Update Locallab Denoise tool lum/chro + if (pp->locallab.selspot < (int) denoiselc.size()) { + const double highres = denoiselc.at(pp->locallab.selspot).highres; + const double nres = denoiselc.at(pp->locallab.selspot).nres; + const double highres46 = denoiselc.at(pp->locallab.selspot).highres46; + const double nres46 = denoiselc.at(pp->locallab.selspot).nres46; + const double Lhighres = denoiselc.at(pp->locallab.selspot).Lhighres; + const double Lnres = denoiselc.at(pp->locallab.selspot).Lnres; + const double Lhighres46 = denoiselc.at(pp->locallab.selspot).Lhighres46; + const double Lnres46 = denoiselc.at(pp->locallab.selspot).Lnres46; + + expblur.updatedenlc(highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46); + } // Update default values according to selected spot setDefaults(pp, pedited); @@ -1094,6 +1107,28 @@ void Locallab::minmaxChanged(const std::vector &minmax, int } } +void Locallab::denChanged(const std::vector &denlc, int selspot) +{ + // Saving transmitted min/max data + denoiselc = denlc; + + //Update Locallab Denoise tool lum chro + if (selspot < (int) denoiselc.size()) { + const double highres = denoiselc.at(selspot).highres; + const double nres = denoiselc.at(selspot).nres; + const double highres46 = denoiselc.at(selspot).highres46; + const double nres46 = denoiselc.at(selspot).nres46; + const double Lhighres = denoiselc.at(selspot).Lhighres; + const double Lnres = denoiselc.at(selspot).Lnres; + const double Lhighres46 = denoiselc.at(selspot).Lhighres46; + const double Lnres46 = denoiselc.at(selspot).Lnres46; + + expblur.updatedenlc(highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46); + } + +} + + 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) { // Update Locallab Log Encoding and Ciecam accordingly diff --git a/rtgui/locallab.h b/rtgui/locallab.h index b0030bbe6..e39f213cc 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -123,6 +123,9 @@ private: // Locallab tools mask background management data std::vector retiMinMax; + // Locallab tools mask background management data + std::vector denoiselc; + // Locallab tools mask background management data std::vector maskBackRef; @@ -145,6 +148,10 @@ public: // Locallab Retinex tool min/man management function void minmaxChanged(const std::vector &minmax, int selspot) override; + //Locallab denoise + // 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; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index c59dd233a..2ebac1630 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -6477,8 +6477,17 @@ LocallabBlur::LocallabBlur(): activlum(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIV")))), expdenoise(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI_EXP")))), quamethod(Gtk::manage(new MyComboBoxText())), + expdenoisenl(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_NLFRA")))), + expdenoiselum(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOIWAVLUM")))), + expdenoisech(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOIWAVCH")))), LocalcurveEditorwavden(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVDEN"))), wavshapeden(static_cast(LocalcurveEditorwavden->addCurve(CT_Flat, "", nullptr, false, false))), + // lCLabels(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_LCLABELS")))), + lCLabels(Gtk::manage(new Gtk::Label("-----------------"))), + lumLabels(Gtk::manage(new Gtk::Label("---"))), + lum46Labels(Gtk::manage(new Gtk::Label("---"))), + chroLabels(Gtk::manage(new Gtk::Label("---"))), + chro46Labels(Gtk::manage(new Gtk::Label("---"))), expdenoise1(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI1_EXP")))), maskusable(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), maskunusable(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), @@ -6514,7 +6523,7 @@ LocallabBlur::LocallabBlur(): decayd(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKDDECAY"), 0.5, 4., 0.1, 2.))), invmaskd(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVMASK")))), invmask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVMASK")))), - nlFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_NLFRA")))), + prevFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LCLABELS")))), nlstr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLLUM"), 0, 100, 1, 0))), nldet(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLDET"), 0, 100, 1, 50))), nlpat(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLPAT"), 1, 5, 1, 2))), @@ -6640,12 +6649,23 @@ LocallabBlur::LocallabBlur(): Gtk::Label* const quaLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENQUA") + ":")); quaHBox->pack_start(*quaLabel, Gtk::PACK_SHRINK, 4); quaHBox->pack_start(*quamethod); + setExpandAlignProperties(expdenoisenl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + setExpandAlignProperties(expdenoiselum, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + setExpandAlignProperties(expdenoisech, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); LocalcurveEditorwavden->setCurveListener(this); wavshapeden->setIdentityValue(0.); wavshapeden->setResetCurve(FlatCurveType(defSpot.locwavcurveden.at(0)), defSpot.locwavcurveden); + setExpandAlignProperties(lCLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(lumLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(lum46Labels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + + setExpandAlignProperties(chroLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(chro46Labels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + + LocalcurveEditorwavden->curveListComplete(); setExpandAlignProperties(expdenoise1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -6701,7 +6721,7 @@ LocallabBlur::LocallabBlur(): decayd->setAdjusterListener(this); bilateral->setAdjusterListener(this); - nlFrame->set_label_align(0.025, 0.5); + prevFrame->set_label_align(0.025, 0.5); nlstr->setAdjusterListener(this); nldet->setAdjusterListener(this); @@ -6838,15 +6858,39 @@ LocallabBlur::LocallabBlur(): Gtk::Frame* const wavFrame = Gtk::manage(new Gtk::Frame()); ToolParamBlock* const wavBox = Gtk::manage(new ToolParamBlock()); wavBox->pack_start(*quaHBox); - wavBox->pack_start(*LocalcurveEditorwavden, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + wavBox->pack_start(*sensiden); + wavBox->pack_start(*reparden); + ToolParamBlock* const prevBox = Gtk::manage(new ToolParamBlock()); + prevBox->pack_start(*lumLabels); + prevBox->pack_start(*lum46Labels); + prevBox->pack_start(*lCLabels); + prevBox->pack_start(*chroLabels); + prevBox->pack_start(*chro46Labels); + prevFrame->add(*prevBox); + wavBox->pack_start(*prevFrame); + + ToolParamBlock* const nlbox = Gtk::manage(new ToolParamBlock()); + nlbox->pack_start(*nlstr); + nlbox->pack_start(*nldet); + nlbox->pack_start(*nlgam); + nlbox->pack_start(*nlpat); + nlbox->pack_start(*nlrad); + expdenoisenl->add(*nlbox); + + wavBox->pack_start(*expdenoisenl); + + // 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(*noiselumdetail); - wavBox->pack_start(*noiselequal); - wavBox->pack_start(*noisegam); - wavBox->pack_start(*LocalcurveEditorwavhue, Gtk::PACK_SHRINK, 4); + ToolParamBlock* const wchBox = Gtk::manage(new ToolParamBlock()); + + wchBox->pack_start(*LocalcurveEditorwavden, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + wchBox->pack_start(*noiselumdetail); + wchBox->pack_start(*noiselequal); + wchBox->pack_start(*noisegam); + wchBox->pack_start(*LocalcurveEditorwavhue, Gtk::PACK_SHRINK, 4); ToolParamBlock* const wavBox1 = Gtk::manage(new ToolParamBlock()); wavBox1->pack_start(*maskusable, Gtk::PACK_SHRINK, 0); wavBox1->pack_start(*maskunusable, Gtk::PACK_SHRINK, 0); @@ -6854,28 +6898,24 @@ LocallabBlur::LocallabBlur(): wavBox1->pack_start(*levelthrlow, Gtk::PACK_SHRINK, 0); wavBox1->pack_start(*levelthr, Gtk::PACK_SHRINK, 0); expdenoise1->add(*wavBox1, false); - wavBox->pack_start(*expdenoise1); + wchBox->pack_start(*expdenoise1); + expdenoiselum->add(*wchBox); + wavBox->pack_start(*expdenoiselum); + ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock()); + + chBox->pack_start(*noisechrof); + chBox->pack_start(*noisechroc); + chBox->pack_start(*noisechrodetail); + chBox->pack_start(*adjblur); + expdenoisech->add(*chBox); + wavBox->pack_start(*expdenoisech); + ToolParamBlock* const detailBox = Gtk::manage(new ToolParamBlock()); detailBox->pack_start(*detailthr); detailBox->pack_start(*usemask, Gtk::PACK_SHRINK, 0); detailFrame->add(*detailBox); 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); - nlbox->pack_start(*nlgam); - nlbox->pack_start(*nlpat); - nlbox->pack_start(*nlrad); - nlFrame->add(*nlbox); - wavBox->pack_start(*nlFrame); - - wavBox->pack_start(*noisechrof); - wavBox->pack_start(*noisechroc); - wavBox->pack_start(*noisechrodetail); - wavBox->pack_start(*adjblur); + wavFrame->add(*wavBox); denoisebox->pack_start(*wavFrame); @@ -6978,6 +7018,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) expdenoise1->set_tooltip_markup(M("TP_LOCALLAB_MASKLC_TOOLTIP")); expdenoise2->set_tooltip_markup(M("TP_LOCALLAB_MASKGF_TOOLTIP")); expdenoise3->set_tooltip_markup(M("TP_LOCALLAB_MASKDE_TOOLTIP")); + expdenoisenl->set_tooltip_markup(M("TP_LOCALLAB_NLFRAME_TOOLTIP")); invmask->set_tooltip_text(M("TP_LOCALLAB_MASKDEINV_TOOLTIP")); invmaskd->set_tooltip_text(M("TP_LOCALLAB_MASKDEINV_TOOLTIP")); LocalcurveEditorwavden->setTooltip(M("TP_LOCALLAB_WASDEN_TOOLTIP")); @@ -6990,7 +7031,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) detailthr->set_tooltip_text(M("TP_LOCALLAB_DENOITHR_TOOLTIP")); adjblur->set_tooltip_text(M("TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP")); bilateral->set_tooltip_text(M("TP_LOCALLAB_DENOIBILAT_TOOLTIP")); - nlFrame->set_tooltip_text(M("TP_LOCALLAB_NLFRAME_TOOLTIP")); + prevFrame->set_tooltip_text(M("TP_LOCALLAB_LCLABELS_TOOLTIP")); nlstr->set_tooltip_text(M("TP_LOCALLAB_NLDENOISE_TOOLTIP")); nldet->set_tooltip_text(M("TP_LOCALLAB_NLDENOISE_TOOLTIP")); nlpat->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP")); @@ -7025,6 +7066,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) higthresd->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP")); higthres->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRES_TOOLTIP")); decayd->set_tooltip_text(M("TP_LOCALLAB_MASKDECAY_TOOLTIP")); + lCLabels->set_tooltip_text(M("TP_LOCALLAB_LCLABELS_TOOLTIP")); } else { expblnoise->set_tooltip_markup(""); @@ -7057,7 +7099,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) detailthr->set_tooltip_text(""); adjblur->set_tooltip_text(""); bilateral->set_tooltip_text(""); - nlFrame->set_tooltip_text(""); + prevFrame->set_tooltip_text(""); nlstr->set_tooltip_text(""); nldet->set_tooltip_text(""); nlpat->set_tooltip_text(""); @@ -7094,6 +7136,8 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) higthres->set_tooltip_text(""); // midthresd->set_tooltip_text(""); decayd->set_tooltip_text(""); + lCLabels->set_tooltip_text(""); + expdenoisenl->set_tooltip_markup(""); } } @@ -7138,7 +7182,36 @@ void LocallabBlur::neutral_pressed () } +void LocallabBlur::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) +{ + idle_register.add( + [this, highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + lumLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_LUMLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), Lnres), + Glib::ustring::format(std::fixed, std::setprecision(0), Lhighres)) + ); + lum46Labels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_LUM46LABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), Lnres46 ), + Glib::ustring::format(std::fixed, std::setprecision(0), Lhighres46)) + ); + chroLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_CHROLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nres), + Glib::ustring::format(std::fixed, std::setprecision(0), highres)) + ); + chro46Labels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_CHRO46LABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nres46), + Glib::ustring::format(std::fixed, std::setprecision(0), highres46)) + ); + return false; + } + ); +} void LocallabBlur::setDefaultExpanderVisibility() { expblnoise->set_expanded(false); @@ -7147,6 +7220,9 @@ void LocallabBlur::setDefaultExpanderVisibility() expdenoise2->set_expanded(false); expdenoise3->set_expanded(false); expmaskbl->set_expanded(false); + expdenoisenl->set_expanded(false); + expdenoiselum->set_expanded(false); + expdenoisech->set_expanded(false); } void LocallabBlur::disableListener() diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index c4e54ca61..ced248ae1 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -707,8 +707,17 @@ private: Gtk::CheckButton* const activlum; MyExpander* const expdenoise; MyComboBoxText* const quamethod; + MyExpander* const expdenoisenl; + MyExpander* const expdenoiselum; + MyExpander* const expdenoisech; CurveEditorGroup* const LocalcurveEditorwavden; FlatCurveEditor* const wavshapeden; + Gtk::Label* const lCLabels; + Gtk::Label* const lumLabels; + Gtk::Label* const lum46Labels; + Gtk::Label* const chroLabels; + Gtk::Label* const chro46Labels; + MyExpander* const expdenoise1; Gtk::Label* const maskusable; Gtk::Label* const maskunusable; @@ -746,7 +755,7 @@ private: Gtk::CheckButton* const invmaskd; Gtk::CheckButton* const invmask; - Gtk::Frame* const nlFrame; + Gtk::Frame* const prevFrame; Adjuster* const nlstr; Adjuster* const nldet; Adjuster* const nlpat; @@ -788,6 +797,8 @@ private: public: LocallabBlur(); ~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; From 1ea0ef8af19d85a08c719761a0a1730b46cb1e9e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 17 Jun 2023 22:07:46 -0700 Subject: [PATCH 260/326] Fix HSV equalizer pipette crash Check if pipette buffer is valid before filling it in the RGB process. --- rtengine/improcfun.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 3f9a426cf..cab89c10b 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1985,7 +1985,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer Imagefloat* editImgFloat = nullptr; PlanarWhateverData* editWhatever = nullptr; - EditUniqueID editID = pipetteBuffer ? pipetteBuffer->getEditID() : EUID_None; + EditUniqueID editID = pipetteBuffer && pipetteBuffer->bufferCreated() ? pipetteBuffer->getEditID() : EUID_None; if (editID != EUID_None) { switch (pipetteBuffer->getDataProvider()->getCurrSubscriber()->getPipetteBufferType()) { From 8e64057e23be8400d15bee941b365cbf58fd4092 Mon Sep 17 00:00:00 2001 From: Christian-Kr Date: Sun, 18 Jun 2023 12:54:45 +0200 Subject: [PATCH 261/326] Add .idea to .gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fc65c877c..2cae259ab 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .settings .directory .vscode +.idea CMakeCache.txt CMakeFiles From a4eeb66145c114cff4d75300c7995a6f8b370b2f Mon Sep 17 00:00:00 2001 From: Christian-Kr Date: Mon, 19 Jun 2023 19:05:42 +0200 Subject: [PATCH 262/326] Set dummy width and height for ThumbBrowserEntry, cause height will be used to calculate the height of the scroll pane. Positions also need to be set as a dummy, cause no method allows only width or height. --- rtgui/thumbbrowserbase.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 8f3499c2a..62c8a56bd 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -781,6 +781,7 @@ void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) for (int i = 0; ct < fd.size() && i < numOfCols; ++i, ++ct) { for (; ct < fd.size() && fd[ct]->filtered; ++ct) { + fd[ct]->setPosition(0, 0, colWidths[i], rowHeight); fd[ct]->drawable = false; } From 960d1fef1fbd3e6e70aa97eb752433aa8a4ba364 Mon Sep 17 00:00:00 2001 From: Christian-Kr Date: Mon, 19 Jun 2023 19:52:25 +0200 Subject: [PATCH 263/326] Variable done should be set to true inside loop, otherwise one fail will cause to stay in loop forever. --- rtgui/profilepanel.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index 8ce9055d0..7d2910cef 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -339,6 +339,8 @@ void ProfilePanel::save_clicked (GdkEventButton* event) bool done = true; do { + done = true; + if (dialog.run() == Gtk::RESPONSE_OK) { std::string fname = dialog.get_filename(); From 27f247e8db202ee124de94d2aeab5e0ad1ca4423 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 20 Jun 2023 22:25:10 -0700 Subject: [PATCH 264/326] Crop row of bad pixels for Canon EOS 7D Mark II --- rtengine/camconst.json | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 352dc26e1..527bbe682 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -647,6 +647,7 @@ Camera constants: "make_model": "Canon EOS 7D Mark II", "dcraw_matrix": [ 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 ], // dng_v8.7 d65 //"dcraw_matrix": [ 6285,-147,-821,-4080,11695,2714,-1045,2459,5497 ], // DXO D50 + "raw_crop": [ 72, 38, 5496, 3669 ], "ranges": { "white": [ { "iso": [ 100, 125 ], "levels": 13500 }, // typical 13583 - LENR 13550 From 0507b0a26a16b0aec63b79186c0ac3e21121f01f Mon Sep 17 00:00:00 2001 From: Christian-Kr Date: Sun, 25 Jun 2023 06:50:13 +0200 Subject: [PATCH 265/326] Add a comment why setting the position of a not drawn thumb is needed here. --- rtgui/thumbbrowserbase.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 62c8a56bd..f697d6648 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -781,7 +781,11 @@ void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) for (int i = 0; ct < fd.size() && i < numOfCols; ++i, ++ct) { for (; ct < fd.size() && fd[ct]->filtered; ++ct) { + // Thumbs that are not going be drawn should also have a minimum height and width. Cause + // the properties might be used in other parts of the code. The position is just set to be + // zero as a default. fd[ct]->setPosition(0, 0, colWidths[i], rowHeight); + fd[ct]->drawable = false; } From 0404a47fb7c7acd70fcc943a34775f2688f3d52b Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 25 Jun 2023 08:02:53 +0200 Subject: [PATCH 266/326] LA Color and Light - Merge file - Screen : improve behavior (#6779) * Change merge secreen in LA color and light * Remove warning in console --- rtengine/iplocallab.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index e58c38faa..6db6b7627 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -18245,9 +18245,9 @@ void ImProcFunctions::Lab_Local( #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), maxR), tmpImageorig->r(y, x)); - tmpImageorig->g(y, x) = intp(lp.opacol, screen(tmpImageorig->g(y, x), tmpImagereserv->g(y, x), maxG), tmpImageorig->g(y, x)); - tmpImageorig->b(y, x) = intp(lp.opacol, screen(tmpImageorig->b(y, x), tmpImagereserv->b(y, x), maxB), tmpImageorig->b(y, x)); + tmpImageorig->r(y, x) = intp(lp.opacol, screen(tmpImageorig->r(y, x), tmpImagereserv->r(y, x), 1.f), tmpImageorig->r(y, x)); + tmpImageorig->g(y, x) = intp(lp.opacol, screen(tmpImageorig->g(y, x), tmpImagereserv->g(y, x), 1.f), tmpImageorig->g(y, x)); + tmpImageorig->b(y, x) = intp(lp.opacol, screen(tmpImageorig->b(y, x), tmpImagereserv->b(y, x), 1.f), tmpImageorig->b(y, x)); } } } else if (lp.mergecolMethod == 12) { //darken only From 81b6dd8be48996f7b6d63b39b765fe84e358b868 Mon Sep 17 00:00:00 2001 From: Christian-Kr Date: Sun, 25 Jun 2023 08:23:33 +0200 Subject: [PATCH 267/326] Refactor code to be more readable. --- rtgui/profilepanel.cc | 80 ++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index 7d2910cef..1acf23649 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -288,6 +288,12 @@ void ProfilePanel::save_clicked (GdkEventButton* event) toSave = entry ? ProfileStore::getInstance()->getProfile(entry) : nullptr; } + // If no entry has been selected or anything unpredictable happened, toSave + // can be nullptr. + if (toSave == nullptr) { + return; + } + // If it's a partial profile, it's more intuitive to first allow the user // to choose which parameters to save before showing the Save As dialog // #5491 @@ -336,52 +342,70 @@ void ProfilePanel::save_clicked (GdkEventButton* event) filter_any->add_pattern("*"); dialog.add_filter(filter_any); - bool done = true; + while (true) { - do { - done = true; + // Run the saving dialog and let the user select a path and filename. + const auto response = dialog.run(); - if (dialog.run() == Gtk::RESPONSE_OK) { + if (response != Gtk::RESPONSE_OK) { + // Just exit the loop, cause the user cancels the dialog. + + break; + } else { + // Go on with saving the the profile. - std::string fname = dialog.get_filename(); + auto fname = dialog.get_filename(); if (("." + getExtension(fname)) != paramFileExtension) { fname += paramFileExtension; } if (!confirmOverwrite(dialog, fname)) { + + // The user doesn't want to override the existing file. So, just restart the loop, + // so the user can select a different path or file name. continue; } lastFilename = Glib::path_get_basename(fname); - if (toSave) { - int retCode; + auto retCode = -1; - if (isPartial) { - // Build partial profile - PartialProfile ppTemp(true); - partialProfileDlg->applyPaste(ppTemp.pparams, ppTemp.pedited, toSave->pparams, nullptr); - // Save partial profile - retCode = ppTemp.pparams->save(fname, "", true, ppTemp.pedited); - // Cleanup - ppTemp.deleteInstance(); - } else { - // Save full profile - retCode = toSave->pparams->save(fname); - } + if (isPartial) { + // Build partial profile + PartialProfile ppTemp(true); + partialProfileDlg->applyPaste(ppTemp.pparams, ppTemp.pedited, toSave->pparams, nullptr); + + // Save partial profile + retCode = ppTemp.pparams->save(fname, "", true, ppTemp.pedited); + + // Cleanup + ppTemp.deleteInstance(); + } else { + // Save full profile + retCode = toSave->pparams->save(fname); + } - if (!retCode) { - const auto ccPrevState = changeconn.block(true); - ProfileStore::getInstance()->parseProfiles(); - changeconn.block(ccPrevState); - } else { - done = false; - writeFailed(dialog, fname); - } + if (retCode == 0) { + // Saving the profile was successfull. + + const auto ccPrevState = changeconn.block(true); + ProfileStore::getInstance()->parseProfiles(); + changeconn.block(ccPrevState); + + // Because saving has been successfull, just leave the loop; + break; + } else { + // Saving the profile was not successfull. + + writeFailed(dialog, fname); + + // In case the saving process was not successfull (missing permissions, ...) + // reopen the dialog and try again. + continue; } } - } while (!done); + } } /* From b950477bc926e812430456f04d0d39b32d2c864a Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 25 Jun 2023 17:42:34 -0700 Subject: [PATCH 268/326] Fix cropped curves widget --- rtgui/toolpanel.cc | 5 +++++ rtgui/toolpanel.h | 1 + 2 files changed, 6 insertions(+) diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index 6db30bb14..46899f1a2 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -47,6 +47,11 @@ ToolParamBlock::ToolParamBlock() { //GTK318 } +Gtk::SizeRequestMode ToolParamBlock::get_request_mode_vfunc () const +{ + return Gtk::SIZE_REQUEST_HEIGHT_FOR_WIDTH; +} + FoldableToolPanel::FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, Glib::ustring UILabel, bool need11, bool useEnabled) : ToolPanel(toolName, need11), parentContainer(nullptr), exp(nullptr), lastEnabled(true) { if (!content) { diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 5ec59c9c2..f22f6f771 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -70,6 +70,7 @@ class ToolParamBlock : { public: ToolParamBlock(); + Gtk::SizeRequestMode get_request_mode_vfunc () const override; }; class ToolPanel : From e507be76abd1216a952117343665d6589b62cb9d Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Jun 2023 18:28:50 -0700 Subject: [PATCH 269/326] Update OM-5 camconst Add white level and fix 80MP raw crop. --- rtengine/camconst.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index cfee0dcd4..e8ce49618 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2188,10 +2188,11 @@ Camera constants: { // Quality X "make_model": ["OM Digital Solutions OM-5"], "dcraw_matrix": [ 11896, -5110, -1076, -3181, 11378, 2048, -519, 1224, 5166 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 15.0 + "ranges": { "white": 3825 }, "raw_crop" : [ { "frame" : [8200, 6132], "crop": [0, 0, 8172, 6132] }, { "frame" : [5240, 3912], "crop": [0, 0, 5240, 3912] }, - { "frame" : [10400, 7792], "crop": [0, 0, 10392, 7792] } + { "frame" : [10400, 7792], "crop": [0, 0, 10390, 7792] } ] }, From fcf22ea33ac1ce99c065677546a2de1a87eb051e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 Jul 2023 18:39:05 -0700 Subject: [PATCH 270/326] Update white level for Canon EOS R5 Drop the white level slightly to account for noise. White level confirmed in https://github.com/Beep6581/RawTherapee/issues/6783. --- rtengine/camconst.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index c4bf9b14a..a7e589416 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1230,7 +1230,7 @@ Camera constants: "raw_crop": [ 160, 120, 6024, 4024 ] }, - { // Quality C + { // Quality A "make_model": "Canon EOS R5", "dcraw_matrix" : [9766, -2953, -1254, -4276, 12116, 2433, -437, 1336, 5131], "raw_crop" : [ @@ -1241,7 +1241,7 @@ Camera constants: { "frame" : [ 8352, 5586 ], "areas": [ 94, 20, 5578, 122 ] }, { "frame" : [ 5248, 3510 ], "areas": [ 94, 20, 3510, 122 ] } ], - "ranges" : { "white" : 16382 } + "ranges" : { "white" : 16300 } // 16382 without LENR, add margin for LENR. Dual-pixel frame 2 is lower for low ISOs. }, { // Quality C From d912dd1e51171a23c31194bbf5982e7d9c717f68 Mon Sep 17 00:00:00 2001 From: Hombre57 Date: Tue, 4 Jul 2023 00:30:25 +0200 Subject: [PATCH 271/326] Ending conversion to std::thread and std::mutex --- rtgui/histogrampanel.cc | 6 ++-- rtgui/threadutils.cc | 61 +++++++++++++++++++++++--------------- rtgui/threadutils.h | 25 +++++++++------- rtgui/thumbimageupdater.cc | 14 ++++----- 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 821f6f0be..b804218f5 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -1197,7 +1197,7 @@ void HistogramArea::update( break; case ScopeType::PARADE: case ScopeType::WAVEFORM: { - MyWriterLock wave_lock(wave_mutex); + MYWRITERLOCK(wave_lock, wave_mutex) waveform_scale = waveformScale; rwave = waveformRed; gwave = waveformGreen; @@ -1330,7 +1330,7 @@ void HistogramArea::updateBackBuffer () cr->unset_dash(); - MyReaderLock wave_lock(wave_mutex); + MYREADERLOCK(wave_lock, wave_mutex) if (valid && (scopeType == ScopeType::HISTOGRAM || scopeType == ScopeType::HISTOGRAM_RAW)) { bool rawMode = scopeType == ScopeType::HISTOGRAM_RAW; @@ -1447,7 +1447,7 @@ void HistogramArea::updateBackBuffer () } else if (scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS) { drawVectorscope(cr, w, h); } - wave_lock.release(); + MYREADERLOCK_RELEASE(wave_lock); // Draw the frame's border style->render_frame(cr, 0, 0, surface->get_width(), surface->get_height()); diff --git a/rtgui/threadutils.cc b/rtgui/threadutils.cc index f747510d3..9bc9cf35d 100644 --- a/rtgui/threadutils.cc +++ b/rtgui/threadutils.cc @@ -17,7 +17,6 @@ * along with RawTherapee. If not, see . */ #include "threadutils.h" -#include #include #include @@ -28,6 +27,8 @@ #if STRICT_MUTEX && !NDEBUG +MyMutex::MyMutex() : locked(false) {} + void MyMutex::checkLock () { if (locked) { @@ -62,13 +63,18 @@ void MyMutex::checkUnlock () #if !TRACE_MYRWMUTEX +MyRWMutex::MyRWMutex() : + writerCount(0), + readerCount(0) +{} + void MyReaderLock::acquire () { if (locked) { return; } - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); if (mutex.writerCount == 0) { // There's no writer operating, we can increment the writer count which will lock writers. @@ -77,7 +83,7 @@ void MyReaderLock::acquire () // The writer count is non null, but a reader can be the owner of the writer lock, // which will be the case if the reader count is not zero too. while (mutex.writerCount != 0) { - mutex.cond.wait(mutex.mutex); + mutex.cond.wait (lock); } // Then, we can increment the writer count. @@ -96,7 +102,7 @@ void MyReaderLock::release () return; } - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // decrement the writer number first... --mutex.readerCount; @@ -106,7 +112,7 @@ void MyReaderLock::release () --mutex.writerCount; // ...and signal the next waiting reader/writer that it's free - mutex.cond.notify_one(); // notify_all ? + mutex.cond.notify_all (); } locked = false; @@ -118,11 +124,11 @@ void MyWriterLock::acquire () return; } - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // The writer count is not zero, so we have to wait for it to be zero again... while (mutex.writerCount != 0) { - mutex.cond.wait (mutex.mutex); + mutex.cond.wait (lock); } // ...then we can increment the writer count. @@ -137,12 +143,12 @@ void MyWriterLock::release () return; } - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // Decrement the writer number first... if (--mutex.writerCount == 0) { - // ...and if the writer count is zero again, we can wake up the next writer or reader. - mutex.cond.notify_one(); // notify_all ? + // ...and if the writer count is zero again, we wake up all of the waiting writer or reader. + mutex.cond.notify_all (); } locked = false; @@ -155,13 +161,20 @@ namespace std::ostream& trace (const char* file, int line) { - const auto currentThread = Glib::Threads::Thread::self (); + const auto currentThread = std::this_thread::get_id(); return std::cout << currentThread << ":" << file << ":" << line << ": "; } } +MyRWMutex::MyRWMutex() : + lastWriterFile(nullptr), + lastWriterLine(0), + writerCount(0), + readerCount(0) +{} + void MyReaderLock::acquire (const char* file, int line) { if (locked) { @@ -171,7 +184,7 @@ void MyReaderLock::acquire (const char* file, int line) trace (file, line) << "Acquiring MyReaderLock..." << std::endl; - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); if (mutex.writerCount == 0) { // There's no writer operating, we can increment the writer count which will lock writers. @@ -185,13 +198,13 @@ void MyReaderLock::acquire (const char* file, int line) << "\tLast writer file: " << mutex.lastWriterFile << std::endl << "\tLast writer line: " << mutex.lastWriterLine << std::endl; - mutex.cond.wait(mutex.mutex); + mutex.cond.wait (lock); } // Then, we can increment the writer count. ++mutex.writerCount; - mutex.ownerThread = Glib::Threads::Thread::self (); + mutex.ownerThread = std::this_thread::get_id (); mutex.lastWriterFile = file; mutex.lastWriterLine = line; } @@ -212,7 +225,7 @@ void MyReaderLock::release (const char* file, int line) trace (file, line) << "Releasing MyReaderLock..." << std::endl; - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // decrement the writer number first... --mutex.readerCount; @@ -222,9 +235,9 @@ void MyReaderLock::release (const char* file, int line) --mutex.writerCount; // ...and signal the next waiting reader/writer that it's free - mutex.cond.notify_one(); // notify_all ? + mutex.cond.notify_all (); - mutex.ownerThread = nullptr; + mutex.ownerThread = std::thread::id(); mutex.lastWriterFile = ""; mutex.lastWriterLine = 0; } @@ -242,7 +255,7 @@ void MyWriterLock::acquire (const char* file, int line) trace (file, line) << "Acquiring MyWriterLock..." << std::endl; - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // The writer count is not zero, so we have to wait for it to be zero again... while (mutex.writerCount != 0) { @@ -251,13 +264,13 @@ void MyWriterLock::acquire (const char* file, int line) << "\tLast writer file: " << mutex.lastWriterFile << std::endl << "\tLast writer line: " << mutex.lastWriterLine << std::endl; - mutex.cond.wait (mutex.mutex); + mutex.cond.wait (lock); } // ...then we can increment the writer count. ++mutex.writerCount; - mutex.ownerThread = Glib::Threads::Thread::self (); + mutex.ownerThread = std::this_thread::get_id (); mutex.lastWriterFile = file; mutex.lastWriterLine = line; @@ -274,14 +287,14 @@ void MyWriterLock::release (const char* file, int line) trace (file, line) << "Releasing MyWriterLock..." << std::endl; - std::lock_guard lock (mutex.mutex); + std::unique_lock lock (mutex.mutex); // Decrement the writer number first... if (--mutex.writerCount == 0) { - // ...and if the writer count is zero again, we can wake up the next writer or reader. - mutex.cond.notify_one(); // notify_all ? + // ...and if the writer count is zero again, we wake up all of the waiting writer or reader. + mutex.cond.notify_all (); - mutex.ownerThread = nullptr; + mutex.ownerThread = std::thread::id(); mutex.lastWriterFile = ""; mutex.lastWriterLine = 0; } diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index cdf093b52..401660b93 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -25,6 +25,7 @@ //#define STRICT_MUTEX 1 #include +#include #include #include "../rtengine/noncopyable.h" @@ -54,8 +55,10 @@ public: void unlock (); #if STRICT_MUTEX && !NDEBUG + MyMutex(); + private: - bool locked = false; + bool locked; void checkLock (); void checkUnlock (); #endif @@ -88,18 +91,20 @@ public: friend class MyReaderLock; friend class MyWriterLock; + MyRWMutex(); + private: - std::mutex mutex; - std::condition_variable_any cond; - - std::size_t writerCount = 0; - std::size_t readerCount = 0; - #if TRACE_MYRWMUTEX - Glib::Threads::Thread* ownerThread = nullptr; - const char* lastWriterFile = ""; - int lastWriterLine = 0; + std::thread::id ownerThread; + const char* lastWriterFile; + int lastWriterLine; #endif + + std::mutex mutex; + std::condition_variable cond; + + std::size_t writerCount; + std::size_t readerCount; }; /** diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index 65958797e..d196fdca5 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -85,7 +85,7 @@ public: Glib::ThreadPool* threadPool_; - // Need to be a std::mutex because used in a std::condition_variable_any object... + // Need to be a std::mutex because used in a std::condition_variable object... // This is the only exceptions along with GThreadMutex (guiutils.cc), MyMutex is used everywhere else std::mutex mutex_; @@ -95,7 +95,7 @@ public: bool inactive_waiting_; - std::condition_variable_any inactive_; + std::condition_variable inactive_; void processNextJob() @@ -169,7 +169,7 @@ public: std::lock_guard lock(mutex_); if (inactive_waiting_) { inactive_waiting_ = false; - inactive_.notify_one(); // notify_all ? + inactive_.notify_all(); } } } @@ -246,9 +246,9 @@ void ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener) while ( impl_->active_ != 0 ) { DEBUG("waiting for running jobs1"); { - std::lock_guard lock(impl_->mutex_); + std::unique_lock lock(impl_->mutex_); impl_->inactive_waiting_ = true; - impl_->inactive_.wait(impl_->mutex_); + impl_->inactive_.wait(lock); } } } @@ -266,9 +266,9 @@ void ThumbImageUpdater::removeAllJobs() while ( impl_->active_ != 0 ) { DEBUG("waiting for running jobs2"); { - std::lock_guard lock(impl_->mutex_); + std::unique_lock lock(impl_->mutex_); impl_->inactive_waiting_ = true; - impl_->inactive_.wait(impl_->mutex_); + impl_->inactive_.wait(lock); } } } From 6bd822352ebeac5d16d237836497ac0571deb431 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 4 Jul 2023 17:40:33 -0700 Subject: [PATCH 272/326] Display actual language names in preferences Add ability to set metadata variables in the language files. Use the LANGUAGE_DISPLAY_NAME metadata variable value in preferences to show the languages. Metadata variables are defined in the first section of a language file, i.e. the comments at the beginning of the file. At most one variable can be defined per line. The definition takes the following format: #
@= where:
is any sequence of non-whitespace characters is any non-empty sequence of whitespace characters is the metadata key name is the metadata value For example, #101 @LANGUAGE_DISPLAY_NAME=English (US) defines a metadata key "LANGUAGE_DISPLAY_NAME" with value "English (US)". Lines that do not match the format are ignored. --- rtdata/languages/Catala | 4 +- rtdata/languages/Chinese (Simplified) | 20 +- rtdata/languages/Czech | 98 +++++----- rtdata/languages/Dansk | 4 +- rtdata/languages/Deutsch | 176 +++++++++--------- rtdata/languages/Espanol (Castellano) | 6 +- rtdata/languages/Espanol (Latin America) | 128 ++++++------- rtdata/languages/Francais | 4 +- rtdata/languages/Italiano | 12 +- rtdata/languages/Japanese | 4 +- rtdata/languages/Magyar | 4 +- rtdata/languages/Nederlands | 36 ++-- rtdata/languages/Polish | 28 +-- rtdata/languages/Portugues | 6 +- rtdata/languages/Portugues (Brasil) | 6 +- rtdata/languages/Russian | 20 +- rtdata/languages/Serbian (Cyrilic Characters) | 4 +- rtdata/languages/Slovenian | 4 +- rtdata/languages/Swedish | 10 +- rtgui/multilangmgr.cc | 94 ++++++++++ rtgui/multilangmgr.h | 21 +++ rtgui/preferences.cc | 39 ++-- 22 files changed, 446 insertions(+), 282 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 4485966ff..cde9262ea 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1,4 +1,6 @@ -#01 2009-10-10 JMG +#001 2009-10-10 JMG +#100 +#101 @LANGUAGE_DISPLAY_NAME=Català ABOUT_TAB_BUILD;Versió ABOUT_TAB_CREDITS;Crèdits diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index e4e89fed2..06e9fadbe 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1,12 +1,14 @@ -#00 Chinese (Simplified) -#01 2008-02-13 Forrest Sun -#02 2008-11-06 Yang Gao (grantyale) -#03 2013-10-20 Jiero -#04 2014-10-24 Jie Luo -#05 2017-09-18 Chongnuo Ji -#06 2020-08-11 十一元人民币 -#07 2021-09-24 十一元人民币 -#08 2022-07-26 十一元人民币 +#000 Chinese (Simplified) +#001 2008-02-13 Forrest Sun +#002 2008-11-06 Yang Gao (grantyale) +#003 2013-10-20 Jiero +#004 2014-10-24 Jie Luo +#005 2017-09-18 Chongnuo Ji +#006 2020-08-11 十一元人民币 +#007 2021-09-24 十一元人民币 +#008 2022-07-26 十一元人民币 +#100 +#101 @LANGUAGE_DISPLAY_NAME=简体中文 ABOUT_TAB_BUILD;版本 ABOUT_TAB_CREDITS;致谢名单 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 61e6af4bf..680e0a1bb 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -1,51 +1,53 @@ -#00 Czech -#01 2008-01-20 translated by absolution -#02 2008-02-21 updated by mkyral (typos and some missing strings) -#03 2008-04-24 updated by mkyral (for version 2.4m1) -#04 2008-10-28 updated by mkyral (for version 2.4 beta1) -#05 2010-11-25 updated by mkyral (for version 3.0) -#06 2011-03-06 updated by mkyral (default branch) -#07 2011-03-20 updated by mkyral (default branch) -#08 2011-05-01 updated by mkyral -#09 2011-05-18 updated by mkyral -#10 2011-06-04 updated by mkyral -#11 2011-06-12 updated by mkyral -#12 2011-06-16 updated by mkyral -#13 2011-07-03 updated by mkyral -#14 2011-07-08 updated by mkyral -#15 2011-09-04 updated by mkyral -#16 2011-09-06 updated by mkyral -#17 2011-11-12 updated by mkyral -#18 2011-12-29 updated by mkyral -#19 2012-02-22 updated by mkyral -#20 2012-04-28 updated by mkyral -#21 2012-10-10 updated by mkyral -#22 2012-11-27 updated by mkyral -#23 2013-03-12 updated by mkyral -#24 2013-04-12 updated by mkyral -#25 2013-09-12 updated by mkyral -#26 2013-09-17 updated by mkyral -#27 2013-12-09 updated by mkyral -#28 2014-01-07 updated by mkyral -#29 2014-04-08 updated by mkyral -#30 2014-04-30 updated by mkyral -#31 2014-05-12 updated by mkyral -#32 2014-10-24 updated by mkyral -#33 2015-02-22 updated by mkyral -#34 2015-07-09 updated by mkyral -#35 2015-11-24 updated by mkyral -#36 2016-10-18 updated by mkyral -#37 2017-01-10 updated by mkyral -#38 2017-04-26 updated by mkyral -#39 2017-07-21 updated by mkyral -#40 2017-12-13 updated by mkyral -#41 2018-03-03 updated by mkyral -#42 2018-10-24 updated by mkyral -#43 2018-12-04 updated by mkyral -#44 2018-12-13 updated by mkyral -#45 2020-04-20 updated by mkyral -#46 2020-04-21 updated by mkyral -#47 2020-06-02 updated by mkyral +#000 Czech +#001 2008-01-20 translated by absolution +#002 2008-02-21 updated by mkyral (typos and some missing strings) +#003 2008-04-24 updated by mkyral (for version 2.4m1) +#004 2008-10-28 updated by mkyral (for version 2.4 beta1) +#005 2010-11-25 updated by mkyral (for version 3.0) +#006 2011-03-06 updated by mkyral (default branch) +#007 2011-03-20 updated by mkyral (default branch) +#008 2011-05-01 updated by mkyral +#009 2011-05-18 updated by mkyral +#010 2011-06-04 updated by mkyral +#011 2011-06-12 updated by mkyral +#012 2011-06-16 updated by mkyral +#013 2011-07-03 updated by mkyral +#014 2011-07-08 updated by mkyral +#015 2011-09-04 updated by mkyral +#016 2011-09-06 updated by mkyral +#017 2011-11-12 updated by mkyral +#018 2011-12-29 updated by mkyral +#019 2012-02-22 updated by mkyral +#020 2012-04-28 updated by mkyral +#021 2012-10-10 updated by mkyral +#022 2012-11-27 updated by mkyral +#023 2013-03-12 updated by mkyral +#024 2013-04-12 updated by mkyral +#025 2013-09-12 updated by mkyral +#026 2013-09-17 updated by mkyral +#027 2013-12-09 updated by mkyral +#028 2014-01-07 updated by mkyral +#029 2014-04-08 updated by mkyral +#030 2014-04-30 updated by mkyral +#031 2014-05-12 updated by mkyral +#032 2014-10-24 updated by mkyral +#033 2015-02-22 updated by mkyral +#034 2015-07-09 updated by mkyral +#035 2015-11-24 updated by mkyral +#036 2016-10-18 updated by mkyral +#037 2017-01-10 updated by mkyral +#038 2017-04-26 updated by mkyral +#039 2017-07-21 updated by mkyral +#040 2017-12-13 updated by mkyral +#041 2018-03-03 updated by mkyral +#042 2018-10-24 updated by mkyral +#043 2018-12-04 updated by mkyral +#044 2018-12-13 updated by mkyral +#045 2020-04-20 updated by mkyral +#046 2020-04-21 updated by mkyral +#047 2020-06-02 updated by mkyral +#100 +#101 @LANGUAGE_DISPLAY_NAME=Český ABOUT_TAB_BUILD;Verze ABOUT_TAB_CREDITS;Zásluhy diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 2cfbf4e27..d3a67766e 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -1,4 +1,6 @@ -#01 2022-04-21 mogensjaeger (github), initial danish translation +#001 2022-04-21 mogensjaeger (github), initial danish translation +#100 +#101 @LANGUAGE_DISPLAY_NAME=Dansk ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Credits diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 3a2c2999c..ceb738ece 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -1,90 +1,92 @@ -#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 +#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 +#100 +#101 @LANGUAGE_DISPLAY_NAME=Deutsch ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index ede64894f..54e3d1157 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -1,5 +1,7 @@ -#01 Español - Castellano -#02 2022-10-08 Francisco Lorés y Javier Bartol, para la versión 5.9 +#001 Español - Castellano +#002 2022-10-08 Francisco Lorés y Javier Bartol, para la versión 5.9 +#100 +#101 @LANGUAGE_DISPLAY_NAME=Español (Castellano) ABOUT_TAB_BUILD;Versión ABOUT_TAB_CREDITS;Reconocimientos diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index 56a73d30f..58556af85 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -1,66 +1,68 @@ -#01 Latin America - Spanish -#02 Conventions used to keep the same writing style along new texts and versions -#03 -#04 Abreviaturas (Abbreviations) -#05 ----------------------------- -#06 AC: Aberración cromática (fringe) -#07 B&N: Blanco y Negro (Black & White) -#08 CV: Corrección de Viñeteado (Vignette Filter: in Transform tab) -#09 FG: Filtro Graduado (Gradient Filter) -#10 FV: Filtrar Viñeteado (Vignette Filter: in Exposure tab) -#11 MC: Mezclador de canales (Channel Mixer) -#12 RGB: Modelo de color Rojo Verde Azul (Red Green Blue) -#13 WB: Balance de blancos (White Balance) -#14 -#15 Convención de traducción de términos importantes, -#16 sin equivalente estándar o poco conocidos en español: -#17 --------------------------------------------- -#18 Artifacts: Elementos extraños -#19 Brightness: Brillo -#20 Checkbox: Casilla (seleccionada/desmarcada) -#21 Chroma: Crominancia (**, definida en es.wikipedia) -#22 Chromatic: Cromática (*) -#23 Chromaticity: Cromaticidad (**) -#24 Colorfulness: Colorido -#25 Cyan: Cian (*) -#26 Dark Frame: Toma Negra -#27 Dim: Luz tenue -#28 Feather: Difuminado -#29 Illuminant: Iluminante -#30 Lightness: Claridad -#31 Luminance: Luminancia (*) -#32 Luminosity: Luminosidad -#33 Mapping: Mapeo (*) -#34 Sharpening: Enfoque -#35 Slider: Control deslizante -#36 Tone Curve: Curva tonal -#37 Vibrance: Vibranza -#38 -#39 (*) Término incluido en diccionario RAE -#40 (**) Término no incluido en diccionario RAE -#41 -#42 Términos conservados en Inglés por no tener traducción breve -#43 al español en el sentido usado por RT/fotografía digital -#44 ----------------------------------------------------- -#45 ICM (Image Color Management) -#46 Gamut -#47 Gamma -#48 Raw -#49 -#50 2008-01-15 keenonkites, first translation -#51 2008-03-03 Ioritz Ibarguren, corrections -#52 2008-04-05 keenonkites, completed for 2.4m1 -#53 2008-04-09 Ramon, partly corrected (part of 2.3) -#54 2008-04-29 Ramon, small correction -#55 2008-06-09 Ramon, Adaptions regarding 2.4m1 and others -#56 2008-09-20 keenonkites, first version for 2.4m2 -#57 2008-12-19 keenonkites, first version for 2.4beta4 -#58 2010-12-07 rickydh, some translations of untranslated keys for 3.0 alpha1 -#59 2011-12-25 plores, translation improvement, translation of untranslated strings -#60 2013-01-03 OdeLama, translation for v4.0.12 of untranslated/changed strings -#61 2014-01-14 mapelo, bug correction and small enhancements. -#62 2014-10-10 fotger -#63 2018-12-09 Faber777 +#001 Latin America - Spanish +#002 Conventions used to keep the same writing style along new texts and versions +#003 +#004 Abreviaturas (Abbreviations) +#005 ----------------------------- +#006 AC: Aberración cromática (fringe) +#007 B&N: Blanco y Negro (Black & White) +#008 CV: Corrección de Viñeteado (Vignette Filter: in Transform tab) +#009 FG: Filtro Graduado (Gradient Filter) +#010 FV: Filtrar Viñeteado (Vignette Filter: in Exposure tab) +#011 MC: Mezclador de canales (Channel Mixer) +#012 RGB: Modelo de color Rojo Verde Azul (Red Green Blue) +#013 WB: Balance de blancos (White Balance) +#014 +#015 Convención de traducción de términos importantes, +#016 sin equivalente estándar o poco conocidos en español: +#017 --------------------------------------------- +#018 Artifacts: Elementos extraños +#019 Brightness: Brillo +#020 Checkbox: Casilla (seleccionada/desmarcada) +#021 Chroma: Crominancia (**, definida en es.wikipedia) +#022 Chromatic: Cromática (*) +#023 Chromaticity: Cromaticidad (**) +#024 Colorfulness: Colorido +#025 Cyan: Cian (*) +#026 Dark Frame: Toma Negra +#027 Dim: Luz tenue +#028 Feather: Difuminado +#029 Illuminant: Iluminante +#030 Lightness: Claridad +#031 Luminance: Luminancia (*) +#032 Luminosity: Luminosidad +#033 Mapping: Mapeo (*) +#034 Sharpening: Enfoque +#035 Slider: Control deslizante +#036 Tone Curve: Curva tonal +#037 Vibrance: Vibranza +#038 +#039 (*) Término incluido en diccionario RAE +#040 (**) Término no incluido en diccionario RAE +#041 +#042 Términos conservados en Inglés por no tener traducción breve +#043 al español en el sentido usado por RT/fotografía digital +#044 ----------------------------------------------------- +#045 ICM (Image Color Management) +#046 Gamut +#047 Gamma +#048 Raw +#049 +#050 2008-01-15 keenonkites, first translation +#051 2008-03-03 Ioritz Ibarguren, corrections +#052 2008-04-05 keenonkites, completed for 2.4m1 +#053 2008-04-09 Ramon, partly corrected (part of 2.3) +#054 2008-04-29 Ramon, small correction +#055 2008-06-09 Ramon, Adaptions regarding 2.4m1 and others +#056 2008-09-20 keenonkites, first version for 2.4m2 +#057 2008-12-19 keenonkites, first version for 2.4beta4 +#058 2010-12-07 rickydh, some translations of untranslated keys for 3.0 alpha1 +#059 2011-12-25 plores, translation improvement, translation of untranslated strings +#060 2013-01-03 OdeLama, translation for v4.0.12 of untranslated/changed strings +#061 2014-01-14 mapelo, bug correction and small enhancements. +#062 2014-10-10 fotger +#063 2018-12-09 Faber777 +#100 +#101 @LANGUAGE_DISPLAY_NAME=Español (Latinoamericano) ABOUT_TAB_BUILD;Versión ABOUT_TAB_CREDITS;Créditos diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index b7b2c7ec7..25fb12904 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -1,4 +1,6 @@ -#01 2008-03-01 Initial translation by Hombre +#001 2008-03-01 Initial translation by Hombre +#100 +#101 @LANGUAGE_DISPLAY_NAME=Français ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Crédits diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index e4447f7f6..9c4e607bc 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1,8 +1,10 @@ -#01 2008-01-19 v2.3 breek -#02 2008-11-01 v2.4 pantaraf, chelidon, roberto -#03 2011-08-26 v3.0 joker, chelidon, ffsup2 -#04 2011-08-31 v4.0 chelidon, ffsup2 -#05 2014-04-21 crx +#001 2008-01-19 v2.3 breek +#002 2008-11-01 v2.4 pantaraf, chelidon, roberto +#003 2011-08-26 v3.0 joker, chelidon, ffsup2 +#004 2011-08-31 v4.0 chelidon, ffsup2 +#005 2014-04-21 crx +#100 +#101 @LANGUAGE_DISPLAY_NAME=Italiano ABOUT_TAB_BUILD;Versione ABOUT_TAB_CREDITS;Riconoscimenti diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 0f35036db..fa403c2d9 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -1,4 +1,6 @@ -#Last update 10-12-2022 +#001 Last update 10-12-2022 +#100 +#101 @LANGUAGE_DISPLAY_NAME=日本語 ABOUT_TAB_BUILD;バージョン ABOUT_TAB_CREDITS;クレジット diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 6283dbe4b..b79be1e4e 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1,4 +1,6 @@ -#01 2010-11-20 RT 3.0 alpha 1 rev. 597:fb291bf74c by Dr. Gyurkó M. 'dualon' Dávid +#001 2010-11-20 RT 3.0 alpha 1 rev. 597:fb291bf74c by Dr. Gyurkó M. 'dualon' Dávid +#100 +#101 @LANGUAGE_DISPLAY_NAME=Magyar ABOUT_TAB_BUILD;Verzió ABOUT_TAB_CREDITS;Szerzők diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 63eaeccc6..3e6dc5621 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -1,20 +1,22 @@ -#01 2007-12-26 Rens Duijsens en Brent Huisman -#02 2008-03-14 updated by reggybe -#03 2009-02-01 updated to RT2.4-RC by paul.matthijsse -#04 2010-05-02 updated to rt3a1 by paul.matthijsse -#05 2011-03-03 updated to rt3a2 by paul.matthijsse -#06 2011-10-10 updated to rt4.0 by wim ter meer -#07 2011-11-28 updated by pm -#08 2012-05-17 updated to rt4.0.8 by wim ter meer -#09 2013-03-27 updated to rt4.0.10 by wim ter meer -#10 2013-11-27 updated to rt4.0.11 by wim ter meer -#11 2014-03-24 updated to rt4.1 by wim ter meer -#12 2014-10-19 updated to rt4.1.92 by wim ter meer -#13 2015-03-03 updated to rt4.2.102 by wim ter meer -#14 2015-11-23 update by wim ter meer -#15 2016-07-21 update by wim ter meer -#16 2017-04-21 update by wim ter meer -#17 2020-06-05 update by dheijl +#001 2007-12-26 Rens Duijsens en Brent Huisman +#002 2008-03-14 updated by reggybe +#003 2009-02-01 updated to RT2.4-RC by paul.matthijsse +#004 2010-05-02 updated to rt3a1 by paul.matthijsse +#005 2011-03-03 updated to rt3a2 by paul.matthijsse +#006 2011-10-10 updated to rt4.0 by wim ter meer +#007 2011-11-28 updated by pm +#008 2012-05-17 updated to rt4.0.8 by wim ter meer +#009 2013-03-27 updated to rt4.0.10 by wim ter meer +#010 2013-11-27 updated to rt4.0.11 by wim ter meer +#011 2014-03-24 updated to rt4.1 by wim ter meer +#012 2014-10-19 updated to rt4.1.92 by wim ter meer +#013 2015-03-03 updated to rt4.2.102 by wim ter meer +#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 +#100 +#101 @LANGUAGE_DISPLAY_NAME=Nederlands ABOUT_TAB_BUILD;Versie ABOUT_TAB_CREDITS;Credits diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 06ed63aba..63d483738 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1,16 +1,18 @@ -#01 2007-12-24 Mateusz Ludwin -#02 2010-01-08 Bartosz "Simek" Kaszubowski -#03 2011-09-06 Dariusz 'Salvadhor' Duma -#04 2011-11-30 DrSlony -#05 2012-01-14 DrSlony -#06 2012-01-30 DrSlony -#07 2012-04-02 DrSlony -#08 2013-05-21 DrSlony -#09 2014-10-16 DrSlony -#10 2020-02-02 Bartłomiej Wiśniowski -#11 2020-02-02 Bartłomiej Wiśniowski -#12 2020-02-15 Bartłomiej Wiśniowski -#13 2020-02-17 Bartłomiej Wiśniowski +#001 2007-12-24 Mateusz Ludwin +#002 2010-01-08 Bartosz "Simek" Kaszubowski +#003 2011-09-06 Dariusz 'Salvadhor' Duma +#004 2011-11-30 DrSlony +#005 2012-01-14 DrSlony +#006 2012-01-30 DrSlony +#007 2012-04-02 DrSlony +#008 2013-05-21 DrSlony +#009 2014-10-16 DrSlony +#010 2020-02-02 Bartłomiej Wiśniowski +#011 2020-02-02 Bartłomiej Wiśniowski +#012 2020-02-15 Bartłomiej Wiśniowski +#013 2020-02-17 Bartłomiej Wiśniowski +#100 +#101 @LANGUAGE_DISPLAY_NAME=Polski ABOUT_TAB_BUILD;Wersja ABOUT_TAB_CREDITS;Zasługi diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 09d3aa790..38c0bc8f6 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -1,5 +1,7 @@ -#01 2018-07-25 Digitalpix58 -#02 2019-03-11 Xendez +#001 2018-07-25 Digitalpix58 +#002 2019-03-11 Xendez +#100 +#101 @LANGUAGE_DISPLAY_NAME=Português ABOUT_TAB_BUILD;Versão ABOUT_TAB_CREDITS;Créditos diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index cf386f5ff..afbd0b6b1 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -1,5 +1,7 @@ -#01 2018-07-25 Digitalpix58 -#02 2019-03-12 Xendez +#001 2018-07-25 Digitalpix58 +#002 2019-03-12 Xendez +#100 +#101 @LANGUAGE_DISPLAY_NAME=Português brasileiro ABOUT_TAB_BUILD;Versão ABOUT_TAB_CREDITS;Créditos diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 6b0aa6ca0..bd83d2f14 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1,12 +1,14 @@ -#01 2007-12-23 ArtDen -#02 2008-07-20 Denis Artemov -#03 2009-02-16 Kvark -#04 2010-02-26 Sergey Smirnov AKA smiserg -#05 2010-11-01 Ilia Popov -#06 2012-07-17 Roman Milanskij -#07 2014-02-12 Kostia (Kildor) Romanov -#08 2018-02-10 Kostia (Kildor) Romanov -#09 2018-12-13 Kostia (Kildor) Romanov +#001 2007-12-23 ArtDen +#002 2008-07-20 Denis Artemov +#003 2009-02-16 Kvark +#004 2010-02-26 Sergey Smirnov AKA smiserg +#005 2010-11-01 Ilia Popov +#006 2012-07-17 Roman Milanskij +#007 2014-02-12 Kostia (Kildor) Romanov +#008 2018-02-10 Kostia (Kildor) Romanov +#009 2018-12-13 Kostia (Kildor) Romanov +#100 +#101 @LANGUAGE_DISPLAY_NAME=Русский ABOUT_TAB_BUILD;Версия ABOUT_TAB_CREDITS;Авторы diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 2c48f771b..be6dfb500 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1,4 +1,6 @@ -#01 2010-11-16 gpopac +#001 2010-11-16 gpopac +#100 +#101 @LANGUAGE_DISPLAY_NAME=српски ABOUT_TAB_BUILD;Издање ABOUT_TAB_CREDITS;Заслуге diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index f3d71c543..1954b1c05 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -1,4 +1,6 @@ -#01 2019-10-05 Matjaž Jeran +#001 2019-10-05 Matjaž Jeran +#100 +#101 @LANGUAGE_DISPLAY_NAME=Slovenščina ABOUT_TAB_BUILD;Verzija ABOUT_TAB_CREDITS;Zasluge diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index de612ad73..16fb9f3f1 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1,7 +1,9 @@ -#01 2008-01-22 Emil Ericsson -#02 2010-2013 Updated by Johan Thor -#03 2015-08-09 Johan Thor -#04 2016-12-30 Johan Thor +#001 2008-01-22 Emil Ericsson +#002 2010-2013 Updated by Johan Thor +#003 2015-08-09 Johan Thor +#004 2016-12-30 Johan Thor +#100 +#101 @LANGUAGE_DISPLAY_NAME=Svenska ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Erkännande diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 13f2569c5..2e093e6eb 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -20,6 +20,8 @@ #include #include +#include +#include #ifdef WIN32 #include #include @@ -28,6 +30,8 @@ #include #endif +#include "../rtengine/settings.h" + namespace { @@ -162,6 +166,25 @@ void setGtkLanguage(const Glib::ustring &language) } +TranslationMetadata::TranslationMetadata(std::map &&metadata) : + metadata(std::move(metadata)) +{ +} + +std::string TranslationMetadata::get(const std::string &key, const std::string &default_value) const +{ + const auto found_entry = metadata.find(key); + if (found_entry == metadata.end()) { + return default_value; + } + return found_entry->second; +} + +std::string TranslationMetadata::getLanguageName(const std::string &default_name) const +{ + return get("LANGUAGE_DISPLAY_NAME", default_name); +} + MultiLangMgr langMgr; MultiLangMgr::MultiLangMgr () @@ -219,6 +242,77 @@ Glib::ustring MultiLangMgr::getStr (const std::string& key) const return key; } +const TranslationMetadata *MultiLangMgr::getMetadata(const Glib::ustring &fname) const +{ + static const char comment_symbol = '#'; + static const char *space_chars = " \t"; + static const char var_symbol = '@'; + static const char key_value_separator = '='; + + // Look for the metadata in the cache. + const auto &found_metadata = lang_files_metadata.find(fname); + if (found_metadata != lang_files_metadata.end()) { + return &found_metadata->second; + } + + std::ifstream file(fname.c_str()); + if (!file.is_open()) { + if (rtengine::settings->verbose) { + std::cerr << "Unable to open language file " << fname << " to get metadata." << std::endl; + } + return nullptr; + } + + if (rtengine::settings->verbose) { + std::cout << "Reading metadata from language file " << fname << std::endl; + } + std::map raw_metadata; + const auto read_key_value = [&raw_metadata](const std::string &meta_line) { + // One metadata key-value pair per line. The format is as follows: + // #001 @KEY=VALUE + // The line must begin with the comment symbol (#). After the first + // sequence of whitespace characters, the metadata variable symbol (@) + // must appear. It is followed immediately with the key name. The end of + // the key name is marked with the equal sign (=). All remaining + // characters until the end of the line make up the metadata value. + if (meta_line.empty() || meta_line.front() != comment_symbol) { + return; + } + const auto first_space = meta_line.find_first_of(space_chars, 1); + if (first_space == std::string::npos) { + return; + } + const auto definition_start = meta_line.find_first_not_of(space_chars, first_space + 1); + if (definition_start == std::string::npos || meta_line[definition_start] != var_symbol) { + return; + } + const auto separator_pos = meta_line.find(key_value_separator, definition_start + 1); + if (separator_pos == std::string::npos) { + return; + } + std::string key = meta_line.substr(definition_start + 1, separator_pos - definition_start - 1); + std::string value = meta_line.substr(separator_pos + 1); + if (rtengine::settings->verbose) { + std::cout << "Found metadata key " << key << " with value " << value << std::endl; + } + raw_metadata.emplace(std::move(key), std::move(value)); + }; + + // Read lines in order. Metadata only appear in the first section of each + // file. + for ( + std::string line; + std::getline(file, line) && (line.empty() || + line.front() == comment_symbol || + line.find_first_not_of(space_chars) == std::string::npos);) { + read_key_value(line); + } + + // Add metadata to cache and return. + lang_files_metadata[fname] = TranslationMetadata(std::move(raw_metadata)); + return &lang_files_metadata[fname]; +} + bool MultiLangMgr::isOSLanguageDetectSupported () { #if defined (WIN32) || defined (__linux__) || defined (__APPLE__) diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index 902161eb2..27ece9fb8 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -24,6 +24,25 @@ #include +class TranslationMetadata +{ +public: + TranslationMetadata() = default; + ~TranslationMetadata() = default; + TranslationMetadata(const TranslationMetadata &other) = delete; + TranslationMetadata(TranslationMetadata &&other) = delete; + explicit TranslationMetadata(std::map &&metadata); + + TranslationMetadata &operator =(const TranslationMetadata &other) = delete; + TranslationMetadata &operator =(TranslationMetadata &&other) noexcept = default; + + std::string get(const std::string &key, const std::string &default_value) const; + std::string getLanguageName(const std::string &default_name) const; + +private: + std::map metadata; +}; + class MultiLangMgr { public: @@ -31,11 +50,13 @@ public: void load(const Glib::ustring &language, const std::vector &fnames); Glib::ustring getStr(const std::string& key) const; + const TranslationMetadata *getMetadata(const Glib::ustring &fname) const; static bool isOSLanguageDetectSupported(); static Glib::ustring getOSUserLanguage(); private: std::map translations; + mutable std::map lang_files_metadata; }; extern MultiLangMgr langMgr; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c9737704e..2610765f4 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -16,21 +16,27 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + +#include +#include #include -#include "externaleditorpreferences.h" -#include "preferences.h" -#include "multilangmgr.h" -#include "splash.h" -#include "cachemanager.h" + #include "addsetids.h" +#include "cachemanager.h" +#include "externaleditorpreferences.h" +#include "multilangmgr.h" +#include "preferences.h" +#include "rtimage.h" +#include "rtwindow.h" +#include "splash.h" +#include "toollocationpref.h" + #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" #include "../rtengine/iccstore.h" #include "../rtengine/procparams.h" -#include -#include "rtimage.h" -#include "rtwindow.h" -#include "toollocationpref.h" + #ifdef _OPENMP #include #endif @@ -1095,9 +1101,14 @@ Gtk::Widget* Preferences::getGeneralPanel() std::vector langs; parseDir(argv0 + "/languages", langs, ""); - for (size_t i = 0; i < langs.size(); i++) { - if ("default" != langs[i] && "README" != langs[i] && "LICENSE" != langs[i]) { - languages->append(langs[i]); + for (const auto &lang : langs) { + if ("default" != lang && "README" != lang && "LICENSE" != lang) { + auto lang_metadata = langMgr.getMetadata(Glib::build_filename(argv0 + "/languages", lang)); + const auto &display_name = + lang_metadata != nullptr + ? Glib::ustring(lang_metadata->getLanguageName(lang)) + : lang; + languages->append(lang, display_name); } } @@ -1721,7 +1732,7 @@ void Preferences::storePreferences() moptions.menuGroupExtProg = ckbmenuGroupExtProg->get_active(); moptions.highlightThreshold = (int)hlThresh->get_value(); moptions.shadowThreshold = (int)shThresh->get_value(); - moptions.language = languages->get_active_text(); + moptions.language = languages->get_active_id(); moptions.languageAutoDetect = ckbLangAutoDetect->get_active(); moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName; @@ -1997,7 +2008,7 @@ void Preferences::fillPreferences() } cprevdemo->set_active (moptions.prevdemo); - languages->set_active_text(moptions.language); + languages->set_active_id(moptions.language); ckbLangAutoDetect->set_active(moptions.languageAutoDetect); int themeNbr = getThemeRowNumber(moptions.theme); themeCBT->set_active (themeNbr == -1 ? 0 : themeNbr); From b0ebab8e08601573c993a58703731ef1d56036ff Mon Sep 17 00:00:00 2001 From: luzpaz Date: Wed, 5 Jul 2023 13:51:11 +0000 Subject: [PATCH 273/326] Fix various typos Found via `codespell -q 3 -S ./rtdata/languages -L activ,alph,ba,bloc,bord,chang,childs,currentry,dof,dum,fo,hist,inout,invers,lonly,makro,ois,pres,preserv,portugues,rady,reall,redy,struc,tbe,thre,trough,vart,vekto` --- rtdata/themes/TooWaBlue-GTK3-20_.css | 2 +- rtdata/themes/size - Legacy.css | 2 +- rtdata/themes/size.css | 2 +- rtengine/cJSON.c | 2 +- rtengine/calc_distort.cc | 2 +- rtengine/color.cc | 2 +- rtengine/iimage.h | 2 +- rtengine/improccoordinator.cc | 4 ++-- rtengine/ipwavelet.cc | 4 ++-- rtengine/rawimagesource.cc | 10 +++++----- rtgui/options.h | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index ba25e70b7..4d7504dc5 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -946,7 +946,7 @@ dialog notebook stack { } -/* Adds a line on top of the notebook as a separtor for the titlebar (only on CSD) */ +/* Adds a line on top of the notebook as a separator for the titlebar (only on CSD) */ dialog.csd #PrefNotebook > header, dialog.csd #AboutNotebook > header, window.csd:not(.fullscreen) #MainNotebook > header.top { diff --git a/rtdata/themes/size - Legacy.css b/rtdata/themes/size - Legacy.css index 089a909ee..290b95d8c 100644 --- a/rtdata/themes/size - Legacy.css +++ b/rtdata/themes/size - Legacy.css @@ -102,7 +102,7 @@ notebook > header.left > tabs > arrow { } -/* Adds a line on top of the notebook as a separtor for the titlebar (only on CSD) */ +/* Adds a line on top of the notebook as a separator for the titlebar (only on CSD) */ dialog.csd #PrefNotebook > header, dialog.csd #AboutNotebook > header, window.csd:not(.fullscreen) #MainNotebook > header.top { diff --git a/rtdata/themes/size.css b/rtdata/themes/size.css index 675ed51c2..5f5e64120 100644 --- a/rtdata/themes/size.css +++ b/rtdata/themes/size.css @@ -102,7 +102,7 @@ notebook > header.left > tabs > arrow { } -/* Adds a line on top of the notebook as a separtor for the titlebar (only on CSD) */ +/* Adds a line on top of the notebook as a separator for the titlebar (only on CSD) */ dialog.csd #PrefNotebook > header, dialog.csd #AboutNotebook > header, window.csd:not(.fullscreen) #MainNotebook > header.top { diff --git a/rtengine/cJSON.c b/rtengine/cJSON.c index 130c8e2a5..5af587eeb 100644 --- a/rtengine/cJSON.c +++ b/rtengine/cJSON.c @@ -126,7 +126,7 @@ typedef struct internal_hooks } internal_hooks; #if defined(_MSC_VER) -/* work around MSVC error C2322: '...' address of dillimport '...' is not static */ +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ static void *internal_malloc(size_t size) { return malloc(size); diff --git a/rtengine/calc_distort.cc b/rtengine/calc_distort.cc index 3a7a4a1c4..8f241d0c5 100644 --- a/rtengine/calc_distort.cc +++ b/rtengine/calc_distort.cc @@ -84,7 +84,7 @@ int calcDistortion(unsigned char* img1, unsigned char* img2, int ncols, int nrow r0[n] = sqrt((x0 - wc) * (x0 - wc) + (y0 - hc) * (y0 - hc)) / radius; - // dots too close to the center tends to have big diviation and create noise, extract them + // dots too close to the center tends to have big deviation and create noise, extract them if (r0[n] < CENTER_R) { continue; } diff --git a/rtengine/color.cc b/rtengine/color.cc index 085fd41ce..4e139a868 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -2895,7 +2895,7 @@ void Color::SkinSat (float lum, float hue, float chrom, float &satreduc) * * data (Munsell ==> Lab) obtained with WallKillcolor and http://www.cis.rit.edu/research/mcsl2/online/munsell.php * each LUT give Hue in function of C, for each color Munsell and Luminance - * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation betwwen values + * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation between values * no value for C<5 (gray) * low memory footprint -- maximum: 195 LUTf * 140 values * errors due to small number of samples in LUT and linearization are very low (1 to 2%) diff --git a/rtengine/iimage.h b/rtengine/iimage.h index cdb7dd6eb..68f739f1a 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -1858,7 +1858,7 @@ class IImage : virtual public ImageDimensions public: virtual ~IImage() {} - /** @brief Returns a mutex that can is useful in many situations. No image operations shuold be performed without locking this mutex. + /** @brief Returns a mutex that can is useful in many situations. No image operations should be performed without locking this mutex. * @return The mutex */ virtual MyMutex& getMutex () = 0; virtual cmsHPROFILE getProfile () const = 0; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 3a3529131..6e3ebc48c 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1889,7 +1889,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->colorappearance.enabled) { // L histo and Chroma histo for ciecam - // histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C + // histogram will be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C int x1, y1, x2, y2; params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); lhist16CAM.clear(); @@ -1936,7 +1936,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) adap = pow(2.0, E_V - 3.0); // cd / m2 // end calculation adaptation scene luminosity } - if(params->colorappearance.catmethod == "symg") {//force abolute luminance scenescene to 400 in symmetric + if(params->colorappearance.catmethod == "symg") {//force absolute luminance scene to 400 in symmetric adap = 400.; } float d, dj, yb; diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 18ee72b80..e5e90a77f 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -2270,7 +2270,7 @@ void ImProcFunctions::Aver(const float* RESTRICT DataList, int datalen, float &a int countP = 0, countN = 0; double averaP = 0.0, averaN = 0.0; // use double precision for large summations - constexpr float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 very low value + constexpr float thres = 32.7f;//different from zero to take into account only data large enough 32.7 = 0.1 in range 0..100 very low value max = 0.f; min = RT_INFINITY_F; #ifdef _OPENMP @@ -2322,7 +2322,7 @@ void ImProcFunctions::Sigma(const float* RESTRICT DataList, int datalen, float a { int countP = 0, countN = 0; double variP = 0.0, variN = 0.0; // use double precision for large summations - float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 + float thres = 32.7f;//different from zero to take into account only data large enough 32.7 = 0.1 in range 0..100 #ifdef _OPENMP #pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(numThreads) if (numThreads>1) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 06aa701e8..a1ace9ffa 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -847,7 +847,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; bool doHr = (hrp.hrenabled && !iscolor); if (hrp.hrenabled && iscolor) { - if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited tne number to 1 + if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited the number to 1 rgbSourceModified = false; } if (!rgbSourceModified) { @@ -5526,7 +5526,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double float gmm[N_t]; float bmm[N_t]; - int siza = 237; //192 untill 01/2023 size of histogram + int siza = 237; //192 until 01/2023 size of histogram if(wbpar.itcwb_sampling == true) { siza = 192;//old sampling 5.9 and before... } @@ -5671,11 +5671,11 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double purp = false; } if(wbpar.itcwb_sampling == false) { - //printf("Use high smapling\n"); + //printf("Use high sampling\n"); histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB //return histogram x and y for each temp and in a range of 235 colors (siza) } else { - //printf("Use low smapling - 5.9\n"); + //printf("Use low sampling - 5.9\n"); histoxyY_low(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy);//low scaling } } @@ -5818,7 +5818,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double // int maxnb = rtengine::LIM(settings->itcwb_sizereference, 1, 5); // int maxnb = rtengine::LIM(wbpar.itcwb_size, 1, 5); int maxnb = 3; - //wbpar.itcwb_size to verify if this setting is usefull...diificulties with High gamut and limited patch spectral colors. + //wbpar.itcwb_size to verify if this setting is useful...diificulties with High gamut and limited patch spectral colors. if (wbpar.itcwb_thres > 55) {//normally never used maxnb = 201 / wbpar.itcwb_thres; diff --git a/rtgui/options.h b/rtgui/options.h index 78059357e..db44a5876 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -327,7 +327,7 @@ public: bool internalThumbIfUntouched; bool overwriteOutputFile; int complexity; - bool inspectorWindow; // open inspector in spearate window + bool inspectorWindow; // open inspector in separate window bool zoomOnScroll; // translate scroll events to zoom std::vector thumbnailZoomRatios; From 00cf09d67527d39468d48f866034247b9094c58e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Fri, 14 Jul 2023 18:40:52 +0200 Subject: [PATCH 274/326] Displays the correct boxes --- rtgui/filmnegative.cc | 132 +++++++++++++++++++++++++++++++++++++----- rtgui/filmnegative.h | 1 + 2 files changed, 119 insertions(+), 14 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 4f1ae9311..a91af4634 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -190,6 +190,68 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } +} +std::unique_ptr spot_setup(int &associatedVar) +{ + std::unique_ptr spotSize(Gtk::manage (new MyComboBoxText ())); + setExpandAlignProperties(spotSize.get(), true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSize->append ("2"); + if (associatedVar == 2) { + spotSize->set_active(0); + } + + spotSize->append ("4"); + + if (associatedVar == 4) { + spotSize->set_active(1); + } + + spotSize->append ("8"); + + if (associatedVar == 8) { + spotSize->set_active(2); + } + + spotSize->append ("16"); + + if (associatedVar == 16) { + spotSize->set_active(3); + } + + spotSize->append ("32"); + + if (associatedVar == 32) { + spotSize->set_active(4); + } + return spotSize; +} + +void picker_setup(const std::unique_ptr slab, const std::unique_ptr spotButton, const std::unique_ptr spotSizeSetter) +{ + // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); + // refInputLabel->set_line_wrap(true); + + // TODO make spot size configurable ? + + setExpandAlignProperties(slab.get(), false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + std::unique_ptr spotSizeHelper(Gtk::manage(new Gtk::Grid())); + spotSizeHelper->set_name("Spot-Size-Helper"); + setExpandAlignProperties(spotSizeHelper.get(), false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + + std::unique_ptr spotgrid(Gtk::manage(new Gtk::Grid())); + spotgrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotgrid.get(), true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + + + spotSizeHelper->attach (*spotSizeSetter, 0, 0, 1, 1); + + spotgrid->attach (*spotButton, 0, 0, 1, 1); + spotgrid->attach (*slab, 1, 0, 1, 1); + spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); } FilmNegative::FilmNegative() : @@ -223,28 +285,69 @@ FilmNegative::FilmNegative() : refSpotButton->set_tooltip_text(M("TP_FILMNEGATIVE_REF_TOOLTIP")); + spotSize = Gtk::manage(new MyComboBoxText()); + setExpandAlignProperties(refInputLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); // TODO make spot size configurable ? - // Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); - // setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_SPOT_SIZE"))); + setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - // Gtk::Grid* wbsizehelper = Gtk::manage(new Gtk::Grid()); - // wbsizehelper->set_name("WB-Size-Helper"); - // setExpandAlignProperties(wbsizehelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + Gtk::Grid* spotSizeHelper = Gtk::manage(new Gtk::Grid()); + spotSizeHelper->set_name("Spot-Size-Helper"); + setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - // spotsize = Gtk::manage (new MyComboBoxText ()); - // setExpandAlignProperties(spotsize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - // spotsize->append ("2"); - // spotsize->set_active(0); - // spotsize->append ("4"); - // spotgrid->attach(*spotButton, 0, 1, 1, 1); - // spotgrid->attach (*slab, 1, 0, 1, 1); - // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); + // from white balance + Gtk::Grid* spotgrid = Gtk::manage(new Gtk::Grid()); + spotgrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSize = Gtk::manage (new MyComboBoxText ()); + setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSize->append ("2"); + if (options.whiteBalanceSpotSize == 2) { + spotSize->set_active(0); + } + + spotSize->append ("4"); + + if (options.whiteBalanceSpotSize == 4) { + spotSize->set_active(1); + } + + spotSize->append ("8"); + + if (options.whiteBalanceSpotSize == 8) { + spotSize->set_active(2); + } + + spotSize->append ("16"); + + if (options.whiteBalanceSpotSize == 16) { + spotSize->set_active(3); + } + + spotSize->append ("32"); + + if (options.whiteBalanceSpotSize == 32) { + spotSize->set_active(4); + } + + spotSizeHelper->attach (*spotSize, 0, 0, 1, 1); + + spotgrid->attach (*spotButton, 0, 0, 1, 1); + spotgrid->attach (*slab, 1, 0, 1, 1); + spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); + + //end + // refSpotSize->set_active(0); + // refSpotSize->append ("4"); + colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_INPUT")); colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_WORKING")); @@ -265,7 +368,8 @@ FilmNegative::FilmNegative() : pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - pack_start(*spotButton, Gtk::PACK_SHRINK, 0); + pack_start (*spotgrid, Gtk::PACK_SHRINK, 0 ); +// pack_start(*spotButton, Gtk::PACK_SHRINK, 0); // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 722625fa2..f95185a35 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -124,6 +124,7 @@ private: Gtk::Label* const refInputLabel; Gtk::ToggleButton* const refSpotButton; + MyComboBoxText* spotSize; Adjuster* const outputLevel; Adjuster* const greenBalance; From ab2cc4ba45ba7cbac62b387c306ff457ac506c82 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 15 Jul 2023 18:36:26 -0700 Subject: [PATCH 275/326] Fix auto DCP detection when using US English For systems where the locale is not English but the language in preferences is manually set to "English (US)", the Color Management Auto-matched camera profile option is not selectable even if a DCP exists for the camera. This is because the Glib::ustring casefold_collate_key() method returns a locale-dependent value. When initializing the list of DCP files, the system locale is used. When finding a matching DCP profile for an image, a different locale is used because the LANG environment variable is set while initializing the RawTherapee GUI language. --- rtengine/dcp.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index b65bb5f72..e949a808b 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -430,6 +430,16 @@ std::map getAliases(const Glib::ustring& profile_dir) return res; } +/** + * Returns a locale-independent case-insensitive collate key. Differs from + * Glib::ustring::casefold_collate_key() in that the Glib method may return + * different results depending on the current locale. + */ +std::string casefold_collate_key(const Glib::ustring &str) +{ + return str.casefold().raw(); +} + } struct DCPProfileApplyState::Data { @@ -1831,7 +1841,7 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) && lastdot <= sname.size() - 4 && !sname.casefold().compare(lastdot, 4, ".dcp") ) { - file_std_profiles[sname.substr(0, lastdot).casefold_collate_key()] = fname; // They will be loaded and cached on demand + file_std_profiles[casefold_collate_key(sname.substr(0, lastdot))] = fname; // They will be loaded and cached on demand } } else { // Directory @@ -1842,10 +1852,10 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) for (const auto& alias : getAliases(rt_profile_dir)) { const Glib::ustring alias_name = Glib::ustring(alias.first).uppercase(); - const std::map::const_iterator real = file_std_profiles.find(Glib::ustring(alias.second).casefold_collate_key()); + const std::map::const_iterator real = file_std_profiles.find(casefold_collate_key(alias.second)); if (real != file_std_profiles.end()) { - file_std_profiles[alias_name.casefold_collate_key()] = real->second; + file_std_profiles[casefold_collate_key(alias_name)] = real->second; } } } @@ -1892,7 +1902,7 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const DCPProfile* DCPStore::getStdProfile(const Glib::ustring& requested_cam_short_name) const { - const std::map::const_iterator iter = file_std_profiles.find(requested_cam_short_name.casefold_collate_key()); + const std::map::const_iterator iter = file_std_profiles.find(casefold_collate_key(requested_cam_short_name)); if (iter != file_std_profiles.end()) { return getProfile(iter->second); } From 6f50b68fa7230ac765c308b7014eafaf01badf9a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:17:57 -0700 Subject: [PATCH 276/326] Consider raw border with CA avoid color shift --- rtengine/CA_correct_RT.cc | 3 ++- rtengine/rawimagesource.cc | 8 ++++---- rtengine/rawimagesource.h | 1 + rtgui/bayerprocess.cc | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index c17826623..5352f19c5 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -123,6 +123,7 @@ float* RawImageSource::CA_correct_RT( double cared, double cablue, bool avoidColourshift, + int border_crop, array2D &rawData, double* fitParamsTransfer, bool fitParamsIn, @@ -145,7 +146,7 @@ float* RawImageSource::CA_correct_RT( const unsigned int cfa[2][2] = {{FC(0,0), FC(0,1)}, {FC(1,0), FC(1,1)}}; constexpr int ts = 128; constexpr int tsh = ts / 2; - constexpr int cb = 2; // 2 pixels border will be excluded from correction + const int cb = border_crop; //shifts to location of vertical and diagonal neighbours constexpr int v1 = ts, v2 = 2 * ts, v3 = 3 * ts, v4 = 4 * ts; //, p1=-ts+1, p2=-2*ts+2, p3=-3*ts+3, m1=ts+1, m2=2*ts+2, m3=3*ts+3; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 06aa701e8..00f24e42e 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1673,13 +1673,13 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } if (numFrames == 4) { double fitParams[64]; - float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure); + float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, raw.bayersensor.border, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure); for (int i = 1; i < 3; ++i) { - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, raw.bayersensor.border, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure); } - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, raw.bayersensor.border, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure); } else { - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA, options.measure); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, raw.bayersensor.border, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA, options.measure); } } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index b19c6f5c0..3a0d30f02 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -249,6 +249,7 @@ protected: double cared, double cablue, bool avoidColourshift, + int border, array2D &rawData, double* fitParamsTransfer, bool fitParamsIn, diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index e7e038e52..5ef3a777c 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -36,7 +36,7 @@ BayerProcess::BayerProcess () : { auto m = ProcEventMapper::getInstance(); - EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER"); + EvDemosaicBorder = m->newEvent(DARKFRAME, "HISTORY_MSG_RAW_BORDER"); EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST"); EvDemosaicAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST"); EvDemosaicPixelshiftDemosaicMethod = m->newEvent(DEMOSAIC, "HISTORY_MSG_PIXELSHIFT_DEMOSAIC"); From 1fb5a5b7353fd08bc01cbac1358f2f4d976a9b48 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Sun, 16 Jul 2023 20:53:37 -0700 Subject: [PATCH 277/326] macOS: fixes -cli Fixes the Command Line Interface (CLI) rawtherapee-cli executable for macOS using ad hoc codesign. --- tools/osx/macosx_bundle.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index ca381ec14..0782e3fc8 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -316,7 +316,7 @@ for frameworklibs in "${LIB}"/*{dylib,so,cli}; do 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 -ditto "${EXECUTABLE}"-cli "${APP}"/.. +# ditto "${EXECUTABLE}"-cli "${APP}"/.. # Merge the app with the other architecture to create the Universal app. if [[ -n $UNIVERSAL_URL ]]; then @@ -324,7 +324,7 @@ if [[ -n $UNIVERSAL_URL ]]; then 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/*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) @@ -344,13 +344,15 @@ if [[ -n $UNIVERSAL_URL ]]; then hdiutil unmount ./RawTherapeeuniv rm -r univapp # Create the fat main RawTherapee binary and move it into the new bundle - lipo -create -output RawTherapee RawTherapee-arm64.app/Contents/MacOS/RawTherapee RawTherapee-x86_64.app/Contents/MacOS/RawTherapee - mv RawTherapee RawTherapee.app/Contents/MacOS + lipo -create -output RawTherapee RawTherapee-arm64.app/Contents/MacOS/rawtherapee RawTherapee-x86_64.app/Contents/MacOS/rawtherapee + lipo -create -output rawtherapee-cli RawTherapee-arm64.app/Contents/MacOS/rawtherapee-cli RawTherapee-x86_64.app/Contents/MacOS/rawtherapee-cli + mv rawtherapee RawTherapee.app/Contents/MacOS # Create all the fat dependencies and move them into the bundle for lib in RawTherapee-arm64.app/Contents/Frameworks/* ; do lipo -create -output $(basename $lib) RawTherapee-arm64.app/Contents/Frameworks/$(basename $lib) RawTherapee-x86_64.app/Contents/Frameworks/$(basename $lib) done - sudo mv *cli *so *dylib RawTherapee.app/Contents/Frameworks + sudo mv *so *dylib RawTherapee.app/Contents/Frameworks + sudo mv *-cli RawTherapee.app/Contents/MacOS rm -r RawTherapee-arm64.app rm -r RawTherapee-x86_64.app else @@ -363,7 +365,8 @@ 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}" +# 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}" spctl -a -vvvv "${APP}" fi @@ -441,7 +444,8 @@ function CreateDmg { # Zip disk image for redistribution msg "Zipping disk image for redistribution:" mkdir "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" - cp {"${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.dmg","${PROJECT_NAME}.app/Contents/Frameworks/rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.readme.rtf"} "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" + cp {"${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.dmg","${PROJECT_NAME}.app/Contents/MacOS/rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.readme.rtf"} "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" + codesign -s - -i com.rawtherapee.rawtherapee-cli -f "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/rawtherapee-cli" zip -r "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/" if [[ -n $NIGHTLY ]]; then cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" From b94727e8384a1ed2fa54f466830b9b859cc3e10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 14:26:02 +0200 Subject: [PATCH 278/326] Picker setup/template in helper function --- rtgui/filmnegative.cc | 84 ++++++++++--------------------------------- 1 file changed, 18 insertions(+), 66 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index a91af4634..bcaba309e 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -191,10 +191,10 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } -std::unique_ptr spot_setup(int &associatedVar) +MyComboBoxText* spot_setup(int const &associatedVar) { - std::unique_ptr spotSize(Gtk::manage (new MyComboBoxText ())); - setExpandAlignProperties(spotSize.get(), true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + MyComboBoxText* spotSize(Gtk::manage (new MyComboBoxText ())); + setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotSize->append ("2"); if (associatedVar == 2) { @@ -227,31 +227,30 @@ std::unique_ptr spot_setup(int &associatedVar) return spotSize; } -void picker_setup(const std::unique_ptr slab, const std::unique_ptr spotButton, const std::unique_ptr spotSizeSetter) +Gtk::Grid* picker_template( Gtk::Label* const &slab, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) { // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); // TODO make spot size configurable ? - setExpandAlignProperties(slab.get(), false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - std::unique_ptr spotSizeHelper(Gtk::manage(new Gtk::Grid())); + Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); spotSizeHelper->set_name("Spot-Size-Helper"); - setExpandAlignProperties(spotSizeHelper.get(), false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - std::unique_ptr spotgrid(Gtk::manage(new Gtk::Grid())); + Gtk::Grid* spotgrid(Gtk::manage(new Gtk::Grid())); spotgrid->get_style_context()->add_class("grid-spacing"); - setExpandAlignProperties(spotgrid.get(), true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - + setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotSizeHelper->attach (*spotSizeSetter, 0, 0, 1, 1); spotgrid->attach (*spotButton, 0, 0, 1, 1); spotgrid->attach (*slab, 1, 0, 1, 1); spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); + return spotgrid; } FilmNegative::FilmNegative() : @@ -272,6 +271,7 @@ FilmNegative::FilmNegative() : redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent spotButton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))), + spotSize(spot_setup(options.whiteBalanceSpotSize)), 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 @@ -284,65 +284,15 @@ FilmNegative::FilmNegative() : spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); refSpotButton->set_tooltip_text(M("TP_FILMNEGATIVE_REF_TOOLTIP")); - - spotSize = Gtk::manage(new MyComboBoxText()); - setExpandAlignProperties(refInputLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); // TODO make spot size configurable ? - - Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_SPOT_SIZE"))); + // spotSize = spot_setup(options.whiteBalanceSpotSize); + Gtk::Label *slab(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - - Gtk::Grid* spotSizeHelper = Gtk::manage(new Gtk::Grid()); - spotSizeHelper->set_name("Spot-Size-Helper"); - setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - - // from white balance - Gtk::Grid* spotgrid = Gtk::manage(new Gtk::Grid()); - spotgrid->get_style_context()->add_class("grid-spacing"); - setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - spotSize = Gtk::manage (new MyComboBoxText ()); - setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - spotSize->append ("2"); - if (options.whiteBalanceSpotSize == 2) { - spotSize->set_active(0); - } - - spotSize->append ("4"); - - if (options.whiteBalanceSpotSize == 4) { - spotSize->set_active(1); - } - - spotSize->append ("8"); - - if (options.whiteBalanceSpotSize == 8) { - spotSize->set_active(2); - } - - spotSize->append ("16"); - - if (options.whiteBalanceSpotSize == 16) { - spotSize->set_active(3); - } - - spotSize->append ("32"); - - if (options.whiteBalanceSpotSize == 32) { - spotSize->set_active(4); - } - - spotSizeHelper->attach (*spotSize, 0, 0, 1, 1); - - spotgrid->attach (*spotButton, 0, 0, 1, 1); - spotgrid->attach (*slab, 1, 0, 1, 1); - spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); //end // refSpotSize->set_active(0); @@ -368,10 +318,11 @@ FilmNegative::FilmNegative() : pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - pack_start (*spotgrid, Gtk::PACK_SHRINK, 0 ); -// pack_start(*spotButton, Gtk::PACK_SHRINK, 0); + Gtk::Grid* spotgrid = picker_template(slab, spotButton, spotSize); + pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); -// pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); + // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); Gtk::Separator* const sep = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); sep->get_style_context()->add_class("grid-row-separator"); @@ -387,6 +338,7 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); + // Gtk::Grid *refSpotGrid = picker_template(slab, refSpotButton, spotSize); pack_start(*refSpotButton, Gtk::PACK_SHRINK, 0); spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); From d987cbd11be761751832fa5644e67e397f43e7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:33:56 +0200 Subject: [PATCH 279/326] Film negative white balance picker displays correctly in menu --- rtgui/filmnegative.cc | 6 ++++-- rtgui/filmnegative.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index bcaba309e..7d681e961 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -274,6 +274,7 @@ FilmNegative::FilmNegative() : spotSize(spot_setup(options.whiteBalanceSpotSize)), 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")))), + refSpotSize(spot_setup(options.whiteBalanceSpotSize)), 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 @@ -338,8 +339,9 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - // Gtk::Grid *refSpotGrid = picker_template(slab, refSpotButton, spotSize); - pack_start(*refSpotButton, Gtk::PACK_SHRINK, 0); + Gtk::Label *WBslab(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); + Gtk::Grid *refSpotGrid = picker_template(WBslab, refSpotButton, refSpotSize); + pack_start(*refSpotGrid, Gtk::PACK_SHRINK, 0); spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index f95185a35..2ccb133c8 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -121,10 +121,11 @@ private: Adjuster* const blueRatio; Gtk::ToggleButton* const spotButton; + MyComboBoxText* const spotSize; Gtk::Label* const refInputLabel; Gtk::ToggleButton* const refSpotButton; - MyComboBoxText* spotSize; + MyComboBoxText* const refSpotSize; Adjuster* const outputLevel; Adjuster* const greenBalance; From edcc52d2569304460ed63f399c2ad44df3e52b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:53:37 +0200 Subject: [PATCH 280/326] Standardised pickbutton creation/look by using new spot_button_template function. Every button has the same icon and should be provided with a tolltip --- rtgui/filmnegative.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 7d681e961..290691797 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -227,6 +227,16 @@ MyComboBoxText* spot_setup(int const &associatedVar) return spotSize; } +Gtk::ToggleButton* spot_button_template(Glib::ustring const &key, const Glib::ustring &tooltip) +{ + Gtk::ToggleButton *spotButton(Gtk::manage(new Gtk::ToggleButton(key))); + setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + spotButton->get_style_context()->add_class("independent"); + spotButton->set_tooltip_text(tooltip); + spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); + return spotButton; +} + Gtk::Grid* picker_template( Gtk::Label* const &slab, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) { // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); @@ -270,21 +280,15 @@ FilmNegative::FilmNegative() : greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 0.01, 1.5)), // master exponent (green channel) redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent - spotButton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))), + spotButton(spot_button_template(M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"))), spotSize(spot_setup(options.whiteBalanceSpotSize)), 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")))), + refSpotButton(spot_button_template(M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"))), refSpotSize(spot_setup(options.whiteBalanceSpotSize)), 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 { - 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"))); - - refSpotButton->set_tooltip_text(M("TP_FILMNEGATIVE_REF_TOOLTIP")); setExpandAlignProperties(refInputLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); From fc56161157ced260bfd350fe93246a3c4b4e4310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 20:53:37 +0200 Subject: [PATCH 281/326] The size of the negative picker rectangles can be changed. --- rtgui/filmnegative.cc | 82 +++++++++++++++++++++++++++---------------- rtgui/filmnegative.h | 21 +++++++++++ 2 files changed, 72 insertions(+), 31 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 290691797..dc13d6cae 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -191,7 +191,7 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } -MyComboBoxText* spot_setup(int const &associatedVar) +MyComboBoxText* spotSetup(int const &associatedVar) { MyComboBoxText* spotSize(Gtk::manage (new MyComboBoxText ())); setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -237,30 +237,30 @@ Gtk::ToggleButton* spot_button_template(Glib::ustring const &key, const Glib::us return spotButton; } -Gtk::Grid* picker_template( Gtk::Label* const &slab, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) +Gtk::Grid* pickerTemplate( Gtk::Label* const &spotLabel, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) { // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); // TODO make spot size configurable ? - setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(spotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); spotSizeHelper->set_name("Spot-Size-Helper"); setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - Gtk::Grid* spotgrid(Gtk::manage(new Gtk::Grid())); - spotgrid->get_style_context()->add_class("grid-spacing"); - setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Grid* spotGrid(Gtk::manage(new Gtk::Grid())); + spotGrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotSizeHelper->attach (*spotSizeSetter, 0, 0, 1, 1); - spotgrid->attach (*spotButton, 0, 0, 1, 1); - spotgrid->attach (*slab, 1, 0, 1, 1); - spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); - return spotgrid; + spotGrid->attach (*spotButton, 0, 0, 1, 1); + spotGrid->attach (*spotLabel, 1, 0, 1, 1); + spotGrid->attach (*spotSizeHelper, 2, 0, 1, 1); + return spotGrid; } FilmNegative::FilmNegative() : @@ -281,10 +281,13 @@ FilmNegative::FilmNegative() : redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent spotButton(spot_button_template(M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"))), - spotSize(spot_setup(options.whiteBalanceSpotSize)), + spotWidth(DEFAULT_SPOT_WIDTH), + spotSize(spotSetup(spotWidth)), refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), refSpotButton(spot_button_template(M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"))), - refSpotSize(spot_setup(options.whiteBalanceSpotSize)), + refSpotWidth(DEFAULT_SPOT_WIDTH), + refSpotSize(spotSetup(refSpotWidth)), + displayRectWidth(&spotWidth), 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 @@ -293,16 +296,6 @@ FilmNegative::FilmNegative() : // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); - // TODO make spot size configurable ? - // spotSize = spot_setup(options.whiteBalanceSpotSize); - Gtk::Label *slab(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); - setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - // from white balance - - //end - // refSpotSize->set_active(0); - // refSpotSize->append ("4"); - colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_INPUT")); colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_WORKING")); @@ -320,11 +313,14 @@ FilmNegative::FilmNegative() : colorSpace->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::colorSpaceChanged)); colorSpace->show(); + Gtk::Label *sLabel(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); + setExpandAlignProperties(sLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - Gtk::Grid* spotgrid = picker_template(slab, spotButton, spotSize); - pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + Gtk::Grid* spotGrid = pickerTemplate(sLabel, spotButton, spotSize); + pack_start(*spotGrid, Gtk::PACK_SHRINK, 0); // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); @@ -343,16 +339,19 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - Gtk::Label *WBslab(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); - Gtk::Grid *refSpotGrid = picker_template(WBslab, refSpotButton, refSpotSize); + Gtk::Label *negWBSpotLabel(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); + setExpandAlignProperties(negWBSpotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + Gtk::Grid *refSpotGrid = pickerTemplate(negWBSpotLabel, refSpotButton, refSpotSize); pack_start(*refSpotGrid, Gtk::PACK_SHRINK, 0); spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + spotSize->signal_changed().connect( sigc::mem_fun(*this, &FilmNegative::spotSizeChanged) ); refSpotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); + refSpotSize->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::refSpotChanged)); // Editing geometry; create the spot rectangle + // TODO: Change behaviour to match that of the white balance spot picker (rectangle disappears behind right toolbar) Rectangle* const spotRect = new Rectangle(); spotRect->filled = false; @@ -627,7 +626,7 @@ bool FilmNegative::mouseOver(int modifierKey) { EditDataProvider* const provider = getEditProvider(); Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); - spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); + spotRect->setXYWH(provider->posImage.x - *displayRectWidth, provider->posImage.y - *displayRectWidth, *displayRectWidth * 2, *displayRectWidth * 2); return true; } @@ -649,8 +648,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], 32, ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], 32, ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], spotWidth, ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], spotWidth, ref2, dummy)) { disableListener(); @@ -696,7 +695,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, 32, refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refSpotWidth, refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); @@ -770,6 +769,9 @@ void FilmNegative::editToggled() refSpotButton->set_active(false); refSpotCoords.clear(); + displayRectWidth = &spotWidth; + // if (spotlistener) + // spotlistener->spotNegRequested(spotWidth); subscribe(); @@ -793,6 +795,9 @@ void FilmNegative::refSpotToggled() spotButton->set_active(false); refSpotCoords.clear(); + displayRectWidth = &refSpotWidth; + // if (spotlistener) + // spotlistener->spotNegRequested(refSpotWidth); subscribe(); @@ -809,3 +814,18 @@ void FilmNegative::refSpotToggled() unsubscribe(); } } + +void FilmNegative::spotSizeChanged () +{ + spotWidth = atoi(spotSize->get_active_text().c_str()); + + // if (spotlistener) + // spotlistener->spotNegRequested(spotWidth); +} + +void FilmNegative::refSpotChanged() +{ + refSpotWidth = atoi(refSpotSize->get_active_text().c_str()); + // if (spotlistener) + // spotlistener->spotNegRequested(refSpotWidth); +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 2ccb133c8..98242d636 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -43,6 +43,12 @@ public: virtual bool getFilmNegativeSpot(rtengine::Coord spot, int spotSize, RGB &refInput, RGB &refOutput) = 0; }; +// class FilmNegSpotListener +// { +// public: +// virtual ~FilmNegSpotListener() = default; +// virtual void spotNegRequested(int size) = 0; +// }; class FilmNegative final : public ToolParamBlock, @@ -79,6 +85,10 @@ public: bool button1Released() override; bool button3Pressed(int modifierKey) override; void switchOffEditMode() override; + // void setFilmNegSpotListener(FilmNegSpotListener* listener) + // { + // spotlistener = listener; + // } private: void editToggled(); @@ -87,6 +97,9 @@ private: void readOutputSliders(RGB &refOutput); void writeOutputSliders(const RGB &refOutput); + void spotSizeChanged(); + void refSpotChanged(); + // ColorTemp value corresponding to neutral RGB multipliers (1,1,1). Should be around 6500K. const rtengine::ColorTemp NEUTRAL_TEMP; @@ -96,6 +109,8 @@ private: const rtengine::ProcEvent evFilmNegativeBalance; const rtengine::ProcEvent evFilmNegativeColorSpace; + // FilmNegSpotListener* spotlistener; + std::vector refSpotCoords; RGB refInputValues; @@ -120,12 +135,18 @@ private: Adjuster* const redRatio; Adjuster* const blueRatio; + #define DEFAULT_SPOT_WIDTH 8 + Gtk::ToggleButton* const spotButton; + int spotWidth; MyComboBoxText* const spotSize; Gtk::Label* const refInputLabel; Gtk::ToggleButton* const refSpotButton; + int refSpotWidth; MyComboBoxText* const refSpotSize; + + int* displayRectWidth; Adjuster* const outputLevel; Adjuster* const greenBalance; From d700364858346bdf14f688296bb702d33f4fbe2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 20:53:37 +0200 Subject: [PATCH 282/326] The size of the negative picker rectangles can be changed. --- rtgui/filmnegative.cc | 88 ++++++++++++++++++++++++++----------------- rtgui/filmnegative.h | 21 +++++++++++ 2 files changed, 75 insertions(+), 34 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 290691797..41b10a687 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -191,7 +191,7 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } -MyComboBoxText* spot_setup(int const &associatedVar) +MyComboBoxText* spotSetup(int const &associatedVar) { MyComboBoxText* spotSize(Gtk::manage (new MyComboBoxText ())); setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -227,7 +227,7 @@ MyComboBoxText* spot_setup(int const &associatedVar) return spotSize; } -Gtk::ToggleButton* spot_button_template(Glib::ustring const &key, const Glib::ustring &tooltip) +Gtk::ToggleButton* spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) { Gtk::ToggleButton *spotButton(Gtk::manage(new Gtk::ToggleButton(key))); setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -237,30 +237,30 @@ Gtk::ToggleButton* spot_button_template(Glib::ustring const &key, const Glib::us return spotButton; } -Gtk::Grid* picker_template( Gtk::Label* const &slab, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) +Gtk::Grid* pickerTemplate( Gtk::Label* const &spotLabel, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) { // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); // TODO make spot size configurable ? - setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + setExpandAlignProperties(spotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); spotSizeHelper->set_name("Spot-Size-Helper"); setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - Gtk::Grid* spotgrid(Gtk::manage(new Gtk::Grid())); - spotgrid->get_style_context()->add_class("grid-spacing"); - setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Grid* spotGrid(Gtk::manage(new Gtk::Grid())); + spotGrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotSizeHelper->attach (*spotSizeSetter, 0, 0, 1, 1); - spotgrid->attach (*spotButton, 0, 0, 1, 1); - spotgrid->attach (*slab, 1, 0, 1, 1); - spotgrid->attach (*spotSizeHelper, 2, 0, 1, 1); - return spotgrid; + spotGrid->attach (*spotButton, 0, 0, 1, 1); + spotGrid->attach (*spotLabel, 1, 0, 1, 1); + spotGrid->attach (*spotSizeHelper, 2, 0, 1, 1); + return spotGrid; } FilmNegative::FilmNegative() : @@ -280,11 +280,14 @@ FilmNegative::FilmNegative() : greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 0.01, 1.5)), // master exponent (green channel) redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent - spotButton(spot_button_template(M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"))), - spotSize(spot_setup(options.whiteBalanceSpotSize)), + spotButton(spotButtonTemplate(M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"))), + spotWidth(DEFAULT_SPOT_WIDTH), + spotSize(spotSetup(spotWidth)), refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), - refSpotButton(spot_button_template(M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"))), - refSpotSize(spot_setup(options.whiteBalanceSpotSize)), + refSpotButton(spotButtonTemplate(M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"))), + refSpotWidth(DEFAULT_SPOT_WIDTH), + refSpotSize(spotSetup(refSpotWidth)), + displayRectWidth(&spotWidth), 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 @@ -293,16 +296,6 @@ FilmNegative::FilmNegative() : // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); // refInputLabel->set_line_wrap(true); - // TODO make spot size configurable ? - // spotSize = spot_setup(options.whiteBalanceSpotSize); - Gtk::Label *slab(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); - setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - // from white balance - - //end - // refSpotSize->set_active(0); - // refSpotSize->append ("4"); - colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_INPUT")); colorSpace->append(M("TP_FILMNEGATIVE_COLORSPACE_WORKING")); @@ -320,11 +313,14 @@ FilmNegative::FilmNegative() : colorSpace->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::colorSpaceChanged)); colorSpace->show(); + Gtk::Label *sLabel(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); + setExpandAlignProperties(sLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - Gtk::Grid* spotgrid = picker_template(slab, spotButton, spotSize); - pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + Gtk::Grid* spotGrid = pickerTemplate(sLabel, spotButton, spotSize); + pack_start(*spotGrid, Gtk::PACK_SHRINK, 0); // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); @@ -343,16 +339,19 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - Gtk::Label *WBslab(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); - Gtk::Grid *refSpotGrid = picker_template(WBslab, refSpotButton, refSpotSize); + Gtk::Label *negWBSpotLabel(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); + setExpandAlignProperties(negWBSpotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + Gtk::Grid *refSpotGrid = pickerTemplate(negWBSpotLabel, refSpotButton, refSpotSize); pack_start(*refSpotGrid, Gtk::PACK_SHRINK, 0); spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + spotSize->signal_changed().connect( sigc::mem_fun(*this, &FilmNegative::spotSizeChanged) ); refSpotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); + refSpotSize->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::refSpotChanged)); // Editing geometry; create the spot rectangle + // TODO: Change behaviour to match that of the white balance spot picker (rectangle disappears behind right toolbar) Rectangle* const spotRect = new Rectangle(); spotRect->filled = false; @@ -627,7 +626,7 @@ bool FilmNegative::mouseOver(int modifierKey) { EditDataProvider* const provider = getEditProvider(); Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); - spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); + spotRect->setXYWH(provider->posImage.x - *displayRectWidth, provider->posImage.y - *displayRectWidth, *displayRectWidth * 2, *displayRectWidth * 2); return true; } @@ -649,8 +648,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], 32, ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], 32, ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], spotWidth, ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], spotWidth, ref2, dummy)) { disableListener(); @@ -696,7 +695,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, 32, refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refSpotWidth, refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); @@ -770,6 +769,9 @@ void FilmNegative::editToggled() refSpotButton->set_active(false); refSpotCoords.clear(); + displayRectWidth = &spotWidth; + // if (spotlistener) + // spotlistener->spotNegRequested(spotWidth); subscribe(); @@ -793,6 +795,9 @@ void FilmNegative::refSpotToggled() spotButton->set_active(false); refSpotCoords.clear(); + displayRectWidth = &refSpotWidth; + // if (spotlistener) + // spotlistener->spotNegRequested(refSpotWidth); subscribe(); @@ -809,3 +814,18 @@ void FilmNegative::refSpotToggled() unsubscribe(); } } + +void FilmNegative::spotSizeChanged () +{ + spotWidth = atoi(spotSize->get_active_text().c_str()); + + // if (spotlistener) + // spotlistener->spotNegRequested(spotWidth); +} + +void FilmNegative::refSpotChanged() +{ + refSpotWidth = atoi(refSpotSize->get_active_text().c_str()); + // if (spotlistener) + // spotlistener->spotNegRequested(refSpotWidth); +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 2ccb133c8..98242d636 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -43,6 +43,12 @@ public: virtual bool getFilmNegativeSpot(rtengine::Coord spot, int spotSize, RGB &refInput, RGB &refOutput) = 0; }; +// class FilmNegSpotListener +// { +// public: +// virtual ~FilmNegSpotListener() = default; +// virtual void spotNegRequested(int size) = 0; +// }; class FilmNegative final : public ToolParamBlock, @@ -79,6 +85,10 @@ public: bool button1Released() override; bool button3Pressed(int modifierKey) override; void switchOffEditMode() override; + // void setFilmNegSpotListener(FilmNegSpotListener* listener) + // { + // spotlistener = listener; + // } private: void editToggled(); @@ -87,6 +97,9 @@ private: void readOutputSliders(RGB &refOutput); void writeOutputSliders(const RGB &refOutput); + void spotSizeChanged(); + void refSpotChanged(); + // ColorTemp value corresponding to neutral RGB multipliers (1,1,1). Should be around 6500K. const rtengine::ColorTemp NEUTRAL_TEMP; @@ -96,6 +109,8 @@ private: const rtengine::ProcEvent evFilmNegativeBalance; const rtengine::ProcEvent evFilmNegativeColorSpace; + // FilmNegSpotListener* spotlistener; + std::vector refSpotCoords; RGB refInputValues; @@ -120,12 +135,18 @@ private: Adjuster* const redRatio; Adjuster* const blueRatio; + #define DEFAULT_SPOT_WIDTH 8 + Gtk::ToggleButton* const spotButton; + int spotWidth; MyComboBoxText* const spotSize; Gtk::Label* const refInputLabel; Gtk::ToggleButton* const refSpotButton; + int refSpotWidth; MyComboBoxText* const refSpotSize; + + int* displayRectWidth; Adjuster* const outputLevel; Adjuster* const greenBalance; From 2c6b7130048450a040ccbbd514bfc4808e5b903c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 23:38:44 +0200 Subject: [PATCH 283/326] Added text to label --- rtdata/languages/default | 2 ++ rtgui/filmnegative.cc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 050836d21..578de8be3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2498,10 +2498,12 @@ TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picki 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_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. +TP_FILMNEGATIVE_REF_SIZE;Size 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 diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 41b10a687..5d46554d2 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -313,7 +313,7 @@ FilmNegative::FilmNegative() : colorSpace->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::colorSpaceChanged)); colorSpace->show(); - Gtk::Label *sLabel(Gtk::manage(new Gtk::Label(M("TP_SPOT_SIZE")))); + Gtk::Label *sLabel(Gtk::manage(new Gtk::Label(M("TP_FILMNEGATIVE_PICK_SIZE")))); setExpandAlignProperties(sLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); pack_start(*greenExp, Gtk::PACK_SHRINK, 0); @@ -339,7 +339,7 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - Gtk::Label *negWBSpotLabel(Gtk::manage(new Gtk::Label(M("TP_WB_SPOT_SIZE")))); + Gtk::Label *negWBSpotLabel(Gtk::manage(new Gtk::Label(M("TP_FILMNEGATIVE_REF_SIZE")))); setExpandAlignProperties(negWBSpotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); Gtk::Grid *refSpotGrid = pickerTemplate(negWBSpotLabel, refSpotButton, refSpotSize); pack_start(*refSpotGrid, Gtk::PACK_SHRINK, 0); From 372ee6c31c90e5a1faf0ab9d81c5d203c4a11235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 23:41:34 +0200 Subject: [PATCH 284/326] Ran ./tools/generateTranslationDiffs --- rtdata/languages/Catala | 90 ++++++++++++++++-- rtdata/languages/Chinese (Simplified) | 88 +++++++++++++++-- rtdata/languages/Czech | 88 +++++++++++++++-- rtdata/languages/Dansk | 88 +++++++++++++++-- rtdata/languages/Deutsch | 85 ++++++++++++++++- rtdata/languages/English (UK) | 94 ++++++++++++++++--- rtdata/languages/English (US) | 94 ++++++++++++++++--- rtdata/languages/Espanol (Castellano) | 84 ++++++++++++++++- rtdata/languages/Espanol (Latin America) | 88 +++++++++++++++-- rtdata/languages/Francais | 82 +++++++++++++++- rtdata/languages/Italiano | 88 +++++++++++++++-- rtdata/languages/Japanese | 80 +++++++++++++++- rtdata/languages/Magyar | 92 ++++++++++++++++-- rtdata/languages/Nederlands | 88 +++++++++++++++-- rtdata/languages/Polish | 88 +++++++++++++++-- rtdata/languages/Portugues | 88 +++++++++++++++-- rtdata/languages/Portugues (Brasil) | 88 +++++++++++++++-- rtdata/languages/Russian | 88 +++++++++++++++-- rtdata/languages/Serbian (Cyrilic Characters) | 88 +++++++++++++++-- rtdata/languages/Slovenian | 88 +++++++++++++++-- rtdata/languages/Swedish | 88 +++++++++++++++-- rtdata/languages/default | 35 ++++--- 22 files changed, 1717 insertions(+), 163 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 4485966ff..623776056 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -907,6 +907,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type +!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -923,14 +924,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green !FILEBROWSER_POPUPCOLORLABEL4;Label: Blue !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -938,6 +937,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version +!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 !FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 !FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 @@ -950,6 +950,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -963,6 +964,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -1971,18 +1973,22 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2002,6 +2008,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2047,6 +2055,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2086,6 +2099,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. @@ -2199,6 +2213,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_LOCALLAB;Local Adjustments @@ -2220,6 +2235,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2237,6 +2253,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2275,6 +2292,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -2284,6 +2306,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2316,12 +2339,20 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_WBA;White Balance !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_GLOBALPROFILES;Bundled profiles !PROFILEPANEL_MODE_TOOLTIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. @@ -2350,11 +2381,19 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. !SOFTPROOF_GAMUTCHECK_TOOLTIP;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 @@ -2449,7 +2488,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Adaptation +!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene +!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2515,6 +2555,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2671,9 +2712,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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? @@ -2681,6 +2724,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -2694,8 +2738,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_GRADIENT_LABEL;Graduated Filter !TP_GRADIENT_STRENGTH;Strength !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !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 @@ -2707,6 +2753,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. !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 @@ -2797,7 +2844,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 is used. +!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 @@ -2856,6 +2903,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -2945,13 +2994,15 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3027,6 +3078,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -3115,6 +3171,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3175,11 +3233,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3211,7 +3271,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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;This 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_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. @@ -3260,7 +3320,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3286,7 +3345,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_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 @@ -3480,6 +3539,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3806,6 +3866,16 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -4060,6 +4130,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_WBALANCE_AUTO_HEADER;Automatic !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_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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index e4e89fed2..c1f80886b 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -143,7 +143,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 FILEBROWSER_PASTEPROFILE;粘贴 FILEBROWSER_POPUPCANCELJOB;取消任务 FILEBROWSER_POPUPCOLORLABEL;色彩标签 -FILEBROWSER_POPUPCOLORLABEL0;标签:无 FILEBROWSER_POPUPCOLORLABEL1;标签:红 FILEBROWSER_POPUPCOLORLABEL2;标签:黄 FILEBROWSER_POPUPCOLORLABEL3;标签:绿 @@ -161,7 +160,6 @@ FILEBROWSER_POPUPPROCESS;放入队列 FILEBROWSER_POPUPPROCESSFAST;放入队列(快速导出) FILEBROWSER_POPUPPROFILEOPERATIONS;后期档案操作 FILEBROWSER_POPUPRANK;评级 -FILEBROWSER_POPUPRANK0;取消评级 FILEBROWSER_POPUPRANK1;评1星 FILEBROWSER_POPUPRANK2;评2星 FILEBROWSER_POPUPRANK3;评3星 @@ -2436,6 +2434,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files +!GENERAL_OTHER;Other !HISTORY_MSG_112;--unused-- !HISTORY_MSG_137;Black level - Green 1 !HISTORY_MSG_138;Black level - Red @@ -3058,13 +3060,17 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_BLURWAV;Blur luminance !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_EDGEFFECT;Edge Attenuation response +!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata !HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output !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_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries @@ -3079,6 +3085,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3098,6 +3106,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3132,6 +3145,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description !ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. @@ -3199,8 +3213,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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. +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic !PREFERENCES_CIE;Ciecam !PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder @@ -3210,16 +3227,38 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID !PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Bypass output profile !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_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_LENSPROFILESDIR;Lens profiles directory +!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 !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser !SAMPLEFORMAT_1;8-bit unsigned !SAMPLEFORMAT_2;16-bit unsigned !SAMPLEFORMAT_4;24-bit LogLuv !SAMPLEFORMAT_8;32-bit LogLuv +!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. !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -3243,6 +3282,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. !TP_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_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_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. @@ -3260,6 +3300,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_COLORAPP_MOD16;CAM16 !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_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. @@ -3278,7 +3319,12 @@ 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 +!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 @@ -3290,6 +3336,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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. !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_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. !TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. @@ -3359,7 +3406,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 is used. +!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 @@ -3389,6 +3436,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 !TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz !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_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_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. @@ -3444,9 +3493,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_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 RT-spot size: 128x128. !TP_LOCALLAB_DETAILFRA;Edge detection - DCT -!TP_LOCALLAB_DETAILTHR;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !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. @@ -3481,6 +3532,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_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. @@ -3544,6 +3600,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_LEVELBLUR;Maximum blur 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. @@ -3586,8 +3644,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_LUM;LL - CC +!TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 !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_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_MASKCOM;Common Color Mask @@ -3616,7 +3676,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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;This 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_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. @@ -3664,7 +3724,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 @@ -3683,7 +3742,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_NLFRA;Non-local Means - Luminance +!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_NLPAT;Maximum patch size !TP_LOCALLAB_NLRAD;Maximum radius size @@ -3801,6 +3860,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_TE_PIVOT;Pivot (Ev) !TP_LOCALLAB_THRES;Threshold structure !TP_LOCALLAB_THRESDELTAE;ΔE scope threshold !TP_LOCALLAB_THRESRETI;Threshold @@ -3966,6 +4026,16 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_RETINEX_VIEW_TRAN;Transmission - Auto !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 @@ -4077,6 +4147,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_WBALANCE_LAMP_HEADER;Lamp !TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!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_SOLUX47;Solux 4700K (vendor) !TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) !TP_WBALANCE_STUDLABEL;Correlation factor: %1 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 61e6af4bf..8d9100d85 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -182,7 +182,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Vložit - částečně FILEBROWSER_PASTEPROFILE;Vložit FILEBROWSER_POPUPCANCELJOB;Zrušit úlohu FILEBROWSER_POPUPCOLORLABEL;Barevný štítek -FILEBROWSER_POPUPCOLORLABEL0;Štítek: Žádný FILEBROWSER_POPUPCOLORLABEL1;Štítek: Červený FILEBROWSER_POPUPCOLORLABEL2;Štítek: Žlutý FILEBROWSER_POPUPCOLORLABEL3;Štítek: Zelený @@ -199,7 +198,6 @@ FILEBROWSER_POPUPPROCESS;Vložit do fronty FILEBROWSER_POPUPPROCESSFAST;Vložit do fronty (Rychlý export) FILEBROWSER_POPUPPROFILEOPERATIONS;Operace profilů zpracování FILEBROWSER_POPUPRANK;Hodnocení -FILEBROWSER_POPUPRANK0;Odstranit hodnocení FILEBROWSER_POPUPRANK1;Hodnocení 1 * FILEBROWSER_POPUPRANK2;Hodnocení 2 ** FILEBROWSER_POPUPRANK3;Hodnocení 3 *** @@ -2424,9 +2422,13 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !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. @@ -3099,15 +3101,19 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_COMPLEX;Wavelet complexity !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation +!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 @@ -3115,6 +3121,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3128,6 +3136,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_RESIZE_SHORTEDGE;Resize - Short Edge !HISTORY_MSG_SPOT;Spot removal !HISTORY_MSG_SPOT_ENTRY;Spot removal - Point modif. +!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_WAVCHR;Blur levels - blur chroma !HISTORY_MSG_WAVDENLH;Level 5 !HISTORY_MSG_WAVDENOISE;Local contrast @@ -3147,14 +3160,18 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_WAVSTREND;Strength soft !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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_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 @@ -3167,9 +3184,31 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3183,6 +3222,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_GEN;Settings @@ -3194,6 +3234,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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. @@ -3206,11 +3247,17 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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 @@ -3266,7 +3313,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 is used. +!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 @@ -3325,6 +3372,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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. @@ -3414,13 +3463,15 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3496,6 +3547,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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. @@ -3584,6 +3640,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3644,11 +3702,13 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3680,7 +3740,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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;This 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_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. @@ -3729,7 +3789,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3755,7 +3814,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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 @@ -3949,6 +4008,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -4074,6 +4134,16 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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. @@ -4116,3 +4186,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_WAVELET_STREND;Strength !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_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. diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 2cfbf4e27..7299c6f5e 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -135,7 +135,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Sæt ind - partiel FILEBROWSER_PASTEPROFILE;Sæt ind FILEBROWSER_POPUPCANCELJOB;Annulér job FILEBROWSER_POPUPCOLORLABEL;Farvemærkat -FILEBROWSER_POPUPCOLORLABEL0;Mærkat: Ingen FILEBROWSER_POPUPCOLORLABEL1;Mærkat: Rød FILEBROWSER_POPUPCOLORLABEL2;Mærkat: Gul FILEBROWSER_POPUPCOLORLABEL3;Mærkat: Grøn @@ -152,7 +151,6 @@ FILEBROWSER_POPUPPROCESS;Sæt i kø FILEBROWSER_POPUPPROCESSFAST;Sæt i kø (hurtig eksport) FILEBROWSER_POPUPPROFILEOPERATIONS;Redigering af profiloperationer FILEBROWSER_POPUPRANK;Rang -FILEBROWSER_POPUPRANK0;Ikke rangeret FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2277,9 +2275,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !!!!!!!!!!!!!!!!!!!!!!!!! !CURVEEDITOR_CURVES;Curves +!EXIFFILTER_PATH;File path !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. @@ -2957,15 +2959,19 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -2974,6 +2980,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -2996,6 +3004,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3035,15 +3048,19 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3056,9 +3073,31 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3072,6 +3111,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_GEN;Settings @@ -3094,6 +3134,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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. @@ -3106,11 +3147,17 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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 @@ -3167,7 +3214,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 is used. +!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 @@ -3226,6 +3273,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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. @@ -3315,13 +3364,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3397,6 +3448,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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. @@ -3485,6 +3541,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3545,11 +3603,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3581,7 +3641,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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;This 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_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. @@ -3630,7 +3690,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3656,7 +3715,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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 @@ -3850,6 +3909,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3979,6 +4039,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -4069,5 +4139,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 3a2c2999c..82463fe75 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -221,7 +221,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Profil selektiv einfügen FILEBROWSER_PASTEPROFILE;Profil einfügen FILEBROWSER_POPUPCANCELJOB;Job abbrechen FILEBROWSER_POPUPCOLORLABEL;Farbmarkierung -FILEBROWSER_POPUPCOLORLABEL0;Markierung: Ohne FILEBROWSER_POPUPCOLORLABEL1;Markierung: Rot FILEBROWSER_POPUPCOLORLABEL2;Markierung: Gelb FILEBROWSER_POPUPCOLORLABEL3;Markierung: Grün @@ -239,7 +238,6 @@ FILEBROWSER_POPUPPROCESS;Zur Warteschlange hinzufügen FILEBROWSER_POPUPPROCESSFAST;Zur Warteschlange hinzufügen\n(Schnell-Export) FILEBROWSER_POPUPPROFILEOPERATIONS;Profiloperationen FILEBROWSER_POPUPRANK;Bewertung -FILEBROWSER_POPUPRANK0;Nicht bewertet FILEBROWSER_POPUPRANK1;Bewertung 1 * FILEBROWSER_POPUPRANK2;Bewertung 2 ** FILEBROWSER_POPUPRANK3;Bewertung 3 *** @@ -3200,7 +3198,6 @@ TP_LOCALLAB_MERNIN;Bildschirm TP_LOCALLAB_MERONE;Normal TP_LOCALLAB_MERSAT;Sättigung TP_LOCALLAB_MERSEV;Weiches Licht (legacy) -TP_LOCALLAB_MERSEV0;Weiches Licht Illusion TP_LOCALLAB_MERSEV1;Weiches Licht W3C TP_LOCALLAB_MERSEV2;Hartes Licht TP_LOCALLAB_MERSIX;Division @@ -4150,3 +4147,85 @@ 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. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXIFFILTER_PATH;File path +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files +!GENERAL_OTHER;Other +!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 - Gamut-Munsell +!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° +!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_LENSPROFILESDIR;Lens profiles directory +!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 +!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_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_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_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_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_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. diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 7de3a54cc..695cebaf3 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -108,6 +108,7 @@ PREFERENCES_PRTPROFILE;Colour profile PREFERENCES_TAB_COLORMGR;Colour Management 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 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 @@ -166,11 +167,9 @@ TP_ICM_INPUTEMBEDDED_TOOLTIP;Use colour profile embedded in non-raw files. TP_ICM_INPUTNONE_TOOLTIP;Use no input colour profile at all.\nUse only in special cases. TP_ICM_LABEL;Colour Management TP_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_LABCURVE_AVOIDCOLORSHIFT;Avoid colour shift -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colours into gamut of the working colour space and apply Munsell correction (Uniform Perceptual Lab). 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 is used. +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_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 @@ -271,6 +270,7 @@ TP_WAVELET_DENWAVHUE_TOOLTIP;Amplify or reduce denoising depending on the colour TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centreed on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. TP_WAVELET_TONFRAME;Excluded colours TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'white balance' by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +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. !!!!!!!!!!!!!!!!!!!!!!!!! ! Untranslated keys follow; remove the ! prefix after an entry is translated. @@ -335,6 +335,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !EXIFFILTER_ISO;ISO !EXIFFILTER_LENS;Lens !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFFILTER_PATH;File path !EXIFFILTER_SHUTTER;Shutter !EXIFPANEL_ADDEDIT;Add/Edit !EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. @@ -408,7 +409,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial !FILEBROWSER_PASTEPROFILE;Paste !FILEBROWSER_POPUPCANCELJOB;Cancel job -!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -426,7 +426,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) !FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations !FILEBROWSER_POPUPRANK;Rank -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -436,6 +435,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPRENAME;Rename !FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_POPUPTRASH;Move to trash !FILEBROWSER_POPUPUNRANK;Unrank !FILEBROWSER_POPUPUNTRASH;Remove from trash @@ -477,6 +477,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multiple Editor Tabs Mode,\nAlt-- - Single Editor Tab Mode. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_CURVE;Curve files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !FILECHOOSER_FILTER_LCP;Lens correction profiles !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo @@ -504,6 +505,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !GENERAL_NONE;None !GENERAL_OK;OK !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_PORTRAIT;Portrait !GENERAL_RESET;Reset !GENERAL_SAVE;Save @@ -1598,16 +1600,20 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_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_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 @@ -1627,6 +1633,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1670,6 +1678,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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 @@ -1708,6 +1721,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1807,7 +1821,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b !MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s\nSave current profile (.pp3).\nShortcut: Ctrl+Shift+s !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e\nCurrent editor: !MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m !MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen !MAIN_FRAME_EDITOR;Editor @@ -1919,6 +1933,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFILE;Flat-field file +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction @@ -1963,6 +1978,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PARTIALPASTE_SOFTLIGHT;Soft light !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TM_FATTAL;Dynamic range compression +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WHITEBALANCE;White balance @@ -1986,6 +2002,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries !PREFERENCES_CACHEOPTS;Cache Options !PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -2041,6 +2058,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir !PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output !PREFERENCES_EXTERNALEDITOR;External Editor +!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_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser !PREFERENCES_FLATFIELDFOUND;Found @@ -2065,6 +2087,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited !PREFERENCES_LANG;Language !PREFERENCES_LANGAUTODETECT;Use system language +!PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' @@ -2131,6 +2154,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !PREFERENCES_STARTUPIMDIR;Image Directory at Startup !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules +!PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_GENERAL;General !PREFERENCES_TAB_IMPROC;Image Processing !PREFERENCES_TAB_PERFORMANCE;Performance @@ -2139,9 +2163,16 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_TP_LABEL;Tool panel: !PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar !PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_WBA;White Balance !PREFERENCES_WORKFLOW;Layout !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2206,6 +2237,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !SAMPLEFORMAT_32;24-bit floating-point !SAMPLEFORMAT_64;32-bit floating-point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FILEFORMAT_FLOAT; floating-point !SAVEDLG_FORCEFORMATOPTS;Force saving options @@ -2223,6 +2255,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!SORT_ASCENDING;Ascending +!SORT_BY_DATE;By Date +!SORT_BY_EXIF;By EXIF +!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 @@ -2325,7 +2363,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_COLORAPP_CATSYMSPE;Mixed !TP_COLORAPP_CHROMA;Chroma (C) !TP_COLORAPP_CHROMA_S;Saturation (S) -!TP_COLORAPP_CIECAT_DEGREE;Adaptation +!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene +!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2382,6 +2421,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2572,9 +2612,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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? @@ -2589,6 +2631,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. +!TP_FLATFIELD_FROMMETADATA;From Metadata !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). @@ -2602,8 +2645,10 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. !TP_HLREC_BLEND;Blend !TP_HLREC_CIELAB;CIELab Blending +!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_HLREC_HLBLUR;Blur +!TP_HLREC_HLTH;Gain threshold !TP_HLREC_LABEL;Highlight reconstruction !TP_HLREC_LUMINANCE;Luminance Recovery !TP_HLREC_METHOD;Method: @@ -2623,6 +2668,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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. !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_INPUTCAMERA;Camera standard !TP_ICM_INPUTCAMERAICC;Auto-matched camera profile @@ -2810,6 +2856,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. !TP_LOCALLAB_CBDL_TOOLNAME;Contrast by Detail Levels !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. @@ -2883,12 +2931,14 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_DEPTH;Depth !TP_LOCALLAB_DETAIL;Local contrast !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details -!TP_LOCALLAB_DETAILTHR;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -2958,6 +3008,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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. @@ -3042,6 +3097,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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 @@ -3093,9 +3150,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_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 @@ -3114,7 +3173,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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;This 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_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_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. @@ -3148,7 +3207,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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 @@ -3173,7 +3231,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_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 @@ -3359,6 +3417,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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 @@ -3745,6 +3804,16 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !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_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple @@ -4043,6 +4112,9 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'wh !TP_WBALANCE_LED_HEADER;LED !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 !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_PICKER;Pick !TP_WBALANCE_SHADE;Shade !TP_WBALANCE_SIZE;Size: diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 40ad9c57b..96a6a9b8c 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -62,6 +62,7 @@ !EXIFFILTER_ISO;ISO !EXIFFILTER_LENS;Lens !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFFILTER_PATH;File path !EXIFFILTER_SHUTTER;Shutter !EXIFPANEL_ADDEDIT;Add/Edit !EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. @@ -138,7 +139,6 @@ !FILEBROWSER_PASTEPROFILE;Paste !FILEBROWSER_POPUPCANCELJOB;Cancel job !FILEBROWSER_POPUPCOLORLABEL;Color label -!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -156,7 +156,6 @@ !FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) !FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations !FILEBROWSER_POPUPRANK;Rank -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -166,6 +165,7 @@ !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPRENAME;Rename !FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_POPUPTRASH;Move to trash !FILEBROWSER_POPUPUNRANK;Unrank !FILEBROWSER_POPUPUNTRASH;Remove from trash @@ -209,6 +209,7 @@ !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 @@ -236,6 +237,7 @@ !GENERAL_NONE;None !GENERAL_OK;OK !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_PORTRAIT;Portrait !GENERAL_RESET;Reset !GENERAL_SAVE;Save @@ -1405,18 +1407,22 @@ !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 @@ -1436,6 +1442,8 @@ !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1481,6 +1489,11 @@ !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 @@ -1520,6 +1533,7 @@ !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1619,7 +1633,7 @@ !MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b !MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s\nSave current profile (.pp3).\nShortcut: Ctrl+Shift+s !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e\nCurrent editor: !MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m !MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen !MAIN_FRAME_EDITOR;Editor @@ -1739,6 +1753,7 @@ !PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFILE;Flat-field file +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_ICMSETTINGS;Color management settings @@ -1786,6 +1801,7 @@ !PARTIALPASTE_SOFTLIGHT;Soft light !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TM_FATTAL;Dynamic range compression +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WHITEBALANCE;White balance @@ -1814,6 +1830,7 @@ !PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries !PREFERENCES_CACHEOPTS;Cache Options !PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -1869,6 +1886,11 @@ !PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir !PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output !PREFERENCES_EXTERNALEDITOR;External Editor +!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_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser !PREFERENCES_FLATFIELDFOUND;Found @@ -1896,6 +1918,7 @@ !PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited !PREFERENCES_LANG;Language !PREFERENCES_LANGAUTODETECT;Use system language +!PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' @@ -1966,6 +1989,7 @@ !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_COLORMGR;Color Management !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules +!PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_GENERAL;General !PREFERENCES_TAB_IMPROC;Image Processing !PREFERENCES_TAB_PERFORMANCE;Performance @@ -1974,9 +1998,16 @@ !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_TP_LABEL;Tool panel: !PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar !PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_WBA;White Balance !PREFERENCES_WORKFLOW;Layout !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2041,6 +2072,7 @@ !SAMPLEFORMAT_32;24-bit floating-point !SAMPLEFORMAT_64;32-bit floating-point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FILEFORMAT_FLOAT; floating-point !SAVEDLG_FORCEFORMATOPTS;Force saving options @@ -2060,6 +2092,13 @@ !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -2176,7 +2215,8 @@ !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Adaptation +!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene +!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2242,6 +2282,7 @@ !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2456,9 +2497,11 @@ !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? @@ -2473,6 +2516,7 @@ !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. +!TP_FLATFIELD_FROMMETADATA;From Metadata !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center @@ -2490,8 +2534,10 @@ !TP_HLREC_BLEND;Blend !TP_HLREC_CIELAB;CIELab Blending !TP_HLREC_COLOR;Color Propagation +!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_HLREC_HLBLUR;Blur +!TP_HLREC_HLTH;Gain threshold !TP_HLREC_LABEL;Highlight reconstruction !TP_HLREC_LUMINANCE;Luminance Recovery !TP_HLREC_METHOD;Method: @@ -2511,6 +2557,7 @@ !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. !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_INPUTCAMERA;Camera standard !TP_ICM_INPUTCAMERAICC;Auto-matched camera profile @@ -2588,8 +2635,6 @@ !TP_ICM_WORKING_TRC_TOOLTIP;Only for built-in profiles. !TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction !TP_IMPULSEDENOISE_THRESH;Threshold -!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift -!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). !TP_LABCURVE_BRIGHTNESS;Lightness !TP_LABCURVE_CHROMATICITY;Chromaticity !TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. @@ -2654,7 +2699,7 @@ !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 is used. +!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 @@ -2713,6 +2758,8 @@ !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. @@ -2802,13 +2849,15 @@ !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -2884,6 +2933,11 @@ !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. @@ -2972,6 +3026,8 @@ !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 @@ -3032,11 +3088,13 @@ !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 @@ -3068,7 +3126,7 @@ !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;This 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_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. @@ -3117,7 +3175,6 @@ !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 @@ -3143,7 +3200,7 @@ !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_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 @@ -3337,6 +3394,7 @@ !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 @@ -3733,6 +3791,16 @@ !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_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones @@ -4043,6 +4111,10 @@ !TP_WBALANCE_LED_HEADER;LED !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 !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_PICKER;Pick !TP_WBALANCE_SHADE;Shade !TP_WBALANCE_SIZE;Size: diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index ede64894f..7a176fec1 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -136,7 +136,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil (parcialmente) FILEBROWSER_PASTEPROFILE;Pegar perfil FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color -FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Ninguna FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Roja FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarilla FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -154,7 +153,6 @@ FILEBROWSER_POPUPPROCESS;Enviar la imagen a la cola FILEBROWSER_POPUPPROCESSFAST;Enviar a la cola (Exportación rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles de revelado FILEBROWSER_POPUPRANK;Asignar rango -FILEBROWSER_POPUPRANK0;Sin rango FILEBROWSER_POPUPRANK1;Rango 1 * FILEBROWSER_POPUPRANK2;Rango 2 ** FILEBROWSER_POPUPRANK3;Rango 3 *** @@ -3115,7 +3113,6 @@ TP_LOCALLAB_MERNIN;Pantalla TP_LOCALLAB_MERONE;Normal TP_LOCALLAB_MERSAT;Saturación TP_LOCALLAB_MERSEV;Luz suave (anterior) -TP_LOCALLAB_MERSEV0;Ilusión de Luz suave TP_LOCALLAB_MERSEV1;Luz suave W3C TP_LOCALLAB_MERSEV2;Luz dura TP_LOCALLAB_MERSIX;Dividir @@ -4066,3 +4063,84 @@ ZOOMPANEL_ZOOMFITSCREEN;Encajar la imagen entera en la vista previa\nAtajo de te ZOOMPANEL_ZOOMIN;Acercar\nAtajo de teclado: + ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXIFFILTER_PATH;File path +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files +!GENERAL_OTHER;Other +!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 - Gamut-Munsell +!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° +!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_LENSPROFILESDIR;Lens profiles directory +!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 +!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_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_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_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_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_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. diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index 56a73d30f..151111900 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -191,7 +191,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil parcialmente FILEBROWSER_PASTEPROFILE;Pegar perfil FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color -FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Ninguna FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Rojo FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarillo FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -208,7 +207,6 @@ FILEBROWSER_POPUPPROCESS;Poner en la cola FILEBROWSER_POPUPPROCESSFAST;Poner en la cola (exportación rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles FILEBROWSER_POPUPRANK;Asignar rango -FILEBROWSER_POPUPRANK0;Sin Rango FILEBROWSER_POPUPRANK1;Rango 1 * FILEBROWSER_POPUPRANK2;Rango 2 ** FILEBROWSER_POPUPRANK3;Rango 3 *** @@ -2286,6 +2284,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !!!!!!!!!!!!!!!!!!!!!!!!! !CURVEEDITOR_CATMULLROM;Flexible +!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -2294,10 +2293,13 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!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. @@ -2976,17 +2978,21 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -2995,6 +3001,8 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -3025,6 +3033,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3064,6 +3077,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector @@ -3073,11 +3087,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !MAIN_TAB_LOCALLAB;Local !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_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -3096,10 +3113,24 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_PERFORMANCE_MEASURE;Measure !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3108,6 +3139,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location +!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 @@ -3121,6 +3160,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_GEN;Settings @@ -3143,6 +3183,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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. @@ -3161,12 +3202,18 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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_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 @@ -3229,7 +3276,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 is used. +!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 @@ -3288,6 +3335,8 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. @@ -3377,13 +3426,15 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3459,6 +3510,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. @@ -3547,6 +3603,8 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3607,11 +3665,13 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3643,7 +3703,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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;This 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_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. @@ -3692,7 +3752,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3718,7 +3777,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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 @@ -3912,6 +3971,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -4048,6 +4108,16 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -4138,5 +4208,9 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index b7b2c7ec7..9d875900c 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -130,7 +130,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Coller partiellement FILEBROWSER_PASTEPROFILE;Coller le profil FILEBROWSER_POPUPCANCELJOB;Retirer de la file de traitement FILEBROWSER_POPUPCOLORLABEL;Label couleur -FILEBROWSER_POPUPCOLORLABEL0;Label: Aucun FILEBROWSER_POPUPCOLORLABEL1;Label: Rouge FILEBROWSER_POPUPCOLORLABEL2;Label: Jaune FILEBROWSER_POPUPCOLORLABEL3;Label: Vert @@ -147,7 +146,6 @@ FILEBROWSER_POPUPPROCESS;Mettre dans la file de traitement FILEBROWSER_POPUPPROCESSFAST;Mettre dans la file de traitement (Export Rapide) FILEBROWSER_POPUPPROFILEOPERATIONS;Opérations sur les profils FILEBROWSER_POPUPRANK;Rang -FILEBROWSER_POPUPRANK0;Aucun FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2201,7 +2199,6 @@ TP_LOCALLAB_MERNIN;Ecran 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;Lumière dure TP_LOCALLAB_MERSIX;Divise @@ -3032,6 +3029,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -3040,10 +3038,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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. +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!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. @@ -3722,12 +3723,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !HISTORY_MSG_EDGEFFECT;Edge Attenuation response +!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata +!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 @@ -3736,6 +3741,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -3763,6 +3770,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_SIGMATON;Toning Attenuation response !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3802,12 +3814,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector !MAIN_FRAME_PLACES_DEL;Remove !PARTIALPASTE_FILMNEGATIVE;Film negative +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_PREPROCWB;Preprocess White Balance +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments @@ -3820,8 +3836,22 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3830,6 +3860,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location +!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 @@ -3842,6 +3880,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_GEN;Settings @@ -3864,12 +3903,19 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_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_CROP_GTCENTEREDSQUARE;Centered square !TP_CROP_PPI;PPI !TP_DEHAZE_SATURATION;Saturation +!TP_FILMNEGATIVE_PICK_SIZE;Size +!TP_FILMNEGATIVE_REF_SIZE;Size +!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_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 @@ -3924,26 +3970,39 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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 is used. +!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_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_COLOR_CIE;Color curve !TP_LOCALLAB_CURVES_CIE;Tone curve !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_DIVGR;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_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_GRAINFRA2;Coarseness !TP_LOCALLAB_HUECIE;Hue !TP_LOCALLAB_INVBL;Inverse !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_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 @@ -3956,6 +4015,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_SATURV;Saturation (s) +!TP_LOCALLAB_TE_PIVOT;Pivot (Ev) !TP_LOCALLAB_TOOLMASK_2;Wavelets !TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. !TP_LOCALLAB_ZCAMFRA;ZCAM Image Adjustments @@ -3983,6 +4043,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RESIZE_SHORT;Short Edge !TP_SHARPENING_ITERCHECK;Auto limit iterations !TP_SHARPENING_RADIUS_BOOST;Corner radius boost +!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 @@ -4070,5 +4140,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index e4447f7f6..28ba9d01b 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -103,7 +103,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Incolla - parziale FILEBROWSER_PASTEPROFILE;Incolla FILEBROWSER_POPUPCANCELJOB;Annulla lavoro FILEBROWSER_POPUPCOLORLABEL;Etichetta colorata -FILEBROWSER_POPUPCOLORLABEL0;Etichetta: Nessuna FILEBROWSER_POPUPCOLORLABEL1;Etichetta: Rosso FILEBROWSER_POPUPCOLORLABEL2;Etichetta: Giallo FILEBROWSER_POPUPCOLORLABEL3;Etichetta: Verde @@ -120,7 +119,6 @@ FILEBROWSER_POPUPPROCESS;Aggiungi alla Coda FILEBROWSER_POPUPPROCESSFAST;Aggiungi alla Coda (Esportazione Rapida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operazioni sui Profili di Sviluppo FILEBROWSER_POPUPRANK;Classificazione -FILEBROWSER_POPUPRANK0;Nessun Punteggio FILEBROWSER_POPUPRANK1;Punteggio 1 * FILEBROWSER_POPUPRANK2;Punteggio 2 ** FILEBROWSER_POPUPRANK3;Punteggio 3 *** @@ -1235,6 +1233,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile !EXIFFILTER_IMAGETYPE;Image type +!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -1252,12 +1251,14 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -1269,6 +1270,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2195,18 +2197,22 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2226,6 +2232,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2271,6 +2279,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2310,6 +2323,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2403,6 +2417,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2421,6 +2436,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2433,6 +2449,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2468,6 +2485,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -2476,6 +2498,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2508,11 +2531,19 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2534,10 +2565,18 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2560,6 +2599,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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] @@ -2586,6 +2626,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -2723,9 +2764,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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? @@ -2733,7 +2776,10 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2742,6 +2788,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2823,7 +2870,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 is used. +!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 @@ -2882,6 +2929,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -2971,13 +3020,15 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3053,6 +3104,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -3141,6 +3197,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3201,11 +3259,13 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3237,7 +3297,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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;This 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_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. @@ -3286,7 +3346,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3312,7 +3371,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_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 @@ -3506,6 +3565,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3815,6 +3875,16 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -4067,6 +4137,10 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 0f35036db..ab82ecf32 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -135,7 +135,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;プロファイルの貼り付け - 一部 FILEBROWSER_PASTEPROFILE;プロファイルの貼り付け FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル FILEBROWSER_POPUPCOLORLABEL;カラー・ラベル -FILEBROWSER_POPUPCOLORLABEL0;ラベル: なし FILEBROWSER_POPUPCOLORLABEL1;ラベル: レッド FILEBROWSER_POPUPCOLORLABEL2;ラベル: イエロー FILEBROWSER_POPUPCOLORLABEL3;ラベル: グリーン @@ -153,7 +152,6 @@ FILEBROWSER_POPUPPROCESS;キューに追加 FILEBROWSER_POPUPPROCESSFAST;キューに追加 (高速書き出し) FILEBROWSER_POPUPPROFILEOPERATIONS;プロファイルの操作 FILEBROWSER_POPUPRANK;ランク -FILEBROWSER_POPUPRANK0;ランクなし FILEBROWSER_POPUPRANK1;ランク 1 * FILEBROWSER_POPUPRANK2;ランク 2 ** FILEBROWSER_POPUPRANK3;ランク 3 *** @@ -3114,7 +3112,6 @@ TP_LOCALLAB_MERNIN;スクリーン TP_LOCALLAB_MERONE;標準 TP_LOCALLAB_MERSAT;彩度 TP_LOCALLAB_MERSEV;ソフトライト(レガシー) -TP_LOCALLAB_MERSEV0;ソフトライト イリュージョン TP_LOCALLAB_MERSEV1;ソフトライト W3C TP_LOCALLAB_MERSEV2;ハードライト TP_LOCALLAB_MERSIX;分割 @@ -4069,4 +4066,81 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files +!GENERAL_OTHER;Other +!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 - Gamut-Munsell +!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° +!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_LENSPROFILESDIR;Lens profiles directory +!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 +!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_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_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_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_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. diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 6283dbe4b..8f828587e 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -833,6 +833,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type +!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -853,7 +854,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. !FILEBROWSER_EXTPROGMENU;Open with !FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) -!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -861,7 +861,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPRANK;Rank -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -869,6 +868,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version +!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 !FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 !FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 @@ -881,6 +881,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -894,6 +895,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -1905,18 +1907,22 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -1936,6 +1942,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1981,6 +1989,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2020,6 +2033,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. @@ -2137,6 +2151,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_LOCALCONTRAST;Local contrast @@ -2159,6 +2174,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2176,6 +2192,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2214,6 +2231,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -2223,6 +2245,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MONINTENT;Default rendering intent @@ -2256,12 +2279,20 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_WBA;White Balance !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_GLOBALPROFILES;Bundled profiles !PROFILEPANEL_MODE_TOOLTIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. @@ -2291,6 +2322,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -2302,6 +2334,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -2403,7 +2442,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Adaptation +!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene +!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2469,6 +2509,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2636,9 +2677,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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? @@ -2646,6 +2689,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -2659,8 +2703,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_GRADIENT_LABEL;Graduated Filter !TP_GRADIENT_STRENGTH;Strength !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !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 @@ -2672,6 +2718,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. !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 @@ -2731,8 +2778,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift -!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). !TP_LABCURVE_CHROMATICITY;Chromaticity !TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. !TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated @@ -2790,7 +2835,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 is used. +!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 @@ -2849,6 +2894,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -2938,13 +2985,15 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3020,6 +3069,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -3108,6 +3162,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3168,11 +3224,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3204,7 +3262,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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;This 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_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. @@ -3253,7 +3311,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3279,7 +3336,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_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 @@ -3473,6 +3530,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3799,6 +3857,16 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple @@ -4063,6 +4131,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_WBALANCE_AUTO_HEADER;Automatic !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_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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 63eaeccc6..08e54048f 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -151,7 +151,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Gedeeltelijk plakken FILEBROWSER_PASTEPROFILE;Plak profiel FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij FILEBROWSER_POPUPCOLORLABEL;Kleur label -FILEBROWSER_POPUPCOLORLABEL0;Label: Geen FILEBROWSER_POPUPCOLORLABEL1;Label: Rood FILEBROWSER_POPUPCOLORLABEL2;Label: Geel FILEBROWSER_POPUPCOLORLABEL3;Label: Groen @@ -168,7 +167,6 @@ FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij FILEBROWSER_POPUPPROCESSFAST;Plaats in verwerkingsrij voor Snelle Export FILEBROWSER_POPUPPROFILEOPERATIONS;Profielbewerkingen FILEBROWSER_POPUPRANK;Waardering -FILEBROWSER_POPUPRANK0;Geen FILEBROWSER_POPUPRANK1;Waardering 1 * FILEBROWSER_POPUPRANK2;Waardering 2 ** FILEBROWSER_POPUPRANK3;Waardering 3 *** @@ -2298,9 +2296,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !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. @@ -2978,15 +2980,19 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -2995,6 +3001,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3017,6 +3025,11 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3055,15 +3068,19 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3076,9 +3093,31 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3092,6 +3131,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_GEN;Settings @@ -3114,6 +3154,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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. @@ -3126,11 +3167,17 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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 @@ -3186,7 +3233,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 is used. +!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 @@ -3245,6 +3292,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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. @@ -3334,13 +3383,15 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3416,6 +3467,11 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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. @@ -3504,6 +3560,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3564,11 +3622,13 @@ 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_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 @@ -3600,7 +3660,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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;This 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_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. @@ -3649,7 +3709,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3675,7 +3734,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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 @@ -3869,6 +3928,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3998,6 +4058,16 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -4088,5 +4158,9 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 06ed63aba..ce9b4322b 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -132,7 +132,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Wklej częściowo FILEBROWSER_PASTEPROFILE;Wklej profil FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta -FILEBROWSER_POPUPCOLORLABEL0;Etykieta: Brak FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Żółta FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona @@ -149,7 +148,6 @@ FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu FILEBROWSER_POPUPPROFILEOPERATIONS;Profile przetwarzania FILEBROWSER_POPUPRANK;Ocena -FILEBROWSER_POPUPRANK0;Usuń ocenę FILEBROWSER_POPUPRANK1;Ocena 1 * FILEBROWSER_POPUPRANK2;Ocena 2 ** FILEBROWSER_POPUPRANK3;Ocena 3 *** @@ -1927,6 +1925,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !DYNPROFILEEDITOR_ENTRY_TOOLTIP;The matching is case insensitive.\nUse the 're:' prefix to enter\na regular expression. !DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule +!EXIFFILTER_PATH;File path !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1939,9 +1938,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version +!FILEBROWSER_POPUPSORTBY;Sort Files !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_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit +!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. @@ -2721,18 +2723,22 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -2747,6 +2753,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera @@ -2777,6 +2785,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance !HISTORY_MSG_WAVBL;Blur levels @@ -2815,6 +2828,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description !ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. !ICCPROFCREATOR_ILL;Illuminant: @@ -2845,6 +2859,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_METADATA;Metadata mode @@ -2857,9 +2872,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_SPOT;Spot removal +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit !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 @@ -2873,10 +2890,16 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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_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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console !PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic) @@ -2891,14 +2914,30 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar !PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips !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_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_ZOOMONSCROLL;Zoom images by scrolling !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. !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 @@ -2915,6 +2954,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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] @@ -2939,6 +2979,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -2978,11 +3019,16 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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_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_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 @@ -2990,6 +3036,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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 @@ -3049,7 +3096,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 is used. +!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 @@ -3108,6 +3155,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -3197,13 +3246,15 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3279,6 +3330,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -3367,6 +3423,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3427,11 +3485,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3463,7 +3523,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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;This 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_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. @@ -3512,7 +3572,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3538,7 +3597,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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 @@ -3732,6 +3791,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3926,6 +3986,16 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_ANCHOR;Anchor +!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_B2;Residual !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. @@ -4079,6 +4149,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. !TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the 'auto white balance'\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by 'computedTemp + computedTemp * bias'. diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 09d3aa790..b3fd4f354 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -131,7 +131,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Colar - parcial FILEBROWSER_PASTEPROFILE;Colar FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho FILEBROWSER_POPUPCOLORLABEL;Etiqueta de cor -FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: nenhuma FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: vermelho FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: amarelo FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: verde @@ -148,7 +147,6 @@ FILEBROWSER_POPUPPROCESS;Colocar na fila FILEBROWSER_POPUPPROCESSFAST;Colocar na fila (exportação rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operações de perfil de processamento FILEBROWSER_POPUPRANK;Classificar -FILEBROWSER_POPUPRANK0;Desclassificar FILEBROWSER_POPUPRANK1;Classificação 1 estrela FILEBROWSER_POPUPRANK2;Classificação 2 estrelas FILEBROWSER_POPUPRANK3;Classificação 3 estrelas @@ -2229,6 +2227,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -2237,10 +2236,13 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!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. @@ -2919,17 +2921,21 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -2938,6 +2944,8 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -2967,6 +2975,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3006,6 +3019,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector @@ -3013,11 +3027,14 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !MAIN_TAB_LOCALLAB;Local !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_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments @@ -3030,8 +3047,22 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3040,6 +3071,14 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location +!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 @@ -3053,6 +3092,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_GEN;Settings @@ -3075,6 +3115,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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. @@ -3093,12 +3134,18 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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_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 @@ -3161,7 +3208,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 is used. +!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 @@ -3220,6 +3267,8 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. @@ -3309,13 +3358,15 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3391,6 +3442,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. @@ -3479,6 +3535,8 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3539,11 +3597,13 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3575,7 +3635,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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;This 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_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. @@ -3624,7 +3684,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3650,7 +3709,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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 @@ -3844,6 +3903,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3978,6 +4038,16 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -4068,5 +4138,9 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index cf386f5ff..b67cd7231 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -135,7 +135,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Colar - parcial FILEBROWSER_PASTEPROFILE;Colar FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho FILEBROWSER_POPUPCOLORLABEL;Etiqueta de Cor -FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Nenhuma FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Vermelha FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarela FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -152,7 +151,6 @@ FILEBROWSER_POPUPPROCESS;Coloque na fila FILEBROWSER_POPUPPROCESSFAST;Coloque na fila (Exportação rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operações de perfil de processamento FILEBROWSER_POPUPRANK;Classificar -FILEBROWSER_POPUPRANK0;Desclassificar FILEBROWSER_POPUPRANK1;Classificação 1 * FILEBROWSER_POPUPRANK2;Classificação 2 ** FILEBROWSER_POPUPRANK3;Classificação 3 *** @@ -2241,11 +2239,15 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !FILEBROWSER_POPUPINSPECT;Inspect +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!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. @@ -2926,17 +2928,21 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -2945,6 +2951,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -2974,6 +2982,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3013,17 +3026,21 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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_FILMNEGATIVE;Film negative +!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_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 @@ -3036,12 +3053,34 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!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 @@ -3055,6 +3094,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_GEN;Settings @@ -3077,6 +3117,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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. @@ -3095,11 +3136,17 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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_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 @@ -3159,7 +3206,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 is used. +!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 @@ -3218,6 +3265,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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. @@ -3307,13 +3356,15 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3389,6 +3440,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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. @@ -3477,6 +3533,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3537,11 +3595,13 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3573,7 +3633,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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;This 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_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. @@ -3622,7 +3682,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3648,7 +3707,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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 @@ -3842,6 +3901,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3979,6 +4039,16 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -4069,5 +4139,9 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 6b0aa6ca0..2e329cc60 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -124,7 +124,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Частичная вставка FILEBROWSER_PASTEPROFILE;Вставить профиль FILEBROWSER_POPUPCANCELJOB;Отменить задание FILEBROWSER_POPUPCOLORLABEL;Цветовая пометка -FILEBROWSER_POPUPCOLORLABEL0;Пометка: нет FILEBROWSER_POPUPCOLORLABEL1;Пометка: Красным FILEBROWSER_POPUPCOLORLABEL2;Пометка: Желтым FILEBROWSER_POPUPCOLORLABEL3;Пометка: Зеленым @@ -141,7 +140,6 @@ FILEBROWSER_POPUPPROCESS;Поместить в очередь на обрабо FILEBROWSER_POPUPPROCESSFAST;Поставить в очередь (Быстрый экспорт) FILEBROWSER_POPUPPROFILEOPERATIONS;Обработка операций профиля FILEBROWSER_POPUPRANK;Рейтинг -FILEBROWSER_POPUPRANK0;Снять FILEBROWSER_POPUPRANK1;Рейтинг 1 * FILEBROWSER_POPUPRANK2;Рейтинг 2 ** FILEBROWSER_POPUPRANK3;Рейтинг 3 *** @@ -1434,6 +1432,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFFILTER_PATH;File path !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1450,13 +1449,16 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. +!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. @@ -2362,17 +2364,21 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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 @@ -2387,6 +2393,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -2428,6 +2436,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -2467,6 +2480,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2526,6 +2540,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !PARTIALPASTE_FILMNEGATIVE;Film negative !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_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2538,11 +2553,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_SPOT;Spot removal +!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !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 @@ -2566,12 +2583,18 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_HISTOGRAM_TOOLTIP;If enabled, the working profile is used for rendering the main histogram and the Navigator panel, otherwise the gamma-corrected output profile is used. !PREFERENCES_INSPECTORWINDOW;Open inspector in own window or fullscreen !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONPROFILE;Default color profile @@ -2592,6 +2615,14 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2609,10 +2640,18 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -2633,6 +2672,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_COLORAPP_CATMOD;Mode !TP_COLORAPP_CATSYMGEN;Automatic Symmetric !TP_COLORAPP_CATSYMSPE;Mixed +!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_DATACIE_TOOLTIP;Affects histograms shown in Color Appearance & Lightning curves. Does not affect RawTherapee's main histogram.\n\nEnabled: show approximate values for J and C, S or M after the CIECAM adjustments.\nDisabled: show L*a*b* values before CIECAM adjustments. !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). @@ -2684,6 +2724,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2794,14 +2835,19 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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_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 @@ -2810,6 +2856,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !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 !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 @@ -2882,7 +2929,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 is used. +!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 @@ -2941,6 +2988,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. @@ -3030,13 +3079,15 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3112,6 +3163,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. @@ -3200,6 +3256,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3260,11 +3318,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3296,7 +3356,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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;This 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_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. @@ -3345,7 +3405,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 @@ -3371,7 +3430,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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 @@ -3565,6 +3624,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3824,6 +3884,16 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 @@ -4074,6 +4144,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. !TP_WBALANCE_TEMPBIAS;AWB temperature bias diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 2c48f771b..2c5d24221 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1194,6 +1194,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type +!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -1208,7 +1209,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -1216,7 +1216,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPOPENINEDITOR;Open in Editor -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -1224,12 +1223,14 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !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 @@ -1241,6 +1242,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open +!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2170,18 +2172,22 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2201,6 +2207,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2246,6 +2254,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2285,6 +2298,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2387,6 +2401,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2406,6 +2421,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2419,6 +2435,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2454,6 +2471,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -2463,6 +2485,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2495,11 +2518,19 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2521,9 +2552,17 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 !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 @@ -2551,6 +2590,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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] @@ -2577,6 +2617,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -2722,9 +2763,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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? @@ -2732,7 +2775,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2742,6 +2788,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_ICM_BPC;Black Point Compensation !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 !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_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. !TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 @@ -2824,7 +2871,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 is used. +!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 @@ -2883,6 +2930,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -2972,13 +3021,15 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3054,6 +3105,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -3142,6 +3198,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3202,11 +3260,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3238,7 +3298,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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;This 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_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. @@ -3287,7 +3347,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3313,7 +3372,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_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 @@ -3507,6 +3566,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3815,6 +3875,16 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -4067,6 +4137,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index f3d71c543..0e5fbdedd 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -135,7 +135,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Delno - prilepi FILEBROWSER_PASTEPROFILE;Prilepi FILEBROWSER_POPUPCANCELJOB;Prekliči ukaz FILEBROWSER_POPUPCOLORLABEL;Barvna oznaka -FILEBROWSER_POPUPCOLORLABEL0;Label: Brez FILEBROWSER_POPUPCOLORLABEL1;Label: Rdeča FILEBROWSER_POPUPCOLORLABEL2;Label: Rumena FILEBROWSER_POPUPCOLORLABEL3;Label: Zelena @@ -152,7 +151,6 @@ FILEBROWSER_POPUPPROCESS;Postavi v čakalno vrsto FILEBROWSER_POPUPPROCESSFAST;Postavi v čakalno vrsto (Hiter izvoz) FILEBROWSER_POPUPPROFILEOPERATIONS;Obdelujem profile FILEBROWSER_POPUPRANK;Rangiraj -FILEBROWSER_POPUPRANK0;Unrank FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2271,10 +2269,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!EXIFFILTER_PATH;File path !FILEBROWSER_POPUPINSPECT;Inspect +!FILEBROWSER_POPUPSORTBY;Sort Files +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!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. @@ -2952,15 +2954,19 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -2969,6 +2975,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -2992,6 +3000,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3031,15 +3044,19 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3052,9 +3069,31 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3068,6 +3107,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_GEN;Settings @@ -3090,6 +3130,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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. @@ -3102,11 +3143,17 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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 @@ -3164,7 +3211,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 is used. +!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 @@ -3223,6 +3270,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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. @@ -3312,13 +3361,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3394,6 +3445,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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. @@ -3482,6 +3538,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3542,11 +3600,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3578,7 +3638,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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;This 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_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. @@ -3627,7 +3687,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3653,7 +3712,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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 @@ -3847,6 +3906,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3977,6 +4037,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -4067,5 +4137,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index de612ad73..855542517 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -105,7 +105,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Klistra in partiell profil FILEBROWSER_PASTEPROFILE;Klistra in profil FILEBROWSER_POPUPCANCELJOB;Avbryt FILEBROWSER_POPUPCOLORLABEL;Färgetikett -FILEBROWSER_POPUPCOLORLABEL0;Label: Ingen FILEBROWSER_POPUPCOLORLABEL1;Label: Röd FILEBROWSER_POPUPCOLORLABEL2;Label: Gul FILEBROWSER_POPUPCOLORLABEL3;Label: Grön @@ -122,7 +121,6 @@ FILEBROWSER_POPUPPROCESS;Flytta till behandlingskön FILEBROWSER_POPUPPROCESSFAST;Lägg till i kön (Snabbexport) FILEBROWSER_POPUPPROFILEOPERATIONS;Profilaktiviteter FILEBROWSER_POPUPRANK;Betyg -FILEBROWSER_POPUPRANK0;Ta bort betyg FILEBROWSER_POPUPRANK1;Betyg 1 * FILEBROWSER_POPUPRANK2;Betyg 2 ** FILEBROWSER_POPUPRANK3;Betyg 3 *** @@ -1728,6 +1726,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile !EXIFFILTER_IMAGETYPE;Image type +!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_PIPELINE;Processing pipeline @@ -1744,12 +1743,15 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. +!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_CURRENT;Current !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help +!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2518,18 +2520,22 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2549,6 +2555,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2594,6 +2602,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2633,6 +2646,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method +!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2721,6 +2735,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_FILMNEGATIVE;Film negative !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 @@ -2735,6 +2750,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2747,6 +2763,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2774,10 +2791,16 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_INSPECTORWINDOW;Open inspector in own window or fullscreen !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor !PREFERENCES_MONPROFILE;Default color profile @@ -2795,11 +2818,19 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2821,9 +2852,17 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 !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 @@ -2842,6 +2881,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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] @@ -2868,6 +2908,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -2936,17 +2977,23 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_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_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_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 @@ -3026,7 +3073,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 is used. +!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 @@ -3085,6 +3132,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -3174,13 +3223,15 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 RT-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;Luma-chro detail threshold +!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3256,6 +3307,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -3344,6 +3400,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3404,11 +3462,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3440,7 +3500,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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;This 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_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. @@ -3489,7 +3549,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3515,7 +3574,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_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 @@ -3709,6 +3768,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3941,6 +4001,16 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_BALCHROM;Equalizer Color !TP_WAVELET_BALLUM;Denoise equalizer White-Black !TP_WAVELET_BL;Blur levels @@ -4069,6 +4139,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic +!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/default b/rtdata/languages/default index 578de8be3..0813a0a2b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -138,7 +138,6 @@ FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial FILEBROWSER_PASTEPROFILE;Paste FILEBROWSER_POPUPCANCELJOB;Cancel job FILEBROWSER_POPUPCOLORLABEL;Color label -FILEBROWSER_POPUPCOLORLABEL0;Label: None FILEBROWSER_POPUPCOLORLABEL1;Label: Red FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -156,7 +155,6 @@ FILEBROWSER_POPUPPROCESS;Put to queue FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations FILEBROWSER_POPUPRANK;Rank -FILEBROWSER_POPUPRANK0;Unrank FILEBROWSER_POPUPRANK1;Rank 1 * FILEBROWSER_POPUPRANK2;Rank 2 ** FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -1443,8 +1441,8 @@ 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_LOCAL_GAMUTMUNSEL;Local - Gamut-Munsell HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - Gamut-Munsell HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1750,11 +1748,11 @@ PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_FILMNEGATIVE;Film negative PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection -PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control PARTIALPASTE_FLATFIELDFILE;Flat-field file +PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata PARTIALPASTE_GRADIENT;Graduated filter PARTIALPASTE_HSVEQUALIZER;HSV equalizer PARTIALPASTE_ICMSETTINGS;Color management settings @@ -1840,7 +1838,6 @@ PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic PREFERENCES_CHUNKSIZE_RGB;RGB processing PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Avoid artifacts -PREFERENCES_WBA;White Balance PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -2009,6 +2006,7 @@ PREFERENCES_TOOLPANEL_TOOL;Tool PREFERENCES_TP_LABEL;Tool panel: PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +PREFERENCES_WBA;White Balance PREFERENCES_WORKFLOW;Layout PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2094,11 +2092,11 @@ SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sl 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_NAME;By Name SORT_BY_DATE;By Date SORT_BY_EXIF;By EXIF -SORT_BY_RANK;By Rank 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 @@ -2283,8 +2281,8 @@ TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode TP_COLORAPP_TCMODE_LIGHTNESS;Lightness TP_COLORAPP_TCMODE_SATUR;Saturation 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_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_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_TONECIE;Use CIECAM for tone mapping TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. TP_COLORAPP_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. @@ -2502,8 +2500,8 @@ 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_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. 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 @@ -2759,6 +2757,8 @@ 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. @@ -2932,11 +2932,11 @@ 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_GAMUTNON;None 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_GAMUTMUNSELL;Munsell only TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) TP_LOCALLAB_GRADANG;Gradient angle TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. @@ -3025,6 +3025,8 @@ TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the 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 @@ -3085,11 +3087,13 @@ TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the 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 @@ -3170,7 +3174,6 @@ 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 @@ -3180,12 +3183,6 @@ 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_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_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 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,12 +3790,12 @@ 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_BANDS;Bands TP_TONE_EQUALIZER_DETAIL;Regularization TP_TONE_EQUALIZER_LABEL;Tone Equalizer TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) From 9e159bbee0716cbbee0f8397567d3681be9ff1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Mon, 17 Jul 2023 23:58:23 +0200 Subject: [PATCH 285/326] Removed potential memory leaks --- rtgui/filmnegative.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 5d46554d2..7c3dd613d 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -376,6 +376,12 @@ FilmNegative::~FilmNegative() for (auto geometry : mouseOverGeometry) { delete geometry; } + delete displayRectWidth; + delete refSpotSize; + delete refSpotButton; + delete refInputLabel; + delete spotSize; + delete spotButton; } From c06ba81a23819073a6ba62d6e19d09a0a19caaa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Tue, 18 Jul 2023 17:39:38 +0200 Subject: [PATCH 286/326] Implemented picker in guiutils as class --- rtgui/guiutils.cc | 80 +++++++++++++++++++++++++++++++++++++++++++++++ rtgui/guiutils.h | 30 +++++++++++++++++- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 18b82fe36..b3125dad0 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1923,3 +1923,83 @@ void BackBuffer::copySurface(Cairo::RefPtr crDest, Gdk::Rectangl crDest->fill(); } } + +SpotPicker::SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey) : + Gtk::Grid(), + _associatedVar(defaultValue), + _spotLabel(Gtk::manage(new Gtk::Label(M(labelKey)))), + _spotSizeSetter(Gtk::manage(selecterSetup())), + _spotButton(Gtk::manage(spotButtonTemplate(buttonKey, buttonTooltip))) + +{ + setExpandAlignProperties(_spotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); + spotSizeHelper->set_name("Spot-Size-Helper"); + setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + this->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(this, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSizeHelper->attach (*_spotSizeSetter, 0, 0, 1, 1); + + this->attach (*_spotButton, 0, 0, 1, 1); + this->attach (*_spotLabel, 1, 0, 1, 1); + this->attach (*spotSizeHelper, 2, 0, 1, 1); + _spotSizeSetter->signal_changed().connect( sigc::mem_fun(*this, &SpotPicker::spotSizeChanged)); +} +SpotPicker::~SpotPicker() +{ + +} + +MyComboBoxText* SpotPicker::selecterSetup() +{ + MyComboBoxText* spotSize(new MyComboBoxText ()); + setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSize->append ("2"); + if (_associatedVar == 2) { + spotSize->set_active(0); + } + + spotSize->append ("4"); + + if (_associatedVar == 4) { + spotSize->set_active(1); + } + + spotSize->append ("8"); + + if (_associatedVar == 8) { + spotSize->set_active(2); + } + + spotSize->append ("16"); + + if (_associatedVar == 16) { + spotSize->set_active(3); + } + + spotSize->append ("32"); + + if (_associatedVar == 32) { + spotSize->set_active(4); + } + return spotSize; +} + +Gtk::ToggleButton* SpotPicker::spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) +{ + Gtk::ToggleButton *spotButton(new Gtk::ToggleButton(key)); + setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + spotButton->get_style_context()->add_class("independent"); + spotButton->set_tooltip_text(tooltip); + spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); + return spotButton; +} + +void SpotPicker::spotSizeChanged() +{ + _associatedVar = atoi(_spotSizeSetter->get_active_text().c_str()); +} \ No newline at end of file diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 152b626de..6306c5b4b 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -689,7 +689,35 @@ public: } }; -inline void setActiveTextOrIndex (Gtk::ComboBoxText& comboBox, const Glib::ustring& text, int index) +/** + * @brief A gui element for picking spots on an image + */ +class SpotPicker : public Gtk::Grid +{ + public: + int _associatedVar; + Gtk::Label* const _spotLabel; + MyComboBoxText* const _spotSizeSetter; + Gtk::ToggleButton* const _spotButton; + + SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); + ~SpotPicker(); + inline Gtk::TreeModel::iterator get_active() + { + return _spotSizeSetter->get_active(); + } + void set_active(bool b) + { + _spotButton->set_active(b); + } + + protected: + MyComboBoxText* selecterSetup(); + static Gtk::ToggleButton *spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip); + void spotSizeChanged(); +}; + +inline void setActiveTextOrIndex(Gtk::ComboBoxText &comboBox, const Glib::ustring &text, int index) { bool valueSet = false; if (!text.empty()) { From 1e6ef3e2a2f72b6bfe7e37939cff736ab82b8463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Tue, 18 Jul 2023 17:53:27 +0200 Subject: [PATCH 287/326] Implemented SpotPicker using the guiutils class in filmnegative --- rtgui/filmnegative.cc | 158 +++++++++--------------------------------- rtgui/filmnegative.h | 14 ++-- 2 files changed, 39 insertions(+), 133 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 7c3dd613d..c61134df9 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -190,77 +190,6 @@ void rgb2temp(const RGB &refOut, double &outLev, double &temp, double &green) } -} -MyComboBoxText* spotSetup(int const &associatedVar) -{ - MyComboBoxText* spotSize(Gtk::manage (new MyComboBoxText ())); - setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - spotSize->append ("2"); - if (associatedVar == 2) { - spotSize->set_active(0); - } - - spotSize->append ("4"); - - if (associatedVar == 4) { - spotSize->set_active(1); - } - - spotSize->append ("8"); - - if (associatedVar == 8) { - spotSize->set_active(2); - } - - spotSize->append ("16"); - - if (associatedVar == 16) { - spotSize->set_active(3); - } - - spotSize->append ("32"); - - if (associatedVar == 32) { - spotSize->set_active(4); - } - return spotSize; -} - -Gtk::ToggleButton* spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) -{ - Gtk::ToggleButton *spotButton(Gtk::manage(new Gtk::ToggleButton(key))); - setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - spotButton->get_style_context()->add_class("independent"); - spotButton->set_tooltip_text(tooltip); - spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); - return spotButton; -} - -Gtk::Grid* pickerTemplate( Gtk::Label* const &spotLabel, Gtk::ToggleButton* const &spotButton, MyComboBoxText* const &spotSizeSetter) -{ - // refInputLabel->set_justify(Gtk::Justification::JUSTIFY_CENTER); - // refInputLabel->set_line_wrap(true); - - // TODO make spot size configurable ? - - setExpandAlignProperties(spotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - - Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); - spotSizeHelper->set_name("Spot-Size-Helper"); - setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - - - Gtk::Grid* spotGrid(Gtk::manage(new Gtk::Grid())); - spotGrid->get_style_context()->add_class("grid-spacing"); - setExpandAlignProperties(spotGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - - spotSizeHelper->attach (*spotSizeSetter, 0, 0, 1, 1); - - spotGrid->attach (*spotButton, 0, 0, 1, 1); - spotGrid->attach (*spotLabel, 1, 0, 1, 1); - spotGrid->attach (*spotSizeHelper, 2, 0, 1, 1); - return spotGrid; } FilmNegative::FilmNegative() : @@ -280,14 +209,10 @@ FilmNegative::FilmNegative() : greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 0.01, 1.5)), // master exponent (green channel) redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent - spotButton(spotButtonTemplate(M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"))), - spotWidth(DEFAULT_SPOT_WIDTH), - spotSize(spotSetup(spotWidth)), + picker(Gtk::manage(new SpotPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"), M("TP_FILMNEGATIVE_PICK_SIZE")))), refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), - refSpotButton(spotButtonTemplate(M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"))), - refSpotWidth(DEFAULT_SPOT_WIDTH), - refSpotSize(spotSetup(refSpotWidth)), - displayRectWidth(&spotWidth), + refPicker(Gtk::manage(new SpotPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"), M("TP_FILMNEGATIVE_REF_SIZE")))), + displayRectWidth(&(picker->_associatedVar)), 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 @@ -313,14 +238,10 @@ FilmNegative::FilmNegative() : colorSpace->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::colorSpaceChanged)); colorSpace->show(); - Gtk::Label *sLabel(Gtk::manage(new Gtk::Label(M("TP_FILMNEGATIVE_PICK_SIZE")))); - setExpandAlignProperties(sLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - Gtk::Grid* spotGrid = pickerTemplate(sLabel, spotButton, spotSize); - pack_start(*spotGrid, Gtk::PACK_SHRINK, 0); + pack_start(*picker, Gtk::PACK_SHRINK, 0); // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); @@ -339,16 +260,11 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - Gtk::Label *negWBSpotLabel(Gtk::manage(new Gtk::Label(M("TP_FILMNEGATIVE_REF_SIZE")))); - setExpandAlignProperties(negWBSpotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - Gtk::Grid *refSpotGrid = pickerTemplate(negWBSpotLabel, refSpotButton, refSpotSize); - pack_start(*refSpotGrid, Gtk::PACK_SHRINK, 0); + pack_start(*refPicker, Gtk::PACK_SHRINK, 0); - spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - spotSize->signal_changed().connect( sigc::mem_fun(*this, &FilmNegative::spotSizeChanged) ); + picker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - refSpotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); - refSpotSize->signal_changed().connect(sigc::mem_fun(*this, &FilmNegative::refSpotChanged)); + refPicker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); // Editing geometry; create the spot rectangle // TODO: Change behaviour to match that of the white balance spot picker (rectangle disappears behind right toolbar) @@ -376,12 +292,6 @@ FilmNegative::~FilmNegative() for (auto geometry : mouseOverGeometry) { delete geometry; } - delete displayRectWidth; - delete refSpotSize; - delete refSpotButton; - delete refInputLabel; - delete spotSize; - delete spotButton; } @@ -522,8 +432,8 @@ void FilmNegative::setBatchMode(bool batchMode) ToolPanel::setBatchMode(batchMode); if (batchMode) { - removeIfThere(this, spotButton, false); - removeIfThere(this, refSpotButton, false); + removeIfThere(this, picker->_spotButton, false); + removeIfThere(this, refPicker->_spotButton, false); colorSpace->append(M("GENERAL_UNCHANGED")); colorSpace->set_active_text(M("GENERAL_UNCHANGED")); redRatio->showEditedCB(); @@ -644,7 +554,7 @@ bool FilmNegative::button1Pressed(int modifierKey) EditSubscriber::action = EditSubscriber::Action::NONE; if (listener) { - if (spotButton->get_active()) { + if (picker->get_active()) { refSpotCoords.push_back(provider->posImage); @@ -654,8 +564,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], spotWidth, ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], spotWidth, ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker->_associatedVar, ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], picker->_associatedVar, ref2, dummy)) { disableListener(); @@ -687,7 +597,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } - } else if (refSpotButton->get_active()) { + } else if (refPicker->get_active()) { disableListener(); @@ -701,7 +611,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, refSpotWidth, refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refPicker->_associatedVar, refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); @@ -765,17 +675,17 @@ void FilmNegative::switchOffEditMode() { refSpotCoords.clear(); unsubscribe(); - spotButton->set_active(false); - refSpotButton->set_active(false); + picker->set_active(false); + refPicker->set_active(false); } void FilmNegative::editToggled() { - if (spotButton->get_active()) { + if (picker->get_active()) { - refSpotButton->set_active(false); + refPicker->set_active(false); refSpotCoords.clear(); - displayRectWidth = &spotWidth; + displayRectWidth = &(picker->_associatedVar); // if (spotlistener) // spotlistener->spotNegRequested(spotWidth); @@ -797,11 +707,11 @@ void FilmNegative::editToggled() void FilmNegative::refSpotToggled() { - if (refSpotButton->get_active()) { + if (refPicker->get_active()) { - spotButton->set_active(false); + picker->set_active(false); refSpotCoords.clear(); - displayRectWidth = &refSpotWidth; + displayRectWidth = &(refPicker->_associatedVar); // if (spotlistener) // spotlistener->spotNegRequested(refSpotWidth); @@ -821,17 +731,17 @@ void FilmNegative::refSpotToggled() } } -void FilmNegative::spotSizeChanged () -{ - spotWidth = atoi(spotSize->get_active_text().c_str()); +// void FilmNegative::spotSizeChanged () +// { +// spotWidth = atoi(spotSize->get_active_text().c_str()); - // if (spotlistener) - // spotlistener->spotNegRequested(spotWidth); -} +// // if (spotlistener) +// // spotlistener->spotNegRequested(spotWidth); +// } -void FilmNegative::refSpotChanged() -{ - refSpotWidth = atoi(refSpotSize->get_active_text().c_str()); - // if (spotlistener) - // spotlistener->spotNegRequested(refSpotWidth); -} +// void FilmNegative::refSpotChanged() +// { +// refSpotWidth = atoi(refSpotSize->get_active_text().c_str()); +// // if (spotlistener) +// // spotlistener->spotNegRequested(refSpotWidth); +// } diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 98242d636..20ddfbb31 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -97,8 +97,8 @@ private: void readOutputSliders(RGB &refOutput); void writeOutputSliders(const RGB &refOutput); - void spotSizeChanged(); - void refSpotChanged(); + // void spotSizeChanged(); + // void refSpotChanged(); // ColorTemp value corresponding to neutral RGB multipliers (1,1,1). Should be around 6500K. const rtengine::ColorTemp NEUTRAL_TEMP; @@ -137,15 +137,11 @@ private: #define DEFAULT_SPOT_WIDTH 8 - Gtk::ToggleButton* const spotButton; - int spotWidth; - MyComboBoxText* const spotSize; + SpotPicker* const picker; Gtk::Label* const refInputLabel; - Gtk::ToggleButton* const refSpotButton; - int refSpotWidth; - MyComboBoxText* const refSpotSize; - + SpotPicker* const refPicker; + int* displayRectWidth; Adjuster* const outputLevel; From 2fd18f02846d56022874e5fcf80d6d781e0a9fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Tue, 18 Jul 2023 17:59:25 +0200 Subject: [PATCH 288/326] Added bug description --- rtgui/filmnegative.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index c61134df9..b37216479 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -262,6 +262,8 @@ FilmNegative::FilmNegative() : pack_start(*refPicker, Gtk::PACK_SHRINK, 0); + //BUG: After selecting a spot for the first time after the button is toggled, picking is still possible, while the button is NOT toggled. After picking for the second time picking is only possible after retoggleing the button + picker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); refPicker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); From 0ab53c39d16a02c0f05cc155752685b34185ae4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Tue, 18 Jul 2023 18:36:54 +0200 Subject: [PATCH 289/326] Resolved bug affecting the negative spot pickers --- rtgui/filmnegative.cc | 2 -- rtgui/guiutils.h | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index b37216479..c61134df9 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -262,8 +262,6 @@ FilmNegative::FilmNegative() : pack_start(*refPicker, Gtk::PACK_SHRINK, 0); - //BUG: After selecting a spot for the first time after the button is toggled, picking is still possible, while the button is NOT toggled. After picking for the second time picking is only possible after retoggleing the button - picker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); refPicker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 6306c5b4b..b6ccddc75 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -702,9 +702,9 @@ class SpotPicker : public Gtk::Grid SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); ~SpotPicker(); - inline Gtk::TreeModel::iterator get_active() + inline bool get_active() { - return _spotSizeSetter->get_active(); + return _spotButton->get_active(); } void set_active(bool b) { From c79b75cea8707284027696c103964fa09ad8e70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Thu, 20 Jul 2023 12:38:17 +0200 Subject: [PATCH 290/326] Removed unnecesarry references --- rtgui/filmnegative.cc | 44 +++++++++++++++---------------- rtgui/filmnegative.h | 4 +-- rtgui/guiutils.cc | 61 +++++++++++++++++++++++-------------------- rtgui/guiutils.h | 13 ++++----- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index c61134df9..f21ed8d9f 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -209,10 +209,10 @@ FilmNegative::FilmNegative() : greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 0.01, 1.5)), // master exponent (green channel) redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 5, 0.01, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 5, 0.01, (1.29 / 1.5))), // ratio of blue exponent to master exponent - picker(Gtk::manage(new SpotPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"), M("TP_FILMNEGATIVE_PICK_SIZE")))), + picker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"), M("TP_FILMNEGATIVE_PICK_SIZE")), refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), - refPicker(Gtk::manage(new SpotPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"), M("TP_FILMNEGATIVE_REF_SIZE")))), - displayRectWidth(&(picker->_associatedVar)), + refPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"), M("TP_FILMNEGATIVE_REF_SIZE")), + displayRectWidth(&(picker._associatedVar)), 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 @@ -241,7 +241,7 @@ FilmNegative::FilmNegative() : pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); - pack_start(*picker, Gtk::PACK_SHRINK, 0); + pack_start(picker, Gtk::PACK_SHRINK, 0); // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); @@ -260,11 +260,11 @@ FilmNegative::FilmNegative() : pack_start(*blueBalance, Gtk::PACK_SHRINK, 0); pack_start(*greenBalance, Gtk::PACK_SHRINK, 0); - pack_start(*refPicker, Gtk::PACK_SHRINK, 0); + pack_start(refPicker, Gtk::PACK_SHRINK, 0); - picker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); + picker._spotButton.signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - refPicker->_spotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); + refPicker._spotButton.signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); // Editing geometry; create the spot rectangle // TODO: Change behaviour to match that of the white balance spot picker (rectangle disappears behind right toolbar) @@ -432,8 +432,8 @@ void FilmNegative::setBatchMode(bool batchMode) ToolPanel::setBatchMode(batchMode); if (batchMode) { - removeIfThere(this, picker->_spotButton, false); - removeIfThere(this, refPicker->_spotButton, false); + removeIfThere(this, &picker._spotButton, false); + removeIfThere(this, &refPicker._spotButton, false); colorSpace->append(M("GENERAL_UNCHANGED")); colorSpace->set_active_text(M("GENERAL_UNCHANGED")); redRatio->showEditedCB(); @@ -554,7 +554,7 @@ bool FilmNegative::button1Pressed(int modifierKey) EditSubscriber::action = EditSubscriber::Action::NONE; if (listener) { - if (picker->get_active()) { + if (picker.get_active()) { refSpotCoords.push_back(provider->posImage); @@ -564,8 +564,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker->_associatedVar, ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], picker->_associatedVar, ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker._associatedVar, ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], picker._associatedVar, ref2, dummy)) { disableListener(); @@ -597,7 +597,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } - } else if (refPicker->get_active()) { + } else if (refPicker.get_active()) { disableListener(); @@ -611,7 +611,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, refPicker->_associatedVar, refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refPicker._associatedVar, refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); @@ -675,17 +675,17 @@ void FilmNegative::switchOffEditMode() { refSpotCoords.clear(); unsubscribe(); - picker->set_active(false); - refPicker->set_active(false); + picker.set_active(false); + refPicker.set_active(false); } void FilmNegative::editToggled() { - if (picker->get_active()) { + if (picker.get_active()) { - refPicker->set_active(false); + refPicker.set_active(false); refSpotCoords.clear(); - displayRectWidth = &(picker->_associatedVar); + displayRectWidth = &(picker._associatedVar); // if (spotlistener) // spotlistener->spotNegRequested(spotWidth); @@ -707,11 +707,11 @@ void FilmNegative::editToggled() void FilmNegative::refSpotToggled() { - if (refPicker->get_active()) { + if (refPicker.get_active()) { - picker->set_active(false); + picker.set_active(false); refSpotCoords.clear(); - displayRectWidth = &(refPicker->_associatedVar); + displayRectWidth = &(refPicker._associatedVar); // if (spotlistener) // spotlistener->spotNegRequested(refSpotWidth); diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 20ddfbb31..02d032f3c 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -137,10 +137,10 @@ private: #define DEFAULT_SPOT_WIDTH 8 - SpotPicker* const picker; + SpotPicker picker; Gtk::Label* const refInputLabel; - SpotPicker* const refPicker; + SpotPicker refPicker; int* displayRectWidth; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index b3125dad0..e3e52fc23 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1927,14 +1927,12 @@ void BackBuffer::copySurface(Cairo::RefPtr crDest, Gdk::Rectangl SpotPicker::SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey) : Gtk::Grid(), _associatedVar(defaultValue), - _spotLabel(Gtk::manage(new Gtk::Label(M(labelKey)))), - _spotSizeSetter(Gtk::manage(selecterSetup())), - _spotButton(Gtk::manage(spotButtonTemplate(buttonKey, buttonTooltip))) + _spotLabel(labelSetup(labelKey)), + _spotSizeSetter(new MyComboBoxText(selecterSetup())), + _spotButton(spotButtonTemplate(buttonKey, buttonTooltip)) { - setExpandAlignProperties(_spotLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - - Gtk::Grid* spotSizeHelper(Gtk::manage(new Gtk::Grid())); + Gtk::Grid* spotSizeHelper = new Gtk::Grid(); spotSizeHelper->set_name("Spot-Size-Helper"); setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -1943,59 +1941,66 @@ SpotPicker::SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, G spotSizeHelper->attach (*_spotSizeSetter, 0, 0, 1, 1); - this->attach (*_spotButton, 0, 0, 1, 1); - this->attach (*_spotLabel, 1, 0, 1, 1); + this->attach (_spotButton, 0, 0, 1, 1); + this->attach (_spotLabel, 1, 0, 1, 1); this->attach (*spotSizeHelper, 2, 0, 1, 1); _spotSizeSetter->signal_changed().connect( sigc::mem_fun(*this, &SpotPicker::spotSizeChanged)); } SpotPicker::~SpotPicker() { - + delete _spotSizeSetter; } -MyComboBoxText* SpotPicker::selecterSetup() +Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) { - MyComboBoxText* spotSize(new MyComboBoxText ()); - setExpandAlignProperties(spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Label label(key); + setExpandAlignProperties(&label, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + return label; +} - spotSize->append ("2"); +MyComboBoxText SpotPicker::selecterSetup() +{ + MyComboBoxText spotSize = MyComboBoxText(); + setExpandAlignProperties(&spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotSize.append ("2"); if (_associatedVar == 2) { - spotSize->set_active(0); + spotSize.set_active(0); } - spotSize->append ("4"); + spotSize.append ("4"); if (_associatedVar == 4) { - spotSize->set_active(1); + spotSize.set_active(1); } - spotSize->append ("8"); + spotSize.append ("8"); if (_associatedVar == 8) { - spotSize->set_active(2); + spotSize.set_active(2); } - spotSize->append ("16"); + spotSize.append ("16"); if (_associatedVar == 16) { - spotSize->set_active(3); + spotSize.set_active(3); } - spotSize->append ("32"); + spotSize.append ("32"); if (_associatedVar == 32) { - spotSize->set_active(4); + spotSize.set_active(4); } return spotSize; } -Gtk::ToggleButton* SpotPicker::spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) +Gtk::ToggleButton SpotPicker::spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) { - Gtk::ToggleButton *spotButton(new Gtk::ToggleButton(key)); - setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - spotButton->get_style_context()->add_class("independent"); - spotButton->set_tooltip_text(tooltip); - spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); + Gtk::ToggleButton spotButton = Gtk::ToggleButton(key); + setExpandAlignProperties(&spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + spotButton.get_style_context()->add_class("independent"); + spotButton.set_tooltip_text(tooltip); + spotButton.set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); return spotButton; } diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index b6ccddc75..77cbdbd93 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -696,24 +696,25 @@ class SpotPicker : public Gtk::Grid { public: int _associatedVar; - Gtk::Label* const _spotLabel; + Gtk::Label _spotLabel; MyComboBoxText* const _spotSizeSetter; - Gtk::ToggleButton* const _spotButton; + Gtk::ToggleButton _spotButton; SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); ~SpotPicker(); inline bool get_active() { - return _spotButton->get_active(); + return _spotButton.get_active(); } void set_active(bool b) { - _spotButton->set_active(b); + _spotButton.set_active(b); } protected: - MyComboBoxText* selecterSetup(); - static Gtk::ToggleButton *spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip); + static Gtk::Label labelSetup(Glib::ustring const &key); + MyComboBoxText selecterSetup(); + static Gtk::ToggleButton spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip); void spotSizeChanged(); }; From bc16e3243f420c12db256465b9dcf7f900416f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Thu, 20 Jul 2023 13:47:29 +0200 Subject: [PATCH 291/326] Added ':' after 'Size' for spot selecter label --- rtdata/languages/default | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 0813a0a2b..73a0ae1cc 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2496,11 +2496,11 @@ TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picki TP_FILMNEGATIVE_LABEL;Film Negative TP_FILMNEGATIVE_OUT_LEVEL;Output level TP_FILMNEGATIVE_PICK;Pick neutral spots -TP_FILMNEGATIVE_PICK_SIZE;Size +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_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? From bfd8b5704e03aa1e72d25105e4f39ef88369f776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Thu, 20 Jul 2023 14:47:07 +0200 Subject: [PATCH 292/326] Generated translation diffs --- rtdata/languages/Catala | 4 ++-- rtdata/languages/Chinese (Simplified) | 4 ++-- rtdata/languages/Czech | 4 ++-- rtdata/languages/Dansk | 4 ++-- rtdata/languages/Deutsch | 4 ++-- rtdata/languages/English (UK) | 4 ++-- rtdata/languages/English (US) | 4 ++-- rtdata/languages/Espanol (Castellano) | 4 ++-- rtdata/languages/Espanol (Latin America) | 4 ++-- rtdata/languages/Francais | 4 ++-- rtdata/languages/Italiano | 4 ++-- rtdata/languages/Japanese | 4 ++-- rtdata/languages/Magyar | 4 ++-- rtdata/languages/Nederlands | 4 ++-- rtdata/languages/Polish | 4 ++-- rtdata/languages/Portugues | 4 ++-- rtdata/languages/Portugues (Brasil) | 4 ++-- rtdata/languages/Russian | 4 ++-- rtdata/languages/Serbian (Cyrilic Characters) | 4 ++-- rtdata/languages/Slovenian | 4 ++-- rtdata/languages/Swedish | 4 ++-- 21 files changed, 42 insertions(+), 42 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 623776056..1cf03a97b 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -2712,11 +2712,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index c1f80886b..3ca7244a0 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -3319,8 +3319,8 @@ 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_FILMNEGATIVE_PICK_SIZE;Size: +!TP_FILMNEGATIVE_REF_SIZE;Size: !TP_FLATFIELD_FROMMETADATA;From Metadata !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 8d9100d85..a99599a38 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -3247,10 +3247,10 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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_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 diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 7299c6f5e..0c3330429 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -3147,10 +3147,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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_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 diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 82463fe75..397d41c7b 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -4195,8 +4195,8 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - !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_FILMNEGATIVE_PICK_SIZE;Size -!TP_FILMNEGATIVE_REF_SIZE;Size +!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 diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 695cebaf3..2724ff3b8 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -2612,11 +2612,11 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 96a6a9b8c..a770c9103 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -2497,11 +2497,11 @@ !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index 7a176fec1..50c45b2b6 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -4110,8 +4110,8 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !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_FILMNEGATIVE_PICK_SIZE;Size -!TP_FILMNEGATIVE_REF_SIZE;Size +!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 diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index 151111900..ccf70ac84 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -3202,11 +3202,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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 diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 9d875900c..53771ff8f 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -3908,8 +3908,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_CROP_GTCENTEREDSQUARE;Centered square !TP_CROP_PPI;PPI !TP_DEHAZE_SATURATION;Saturation -!TP_FILMNEGATIVE_PICK_SIZE;Size -!TP_FILMNEGATIVE_REF_SIZE;Size +!TP_FILMNEGATIVE_PICK_SIZE;Size: +!TP_FILMNEGATIVE_REF_SIZE;Size: !TP_FLATFIELD_FROMMETADATA;From Metadata !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 28ba9d01b..aeed90a44 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -2764,11 +2764,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index ab82ecf32..36555b955 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -4109,8 +4109,8 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !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_FILMNEGATIVE_PICK_SIZE;Size -!TP_FILMNEGATIVE_REF_SIZE;Size +!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 diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 8f828587e..b0c33bb6a 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -2677,11 +2677,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 08e54048f..ff4ae66f6 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -3167,10 +3167,10 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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_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 diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index ce9b4322b..d58ecf454 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -3019,10 +3019,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_OUT_LEVEL;Output level -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_SIZE;Size: !TP_FILMNEGATIVE_REF_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. !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_FLATFIELD_FROMMETADATA;From Metadata diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index b3fd4f354..03b160b3a 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -3134,11 +3134,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index b67cd7231..2a4d1e4cf 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -3136,10 +3136,10 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_SIZE;Size +!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_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 diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 2e329cc60..15c833742 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -2835,11 +2835,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_SIZE;Size: !TP_FILMNEGATIVE_REF_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. !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_FLATFIELD_CLIPCONTROL;Clip control diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 2c5d24221..179759476 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -2763,11 +2763,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_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? diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index 0e5fbdedd..f47368abb 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -3143,10 +3143,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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_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 diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 855542517..a1b70fbb5 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -2977,11 +2977,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_OUT_LEVEL;Output level !TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size +!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_SIZE;Size: !TP_FILMNEGATIVE_REF_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. !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. From 688c6d87ea74c3323396e964e66fa4ac7c017499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Fri, 21 Jul 2023 10:29:03 +0200 Subject: [PATCH 293/326] Removed translation diffs from language files --- rtdata/languages/Catala | 90 ++---------------- rtdata/languages/Chinese (Simplified) | 88 ++--------------- rtdata/languages/Czech | 88 ++--------------- rtdata/languages/Dansk | 88 ++--------------- rtdata/languages/Deutsch | 85 +---------------- rtdata/languages/English (UK) | 94 +++---------------- rtdata/languages/English (US) | 94 +++---------------- rtdata/languages/Espanol (Castellano) | 84 +---------------- rtdata/languages/Espanol (Latin America) | 88 ++--------------- rtdata/languages/Francais | 82 +--------------- rtdata/languages/Italiano | 88 ++--------------- rtdata/languages/Japanese | 80 +--------------- rtdata/languages/Magyar | 92 ++---------------- rtdata/languages/Nederlands | 88 ++--------------- rtdata/languages/Polish | 88 ++--------------- rtdata/languages/Portugues | 88 ++--------------- rtdata/languages/Portugues (Brasil) | 88 ++--------------- rtdata/languages/Russian | 88 ++--------------- rtdata/languages/Serbian (Cyrilic Characters) | 88 ++--------------- rtdata/languages/Slovenian | 88 ++--------------- rtdata/languages/Swedish | 88 ++--------------- 21 files changed, 144 insertions(+), 1701 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 1cf03a97b..4485966ff 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -907,7 +907,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -924,12 +923,14 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green !FILEBROWSER_POPUPCOLORLABEL4;Label: Blue !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect +!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -937,7 +938,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 !FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 !FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 @@ -950,7 +950,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -964,7 +963,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -1973,22 +1971,18 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2008,8 +2002,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2055,11 +2047,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2099,7 +2086,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. @@ -2213,7 +2199,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_LOCALLAB;Local Adjustments @@ -2235,7 +2220,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2253,7 +2237,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -2292,11 +2275,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -2306,7 +2284,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2339,20 +2316,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_WBA;White Balance !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_GLOBALPROFILES;Bundled profiles !PROFILEPANEL_MODE_TOOLTIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. @@ -2381,19 +2350,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. !SOFTPROOF_GAMUTCHECK_TOOLTIP;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 @@ -2488,8 +2449,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing +!TP_COLORAPP_CIECAT_DEGREE;Adaptation !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2555,7 +2515,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2712,11 +2671,9 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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? @@ -2724,7 +2681,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -2738,10 +2694,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_GRADIENT_LABEL;Graduated Filter !TP_GRADIENT_STRENGTH;Strength !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. -!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !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 @@ -2753,7 +2707,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. !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 @@ -2844,7 +2797,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_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 is used. !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,8 +2856,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -2994,15 +2945,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3078,11 +3027,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. @@ -3171,8 +3115,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3233,13 +3175,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3271,7 +3211,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_MASKLC_TOOLTIP;This 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. @@ -3320,6 +3260,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3345,7 +3286,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_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 @@ -3539,7 +3480,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -3866,16 +3806,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 @@ -4130,10 +4060,6 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_WBALANCE_AUTO_HEADER;Automatic !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_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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 3ca7244a0..e4e89fed2 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -143,6 +143,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 FILEBROWSER_PASTEPROFILE;粘贴 FILEBROWSER_POPUPCANCELJOB;取消任务 FILEBROWSER_POPUPCOLORLABEL;色彩标签 +FILEBROWSER_POPUPCOLORLABEL0;标签:无 FILEBROWSER_POPUPCOLORLABEL1;标签:红 FILEBROWSER_POPUPCOLORLABEL2;标签:黄 FILEBROWSER_POPUPCOLORLABEL3;标签:绿 @@ -160,6 +161,7 @@ FILEBROWSER_POPUPPROCESS;放入队列 FILEBROWSER_POPUPPROCESSFAST;放入队列(快速导出) FILEBROWSER_POPUPPROFILEOPERATIONS;后期档案操作 FILEBROWSER_POPUPRANK;评级 +FILEBROWSER_POPUPRANK0;取消评级 FILEBROWSER_POPUPRANK1;评1星 FILEBROWSER_POPUPRANK2;评2星 FILEBROWSER_POPUPRANK3;评3星 @@ -2434,10 +2436,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_OTHER;Other !HISTORY_MSG_112;--unused-- !HISTORY_MSG_137;Black level - Green 1 !HISTORY_MSG_138;Black level - Red @@ -3060,17 +3058,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_BLURWAV;Blur luminance !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_EDGEFFECT;Edge Attenuation response -!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata !HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output !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_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries @@ -3085,8 +3079,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3106,11 +3098,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3145,7 +3132,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description !ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. @@ -3213,11 +3199,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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. -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_RETINEX;Retinex -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic !PREFERENCES_CIE;Ciecam !PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder @@ -3227,38 +3210,16 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID !PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Bypass output profile !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_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_LENSPROFILESDIR;Lens profiles directory -!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 !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser !SAMPLEFORMAT_1;8-bit unsigned !SAMPLEFORMAT_2;16-bit unsigned !SAMPLEFORMAT_4;24-bit LogLuv !SAMPLEFORMAT_8;32-bit LogLuv -!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. !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -3282,7 +3243,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. !TP_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_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_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. @@ -3300,7 +3260,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_COLORAPP_MOD16;CAM16 !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_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. @@ -3319,12 +3278,7 @@ 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 -!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 @@ -3336,7 +3290,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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. !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_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. !TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. @@ -3406,7 +3359,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).\nMunsell correction always disabled when Jz or CAM16 is used. !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 @@ -3436,8 +3389,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 !TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz !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_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_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. @@ -3493,11 +3444,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_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 RT-spot size: 128x128. !TP_LOCALLAB_DETAILFRA;Edge detection - DCT -!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DETAILTHR;Luma-chro detail threshold !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. @@ -3532,11 +3481,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_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. @@ -3600,8 +3544,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_LEVELBLUR;Maximum blur 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. @@ -3644,10 +3586,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_LUM;LL - CC -!TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 !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_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_MASKCOM;Common Color Mask @@ -3676,7 +3616,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_MASKLC_TOOLTIP;This 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. @@ -3724,6 +3664,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 @@ -3742,7 +3683,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_NLFRA;Non-local Means: Luminance +!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_NLPAT;Maximum patch size !TP_LOCALLAB_NLRAD;Maximum radius size @@ -3860,7 +3801,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !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_TE_PIVOT;Pivot (Ev) !TP_LOCALLAB_THRES;Threshold structure !TP_LOCALLAB_THRESDELTAE;ΔE scope threshold !TP_LOCALLAB_THRESRETI;Threshold @@ -4026,16 +3966,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_RETINEX_VIEW_TRAN;Transmission - Auto !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 @@ -4147,10 +4077,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键:- !TP_WBALANCE_LAMP_HEADER;Lamp !TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 -!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_SOLUX47;Solux 4700K (vendor) !TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) !TP_WBALANCE_STUDLABEL;Correlation factor: %1 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index a99599a38..61e6af4bf 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -182,6 +182,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Vložit - částečně FILEBROWSER_PASTEPROFILE;Vložit FILEBROWSER_POPUPCANCELJOB;Zrušit úlohu FILEBROWSER_POPUPCOLORLABEL;Barevný štítek +FILEBROWSER_POPUPCOLORLABEL0;Štítek: Žádný FILEBROWSER_POPUPCOLORLABEL1;Štítek: Červený FILEBROWSER_POPUPCOLORLABEL2;Štítek: Žlutý FILEBROWSER_POPUPCOLORLABEL3;Štítek: Zelený @@ -198,6 +199,7 @@ FILEBROWSER_POPUPPROCESS;Vložit do fronty FILEBROWSER_POPUPPROCESSFAST;Vložit do fronty (Rychlý export) FILEBROWSER_POPUPPROFILEOPERATIONS;Operace profilů zpracování FILEBROWSER_POPUPRANK;Hodnocení +FILEBROWSER_POPUPRANK0;Odstranit hodnocení FILEBROWSER_POPUPRANK1;Hodnocení 1 * FILEBROWSER_POPUPRANK2;Hodnocení 2 ** FILEBROWSER_POPUPRANK3;Hodnocení 3 *** @@ -2422,13 +2424,9 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !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. @@ -3101,19 +3099,15 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_COMPLEX;Wavelet complexity !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation -!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 @@ -3121,8 +3115,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -!HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3136,11 +3128,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_RESIZE_SHORTEDGE;Resize - Short Edge !HISTORY_MSG_SPOT;Spot removal !HISTORY_MSG_SPOT_ENTRY;Spot removal - Point modif. -!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_WAVCHR;Blur levels - blur chroma !HISTORY_MSG_WAVDENLH;Level 5 !HISTORY_MSG_WAVDENOISE;Local contrast @@ -3160,18 +3147,14 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_WAVSTREND;Strength soft !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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_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 @@ -3184,31 +3167,9 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3222,7 +3183,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_GEN;Settings @@ -3234,7 +3194,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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. @@ -3247,17 +3206,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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 @@ -3313,7 +3266,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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 is used. !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,8 +3325,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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. @@ -3463,15 +3414,13 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3547,11 +3496,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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. @@ -3640,8 +3584,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3702,13 +3644,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3740,7 +3680,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_MASKLC_TOOLTIP;This 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. @@ -3789,6 +3729,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -3814,7 +3755,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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 @@ -4008,7 +3949,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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 @@ -4134,16 +4074,6 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !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_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. @@ -4186,7 +4116,3 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_WAVELET_STREND;Strength !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_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. diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 0c3330429..2cfbf4e27 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -135,6 +135,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Sæt ind - partiel FILEBROWSER_PASTEPROFILE;Sæt ind FILEBROWSER_POPUPCANCELJOB;Annulér job FILEBROWSER_POPUPCOLORLABEL;Farvemærkat +FILEBROWSER_POPUPCOLORLABEL0;Mærkat: Ingen FILEBROWSER_POPUPCOLORLABEL1;Mærkat: Rød FILEBROWSER_POPUPCOLORLABEL2;Mærkat: Gul FILEBROWSER_POPUPCOLORLABEL3;Mærkat: Grøn @@ -151,6 +152,7 @@ FILEBROWSER_POPUPPROCESS;Sæt i kø FILEBROWSER_POPUPPROCESSFAST;Sæt i kø (hurtig eksport) FILEBROWSER_POPUPPROFILEOPERATIONS;Redigering af profiloperationer FILEBROWSER_POPUPRANK;Rang +FILEBROWSER_POPUPRANK0;Ikke rangeret FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2275,13 +2277,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !!!!!!!!!!!!!!!!!!!!!!!!! !CURVEEDITOR_CURVES;Curves -!EXIFFILTER_PATH;File path !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. @@ -2959,19 +2957,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -2980,8 +2974,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3004,11 +2996,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3048,19 +3035,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3073,31 +3056,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3111,7 +3072,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_GEN;Settings @@ -3134,7 +3094,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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. @@ -3147,17 +3106,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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 @@ -3214,7 +3167,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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 is used. !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 @@ -3273,8 +3226,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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. @@ -3364,15 +3315,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3448,11 +3397,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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. @@ -3541,8 +3485,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3603,13 +3545,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3641,7 +3581,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_MASKLC_TOOLTIP;This 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. @@ -3690,6 +3630,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -3715,7 +3656,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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_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 @@ -3909,7 +3850,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -4039,16 +3979,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !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 @@ -4139,9 +4069,5 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 397d41c7b..3a2c2999c 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -221,6 +221,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Profil selektiv einfügen FILEBROWSER_PASTEPROFILE;Profil einfügen FILEBROWSER_POPUPCANCELJOB;Job abbrechen FILEBROWSER_POPUPCOLORLABEL;Farbmarkierung +FILEBROWSER_POPUPCOLORLABEL0;Markierung: Ohne FILEBROWSER_POPUPCOLORLABEL1;Markierung: Rot FILEBROWSER_POPUPCOLORLABEL2;Markierung: Gelb FILEBROWSER_POPUPCOLORLABEL3;Markierung: Grün @@ -238,6 +239,7 @@ FILEBROWSER_POPUPPROCESS;Zur Warteschlange hinzufügen FILEBROWSER_POPUPPROCESSFAST;Zur Warteschlange hinzufügen\n(Schnell-Export) FILEBROWSER_POPUPPROFILEOPERATIONS;Profiloperationen FILEBROWSER_POPUPRANK;Bewertung +FILEBROWSER_POPUPRANK0;Nicht bewertet FILEBROWSER_POPUPRANK1;Bewertung 1 * FILEBROWSER_POPUPRANK2;Bewertung 2 ** FILEBROWSER_POPUPRANK3;Bewertung 3 *** @@ -3198,6 +3200,7 @@ TP_LOCALLAB_MERNIN;Bildschirm TP_LOCALLAB_MERONE;Normal TP_LOCALLAB_MERSAT;Sättigung TP_LOCALLAB_MERSEV;Weiches Licht (legacy) +TP_LOCALLAB_MERSEV0;Weiches Licht Illusion TP_LOCALLAB_MERSEV1;Weiches Licht W3C TP_LOCALLAB_MERSEV2;Hartes Licht TP_LOCALLAB_MERSIX;Division @@ -4147,85 +4150,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: - - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!EXIFFILTER_PATH;File path -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_OTHER;Other -!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 - Gamut-Munsell -!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° -!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_LENSPROFILESDIR;Lens profiles directory -!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 -!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_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_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_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_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_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. diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 2724ff3b8..7de3a54cc 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -108,7 +108,6 @@ PREFERENCES_PRTPROFILE;Colour profile PREFERENCES_TAB_COLORMGR;Colour Management 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 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 @@ -167,9 +166,11 @@ TP_ICM_INPUTEMBEDDED_TOOLTIP;Use colour profile embedded in non-raw files. TP_ICM_INPUTNONE_TOOLTIP;Use no input colour profile at all.\nUse only in special cases. TP_ICM_LABEL;Colour Management TP_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_LABCURVE_AVOIDCOLORSHIFT;Avoid colour shift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colours into gamut of the working colour space and apply Munsell correction (Uniform Perceptual Lab). 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).\nMunsell correction always disabled when Jz or CAM16 is used. 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 @@ -270,7 +271,6 @@ TP_WAVELET_DENWAVHUE_TOOLTIP;Amplify or reduce denoising depending on the colour TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centreed on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. TP_WAVELET_TONFRAME;Excluded colours TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of 'white balance' by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. -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. !!!!!!!!!!!!!!!!!!!!!!!!! ! Untranslated keys follow; remove the ! prefix after an entry is translated. @@ -335,7 +335,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !EXIFFILTER_ISO;ISO !EXIFFILTER_LENS;Lens !EXIFFILTER_METADATAFILTER;Enable metadata filters -!EXIFFILTER_PATH;File path !EXIFFILTER_SHUTTER;Shutter !EXIFPANEL_ADDEDIT;Add/Edit !EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. @@ -409,6 +408,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial !FILEBROWSER_PASTEPROFILE;Paste !FILEBROWSER_POPUPCANCELJOB;Cancel job +!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -426,6 +426,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) !FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations !FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -435,7 +436,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPRENAME;Rename !FILEBROWSER_POPUPSELECTALL;Select all -!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_POPUPTRASH;Move to trash !FILEBROWSER_POPUPUNRANK;Unrank !FILEBROWSER_POPUPUNTRASH;Remove from trash @@ -477,7 +477,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multiple Editor Tabs Mode,\nAlt-- - Single Editor Tab Mode. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_CURVE;Curve files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !FILECHOOSER_FILTER_LCP;Lens correction profiles !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo @@ -505,7 +504,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !GENERAL_NONE;None !GENERAL_OK;OK !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_PORTRAIT;Portrait !GENERAL_RESET;Reset !GENERAL_SAVE;Save @@ -1600,20 +1598,16 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_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_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 @@ -1633,8 +1627,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1678,11 +1670,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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 @@ -1721,7 +1708,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1821,7 +1807,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b !MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s\nSave current profile (.pp3).\nShortcut: Ctrl+Shift+s !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e\nCurrent editor: +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e !MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m !MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen !MAIN_FRAME_EDITOR;Editor @@ -1933,7 +1919,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFILE;Flat-field file -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction @@ -1978,7 +1963,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PARTIALPASTE_SOFTLIGHT;Soft light !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TM_FATTAL;Dynamic range compression -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WHITEBALANCE;White balance @@ -2002,7 +1986,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries !PREFERENCES_CACHEOPTS;Cache Options !PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -2058,11 +2041,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir !PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output !PREFERENCES_EXTERNALEDITOR;External Editor -!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_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser !PREFERENCES_FLATFIELDFOUND;Found @@ -2087,7 +2065,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited !PREFERENCES_LANG;Language !PREFERENCES_LANGAUTODETECT;Use system language -!PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' @@ -2154,7 +2131,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !PREFERENCES_STARTUPIMDIR;Image Directory at Startup !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules -!PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_GENERAL;General !PREFERENCES_TAB_IMPROC;Image Processing !PREFERENCES_TAB_PERFORMANCE;Performance @@ -2163,16 +2139,9 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_TP_LABEL;Tool panel: !PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar !PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_WBA;White Balance !PREFERENCES_WORKFLOW;Layout !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2237,7 +2206,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !SAMPLEFORMAT_32;24-bit floating-point !SAMPLEFORMAT_64;32-bit floating-point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists -!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FILEFORMAT_FLOAT; floating-point !SAVEDLG_FORCEFORMATOPTS;Force saving options @@ -2255,12 +2223,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SORT_ASCENDING;Ascending -!SORT_BY_DATE;By Date -!SORT_BY_EXIF;By EXIF -!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 @@ -2363,8 +2325,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_COLORAPP_CATSYMSPE;Mixed !TP_COLORAPP_CHROMA;Chroma (C) !TP_COLORAPP_CHROMA_S;Saturation (S) -!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing +!TP_COLORAPP_CIECAT_DEGREE;Adaptation !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2421,7 +2382,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2612,11 +2572,9 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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? @@ -2631,7 +2589,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. -!TP_FLATFIELD_FROMMETADATA;From Metadata !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). @@ -2645,10 +2602,8 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. !TP_HLREC_BLEND;Blend !TP_HLREC_CIELAB;CIELab Blending -!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_HLREC_HLBLUR;Blur -!TP_HLREC_HLTH;Gain threshold !TP_HLREC_LABEL;Highlight reconstruction !TP_HLREC_LUMINANCE;Luminance Recovery !TP_HLREC_METHOD;Method: @@ -2668,7 +2623,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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. !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_INPUTCAMERA;Camera standard !TP_ICM_INPUTCAMERAICC;Auto-matched camera profile @@ -2856,8 +2810,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. !TP_LOCALLAB_CBDL_TOOLNAME;Contrast by Detail Levels !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. @@ -2931,14 +2883,12 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3008,11 +2958,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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. @@ -3097,8 +3042,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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 @@ -3150,11 +3093,9 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_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 @@ -3173,7 +3114,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_MASKLC_TOOLTIP;This 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_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. @@ -3207,6 +3148,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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 @@ -3231,7 +3173,7 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_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 @@ -3417,7 +3359,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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 @@ -3804,16 +3745,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !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_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple @@ -4112,9 +4043,6 @@ TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balan !TP_WBALANCE_LED_HEADER;LED !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 !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_PICKER;Pick !TP_WBALANCE_SHADE;Shade !TP_WBALANCE_SIZE;Size: diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index a770c9103..40ad9c57b 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -62,7 +62,6 @@ !EXIFFILTER_ISO;ISO !EXIFFILTER_LENS;Lens !EXIFFILTER_METADATAFILTER;Enable metadata filters -!EXIFFILTER_PATH;File path !EXIFFILTER_SHUTTER;Shutter !EXIFPANEL_ADDEDIT;Add/Edit !EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. @@ -139,6 +138,7 @@ !FILEBROWSER_PASTEPROFILE;Paste !FILEBROWSER_POPUPCANCELJOB;Cancel job !FILEBROWSER_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -156,6 +156,7 @@ !FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) !FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations !FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -165,7 +166,6 @@ !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPRENAME;Rename !FILEBROWSER_POPUPSELECTALL;Select all -!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_POPUPTRASH;Move to trash !FILEBROWSER_POPUPUNRANK;Unrank !FILEBROWSER_POPUPUNTRASH;Remove from trash @@ -209,7 +209,6 @@ !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 @@ -237,7 +236,6 @@ !GENERAL_NONE;None !GENERAL_OK;OK !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_PORTRAIT;Portrait !GENERAL_RESET;Reset !GENERAL_SAVE;Save @@ -1407,22 +1405,18 @@ !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 @@ -1442,8 +1436,6 @@ !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1489,11 +1481,6 @@ !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 @@ -1533,7 +1520,6 @@ !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -1633,7 +1619,7 @@ !MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b !MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s\nSave current profile (.pp3).\nShortcut: Ctrl+Shift+s !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e\nCurrent editor: +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e !MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m !MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen !MAIN_FRAME_EDITOR;Editor @@ -1753,7 +1739,6 @@ !PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFILE;Flat-field file -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_ICMSETTINGS;Color management settings @@ -1801,7 +1786,6 @@ !PARTIALPASTE_SOFTLIGHT;Soft light !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TM_FATTAL;Dynamic range compression -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WHITEBALANCE;White balance @@ -1830,7 +1814,6 @@ !PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries !PREFERENCES_CACHEOPTS;Cache Options !PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -1886,11 +1869,6 @@ !PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir !PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output !PREFERENCES_EXTERNALEDITOR;External Editor -!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_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser !PREFERENCES_FLATFIELDFOUND;Found @@ -1918,7 +1896,6 @@ !PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited !PREFERENCES_LANG;Language !PREFERENCES_LANGAUTODETECT;Use system language -!PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' @@ -1989,7 +1966,6 @@ !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_COLORMGR;Color Management !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules -!PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_GENERAL;General !PREFERENCES_TAB_IMPROC;Image Processing !PREFERENCES_TAB_PERFORMANCE;Performance @@ -1998,16 +1974,9 @@ !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_TP_LABEL;Tool panel: !PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar !PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_WBA;White Balance !PREFERENCES_WORKFLOW;Layout !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2072,7 +2041,6 @@ !SAMPLEFORMAT_32;24-bit floating-point !SAMPLEFORMAT_64;32-bit floating-point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists -!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FILEFORMAT_FLOAT; floating-point !SAVEDLG_FORCEFORMATOPTS;Force saving options @@ -2092,13 +2060,6 @@ !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -2215,8 +2176,7 @@ !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing +!TP_COLORAPP_CIECAT_DEGREE;Adaptation !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2282,7 +2242,6 @@ !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2497,11 +2456,9 @@ !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? @@ -2516,7 +2473,6 @@ !TP_FLATFIELD_BT_VERTICAL;Vertical !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. -!TP_FLATFIELD_FROMMETADATA;From Metadata !TP_FLATFIELD_LABEL;Flat-Field !TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center @@ -2534,10 +2490,8 @@ !TP_HLREC_BLEND;Blend !TP_HLREC_CIELAB;CIELab Blending !TP_HLREC_COLOR;Color Propagation -!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !TP_HLREC_HLBLUR;Blur -!TP_HLREC_HLTH;Gain threshold !TP_HLREC_LABEL;Highlight reconstruction !TP_HLREC_LUMINANCE;Luminance Recovery !TP_HLREC_METHOD;Method: @@ -2557,7 +2511,6 @@ !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. !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_INPUTCAMERA;Camera standard !TP_ICM_INPUTCAMERAICC;Auto-matched camera profile @@ -2635,6 +2588,8 @@ !TP_ICM_WORKING_TRC_TOOLTIP;Only for built-in profiles. !TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction !TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). !TP_LABCURVE_BRIGHTNESS;Lightness !TP_LABCURVE_CHROMATICITY;Chromaticity !TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. @@ -2699,7 +2654,7 @@ !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_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 is used. !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 @@ -2758,8 +2713,6 @@ !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. @@ -2849,15 +2802,13 @@ !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -2933,11 +2884,6 @@ !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. @@ -3026,8 +2972,6 @@ !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 @@ -3088,13 +3032,11 @@ !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 @@ -3126,7 +3068,7 @@ !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_MASKLC_TOOLTIP;This 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. @@ -3175,6 +3117,7 @@ !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 @@ -3200,7 +3143,7 @@ !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_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 @@ -3394,7 +3337,6 @@ !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 @@ -3791,16 +3733,6 @@ !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_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones @@ -4111,10 +4043,6 @@ !TP_WBALANCE_LED_HEADER;LED !TP_WBALANCE_LED_LSI;LSI Lumelex 2040 !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_PICKER;Pick !TP_WBALANCE_SHADE;Shade !TP_WBALANCE_SIZE;Size: diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index 50c45b2b6..ede64894f 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -136,6 +136,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil (parcialmente) FILEBROWSER_PASTEPROFILE;Pegar perfil FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color +FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Ninguna FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Roja FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarilla FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -153,6 +154,7 @@ FILEBROWSER_POPUPPROCESS;Enviar la imagen a la cola FILEBROWSER_POPUPPROCESSFAST;Enviar a la cola (Exportación rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles de revelado FILEBROWSER_POPUPRANK;Asignar rango +FILEBROWSER_POPUPRANK0;Sin rango FILEBROWSER_POPUPRANK1;Rango 1 * FILEBROWSER_POPUPRANK2;Rango 2 ** FILEBROWSER_POPUPRANK3;Rango 3 *** @@ -3113,6 +3115,7 @@ TP_LOCALLAB_MERNIN;Pantalla TP_LOCALLAB_MERONE;Normal TP_LOCALLAB_MERSAT;Saturación TP_LOCALLAB_MERSEV;Luz suave (anterior) +TP_LOCALLAB_MERSEV0;Ilusión de Luz suave TP_LOCALLAB_MERSEV1;Luz suave W3C TP_LOCALLAB_MERSEV2;Luz dura TP_LOCALLAB_MERSIX;Dividir @@ -4063,84 +4066,3 @@ ZOOMPANEL_ZOOMFITSCREEN;Encajar la imagen entera en la vista previa\nAtajo de te ZOOMPANEL_ZOOMIN;Acercar\nAtajo de teclado: + ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!EXIFFILTER_PATH;File path -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_OTHER;Other -!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 - Gamut-Munsell -!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° -!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_LENSPROFILESDIR;Lens profiles directory -!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 -!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_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_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_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_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_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. diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index ccf70ac84..56a73d30f 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -191,6 +191,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil parcialmente FILEBROWSER_PASTEPROFILE;Pegar perfil FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color +FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Ninguna FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Rojo FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarillo FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -207,6 +208,7 @@ FILEBROWSER_POPUPPROCESS;Poner en la cola FILEBROWSER_POPUPPROCESSFAST;Poner en la cola (exportación rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles FILEBROWSER_POPUPRANK;Asignar rango +FILEBROWSER_POPUPRANK0;Sin Rango FILEBROWSER_POPUPRANK1;Rango 1 * FILEBROWSER_POPUPRANK2;Rango 2 ** FILEBROWSER_POPUPRANK3;Rango 3 *** @@ -2284,7 +2286,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !!!!!!!!!!!!!!!!!!!!!!!!! !CURVEEDITOR_CATMULLROM;Flexible -!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -2293,13 +2294,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!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. @@ -2978,21 +2976,17 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -3001,8 +2995,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -3033,11 +3025,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3077,7 +3064,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector @@ -3087,14 +3073,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !MAIN_TAB_LOCALLAB;Local !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_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic !PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction @@ -3113,24 +3096,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_PERFORMANCE_MEASURE;Measure !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3139,14 +3108,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location -!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 @@ -3160,7 +3121,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_GEN;Settings @@ -3183,7 +3143,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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. @@ -3202,18 +3161,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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_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 @@ -3276,7 +3229,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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 is used. !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 @@ -3335,8 +3288,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. @@ -3426,15 +3377,13 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3510,11 +3459,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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. @@ -3603,8 +3547,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3665,13 +3607,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3703,7 +3643,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_MASKLC_TOOLTIP;This 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. @@ -3752,6 +3692,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -3777,7 +3718,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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_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 @@ -3971,7 +3912,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -4108,16 +4048,6 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !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 @@ -4208,9 +4138,5 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 53771ff8f..b7b2c7ec7 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -130,6 +130,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Coller partiellement FILEBROWSER_PASTEPROFILE;Coller le profil FILEBROWSER_POPUPCANCELJOB;Retirer de la file de traitement FILEBROWSER_POPUPCOLORLABEL;Label couleur +FILEBROWSER_POPUPCOLORLABEL0;Label: Aucun FILEBROWSER_POPUPCOLORLABEL1;Label: Rouge FILEBROWSER_POPUPCOLORLABEL2;Label: Jaune FILEBROWSER_POPUPCOLORLABEL3;Label: Vert @@ -146,6 +147,7 @@ FILEBROWSER_POPUPPROCESS;Mettre dans la file de traitement FILEBROWSER_POPUPPROCESSFAST;Mettre dans la file de traitement (Export Rapide) FILEBROWSER_POPUPPROFILEOPERATIONS;Opérations sur les profils FILEBROWSER_POPUPRANK;Rang +FILEBROWSER_POPUPRANK0;Aucun FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2199,6 +2201,7 @@ TP_LOCALLAB_MERNIN;Ecran 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;Lumière dure TP_LOCALLAB_MERSIX;Divise @@ -3029,7 +3032,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -3038,13 +3040,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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. -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!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. @@ -3723,16 +3722,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !HISTORY_MSG_EDGEFFECT;Edge Attenuation response -!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata -!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 @@ -3741,8 +3736,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -3770,11 +3763,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_SIGMATON;Toning Attenuation response !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3814,16 +3802,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector !MAIN_FRAME_PLACES_DEL;Remove !PARTIALPASTE_FILMNEGATIVE;Film negative -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_PREPROCWB;Preprocess White Balance -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments @@ -3836,22 +3820,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3860,14 +3830,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location -!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 @@ -3880,7 +3842,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_GEN;Settings @@ -3903,19 +3864,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_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_CROP_GTCENTEREDSQUARE;Centered square !TP_CROP_PPI;PPI !TP_DEHAZE_SATURATION;Saturation -!TP_FILMNEGATIVE_PICK_SIZE;Size: -!TP_FILMNEGATIVE_REF_SIZE;Size: -!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_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 @@ -3970,39 +3924,26 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_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 is used. !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_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_COLOR_CIE;Color curve !TP_LOCALLAB_CURVES_CIE;Tone curve !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_DIVGR;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_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_GRAINFRA2;Coarseness !TP_LOCALLAB_HUECIE;Hue !TP_LOCALLAB_INVBL;Inverse !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_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 @@ -4015,7 +3956,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !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_SATURV;Saturation (s) -!TP_LOCALLAB_TE_PIVOT;Pivot (Ev) !TP_LOCALLAB_TOOLMASK_2;Wavelets !TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. !TP_LOCALLAB_ZCAMFRA;ZCAM Image Adjustments @@ -4043,16 +3983,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_RESIZE_SHORT;Short Edge !TP_SHARPENING_ITERCHECK;Auto limit iterations !TP_SHARPENING_RADIUS_BOOST;Corner radius boost -!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 @@ -4140,9 +4070,5 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index aeed90a44..e4447f7f6 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -103,6 +103,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Incolla - parziale FILEBROWSER_PASTEPROFILE;Incolla FILEBROWSER_POPUPCANCELJOB;Annulla lavoro FILEBROWSER_POPUPCOLORLABEL;Etichetta colorata +FILEBROWSER_POPUPCOLORLABEL0;Etichetta: Nessuna FILEBROWSER_POPUPCOLORLABEL1;Etichetta: Rosso FILEBROWSER_POPUPCOLORLABEL2;Etichetta: Giallo FILEBROWSER_POPUPCOLORLABEL3;Etichetta: Verde @@ -119,6 +120,7 @@ FILEBROWSER_POPUPPROCESS;Aggiungi alla Coda FILEBROWSER_POPUPPROCESSFAST;Aggiungi alla Coda (Esportazione Rapida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operazioni sui Profili di Sviluppo FILEBROWSER_POPUPRANK;Classificazione +FILEBROWSER_POPUPRANK0;Nessun Punteggio FILEBROWSER_POPUPRANK1;Punteggio 1 * FILEBROWSER_POPUPRANK2;Punteggio 2 ** FILEBROWSER_POPUPRANK3;Punteggio 3 *** @@ -1233,7 +1235,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile !EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -1251,14 +1252,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -1270,7 +1269,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2197,22 +2195,18 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2232,8 +2226,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2279,11 +2271,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2323,7 +2310,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2417,7 +2403,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2436,7 +2421,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2449,7 +2433,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2485,11 +2468,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -2498,7 +2476,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2531,19 +2508,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2565,18 +2534,10 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2599,7 +2560,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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] @@ -2626,7 +2586,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -2764,11 +2723,9 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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? @@ -2776,10 +2733,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2788,7 +2742,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -2870,7 +2823,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_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 is used. !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 @@ -2929,8 +2882,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -3020,15 +2971,13 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3104,11 +3053,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. @@ -3197,8 +3141,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3259,13 +3201,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3297,7 +3237,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_MASKLC_TOOLTIP;This 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. @@ -3346,6 +3286,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3371,7 +3312,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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_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 @@ -3565,7 +3506,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -3875,16 +3815,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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 @@ -4137,10 +4067,6 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 36555b955..0f35036db 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -135,6 +135,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;プロファイルの貼り付け - 一部 FILEBROWSER_PASTEPROFILE;プロファイルの貼り付け FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル FILEBROWSER_POPUPCOLORLABEL;カラー・ラベル +FILEBROWSER_POPUPCOLORLABEL0;ラベル: なし FILEBROWSER_POPUPCOLORLABEL1;ラベル: レッド FILEBROWSER_POPUPCOLORLABEL2;ラベル: イエロー FILEBROWSER_POPUPCOLORLABEL3;ラベル: グリーン @@ -152,6 +153,7 @@ FILEBROWSER_POPUPPROCESS;キューに追加 FILEBROWSER_POPUPPROCESSFAST;キューに追加 (高速書き出し) FILEBROWSER_POPUPPROFILEOPERATIONS;プロファイルの操作 FILEBROWSER_POPUPRANK;ランク +FILEBROWSER_POPUPRANK0;ランクなし FILEBROWSER_POPUPRANK1;ランク 1 * FILEBROWSER_POPUPRANK2;ランク 2 ** FILEBROWSER_POPUPRANK3;ランク 3 *** @@ -3112,6 +3114,7 @@ TP_LOCALLAB_MERNIN;スクリーン TP_LOCALLAB_MERONE;標準 TP_LOCALLAB_MERSAT;彩度 TP_LOCALLAB_MERSEV;ソフトライト(レガシー) +TP_LOCALLAB_MERSEV0;ソフトライト イリュージョン TP_LOCALLAB_MERSEV1;ソフトライト W3C TP_LOCALLAB_MERSEV2;ハードライト TP_LOCALLAB_MERSIX;分割 @@ -4066,81 +4069,4 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_OTHER;Other -!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 - Gamut-Munsell -!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° -!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_LENSPROFILESDIR;Lens profiles directory -!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 -!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_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_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_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_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. diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index b0c33bb6a..6283dbe4b 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -833,7 +833,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -854,6 +853,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. !FILEBROWSER_EXTPROGMENU;Open with !FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -861,6 +861,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -868,7 +869,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 !FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 !FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 @@ -881,7 +881,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -895,7 +894,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -1907,22 +1905,18 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -1942,8 +1936,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1989,11 +1981,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2033,7 +2020,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. @@ -2151,7 +2137,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_LOCALCONTRAST;Local contrast @@ -2174,7 +2159,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2192,7 +2176,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -2231,11 +2214,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -2245,7 +2223,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MONINTENT;Default rendering intent @@ -2279,20 +2256,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_WBA;White Balance !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_GLOBALPROFILES;Bundled profiles !PROFILEPANEL_MODE_TOOLTIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. @@ -2322,7 +2291,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -2334,13 +2302,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. !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 @@ -2442,8 +2403,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_COLORAPP_CHROMA_S;Saturation (S) !TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM corresponds to the color of a stimulus in relation to its own brightness. It differs from L*a*b* and RGB saturation. !TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM corresponds to the color of a stimulus relative to the clarity of a stimulus that appears white under identical conditions. It differs from L*a*b* and RGB chroma. -!TP_COLORAPP_CIECAT_DEGREE;Chromatic Adaptation Scene -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing +!TP_COLORAPP_CIECAT_DEGREE;Adaptation !TP_COLORAPP_CONTRAST;Contrast (J) !TP_COLORAPP_CONTRAST_Q;Contrast (Q) !TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM is based on brightness. It differs from L*a*b* and RGB contrast. @@ -2509,7 +2469,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2677,11 +2636,9 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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? @@ -2689,7 +2646,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. !TP_GRADIENT_CENTER;Center !TP_GRADIENT_CENTER_X;Center X @@ -2703,10 +2659,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_GRADIENT_LABEL;Graduated Filter !TP_GRADIENT_STRENGTH;Strength !TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. -!TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. !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 @@ -2718,7 +2672,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. !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 @@ -2778,6 +2731,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). !TP_LABCURVE_CHROMATICITY;Chromaticity !TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. !TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated @@ -2835,7 +2790,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_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 is used. !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 @@ -2894,8 +2849,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -2985,15 +2938,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3069,11 +3020,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. @@ -3162,8 +3108,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3224,13 +3168,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3262,7 +3204,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_MASKLC_TOOLTIP;This 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. @@ -3311,6 +3253,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3336,7 +3279,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_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 @@ -3530,7 +3473,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 @@ -3857,16 +3799,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple @@ -4131,10 +4063,6 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_WBALANCE_AUTO_HEADER;Automatic !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_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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index ff4ae66f6..63eaeccc6 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -151,6 +151,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Gedeeltelijk plakken FILEBROWSER_PASTEPROFILE;Plak profiel FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij FILEBROWSER_POPUPCOLORLABEL;Kleur label +FILEBROWSER_POPUPCOLORLABEL0;Label: Geen FILEBROWSER_POPUPCOLORLABEL1;Label: Rood FILEBROWSER_POPUPCOLORLABEL2;Label: Geel FILEBROWSER_POPUPCOLORLABEL3;Label: Groen @@ -167,6 +168,7 @@ FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij FILEBROWSER_POPUPPROCESSFAST;Plaats in verwerkingsrij voor Snelle Export FILEBROWSER_POPUPPROFILEOPERATIONS;Profielbewerkingen FILEBROWSER_POPUPRANK;Waardering +FILEBROWSER_POPUPRANK0;Geen FILEBROWSER_POPUPRANK1;Waardering 1 * FILEBROWSER_POPUPRANK2;Waardering 2 ** FILEBROWSER_POPUPRANK3;Waardering 3 *** @@ -2296,13 +2298,9 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !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. @@ -2980,19 +2978,15 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -3001,8 +2995,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 - Gamut-Munsell !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera !HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera @@ -3025,11 +3017,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3068,19 +3055,15 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3093,31 +3076,9 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3131,7 +3092,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_GEN;Settings @@ -3154,7 +3114,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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. @@ -3167,17 +3126,11 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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 @@ -3233,7 +3186,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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 is used. !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 @@ -3292,8 +3245,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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. @@ -3383,15 +3334,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3467,11 +3416,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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. @@ -3560,8 +3504,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3622,13 +3564,11 @@ 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_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 @@ -3660,7 +3600,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_MASKLC_TOOLTIP;This 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. @@ -3709,6 +3649,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -3734,7 +3675,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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_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 @@ -3928,7 +3869,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -4058,16 +3998,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !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 @@ -4158,9 +4088,5 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index d58ecf454..06ed63aba 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -132,6 +132,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Wklej częściowo FILEBROWSER_PASTEPROFILE;Wklej profil FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta +FILEBROWSER_POPUPCOLORLABEL0;Etykieta: Brak FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Żółta FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona @@ -148,6 +149,7 @@ FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu FILEBROWSER_POPUPPROFILEOPERATIONS;Profile przetwarzania FILEBROWSER_POPUPRANK;Ocena +FILEBROWSER_POPUPRANK0;Usuń ocenę FILEBROWSER_POPUPRANK1;Ocena 1 * FILEBROWSER_POPUPRANK2;Ocena 2 ** FILEBROWSER_POPUPRANK3;Ocena 3 *** @@ -1925,7 +1927,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !DYNPROFILEEDITOR_ENTRY_TOOLTIP;The matching is case insensitive.\nUse the 're:' prefix to enter\na regular expression. !DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule -!EXIFFILTER_PATH;File path !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1938,12 +1939,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_POPUPSORTBY;Sort Files !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_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit -!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. @@ -2723,22 +2721,18 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -2753,8 +2747,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera @@ -2785,11 +2777,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance !HISTORY_MSG_WAVBL;Blur levels @@ -2828,7 +2815,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description !ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. !ICCPROFCREATOR_ILL;Illuminant: @@ -2859,7 +2845,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_METADATA;Metadata mode @@ -2872,11 +2857,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit !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 @@ -2890,16 +2873,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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_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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console !PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic) @@ -2914,30 +2891,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar !PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips !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_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_ZOOMONSCROLL;Zoom images by scrolling !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. !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 @@ -2954,7 +2915,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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] @@ -2979,7 +2939,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -3019,16 +2978,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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_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_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 @@ -3036,7 +2990,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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 @@ -3096,7 +3049,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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 is used. !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 @@ -3155,8 +3108,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -3246,15 +3197,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3330,11 +3279,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. @@ -3423,8 +3367,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3485,13 +3427,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3523,7 +3463,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_MASKLC_TOOLTIP;This 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. @@ -3572,6 +3512,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3597,7 +3538,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_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 @@ -3791,7 +3732,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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 @@ -3986,16 +3926,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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_ANCHOR;Anchor -!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_B2;Residual !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. @@ -4149,10 +4079,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. !TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the 'auto white balance'\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by 'computedTemp + computedTemp * bias'. diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 03b160b3a..09d3aa790 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -131,6 +131,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Colar - parcial FILEBROWSER_PASTEPROFILE;Colar FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho FILEBROWSER_POPUPCOLORLABEL;Etiqueta de cor +FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: nenhuma FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: vermelho FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: amarelo FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: verde @@ -147,6 +148,7 @@ FILEBROWSER_POPUPPROCESS;Colocar na fila FILEBROWSER_POPUPPROCESSFAST;Colocar na fila (exportação rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operações de perfil de processamento FILEBROWSER_POPUPRANK;Classificar +FILEBROWSER_POPUPRANK0;Desclassificar FILEBROWSER_POPUPRANK1;Classificação 1 estrela FILEBROWSER_POPUPRANK2;Classificação 2 estrelas FILEBROWSER_POPUPRANK3;Classificação 3 estrelas @@ -2227,7 +2229,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !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? @@ -2236,13 +2237,10 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!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. @@ -2921,21 +2919,17 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -2944,8 +2938,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -2975,11 +2967,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3019,7 +3006,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector @@ -3027,14 +3013,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !MAIN_TAB_LOCALLAB;Local !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_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments @@ -3047,22 +3030,8 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -3071,14 +3040,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location -!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 @@ -3092,7 +3053,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_GEN;Settings @@ -3115,7 +3075,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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. @@ -3134,18 +3093,12 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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_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 @@ -3208,7 +3161,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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 is used. !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 @@ -3267,8 +3220,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. @@ -3358,15 +3309,13 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3442,11 +3391,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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. @@ -3535,8 +3479,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3597,13 +3539,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3635,7 +3575,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_MASKLC_TOOLTIP;This 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. @@ -3684,6 +3624,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -3709,7 +3650,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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_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 @@ -3903,7 +3844,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -4038,16 +3978,6 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !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 @@ -4138,9 +4068,5 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index 2a4d1e4cf..cf386f5ff 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -135,6 +135,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Colar - parcial FILEBROWSER_PASTEPROFILE;Colar FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho FILEBROWSER_POPUPCOLORLABEL;Etiqueta de Cor +FILEBROWSER_POPUPCOLORLABEL0;Etiqueta: Nenhuma FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Vermelha FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarela FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde @@ -151,6 +152,7 @@ FILEBROWSER_POPUPPROCESS;Coloque na fila FILEBROWSER_POPUPPROCESSFAST;Coloque na fila (Exportação rápida) FILEBROWSER_POPUPPROFILEOPERATIONS;Operações de perfil de processamento FILEBROWSER_POPUPRANK;Classificar +FILEBROWSER_POPUPRANK0;Desclassificar FILEBROWSER_POPUPRANK1;Classificação 1 * FILEBROWSER_POPUPRANK2;Classificação 2 ** FILEBROWSER_POPUPRANK3;Classificação 3 *** @@ -2239,15 +2241,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!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. @@ -2928,21 +2926,17 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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_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 @@ -2951,8 +2945,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations @@ -2982,11 +2974,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3026,21 +3013,17 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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_FILMNEGATIVE;Film negative -!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_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 @@ -3053,34 +3036,12 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_LENSPROFILESDIR;Lens profiles directory !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_ZOOMONSCROLL;Zoom images by scrolling !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... -!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 @@ -3094,7 +3055,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_GEN;Settings @@ -3117,7 +3077,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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. @@ -3136,17 +3095,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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_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 @@ -3206,7 +3159,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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 is used. !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 @@ -3265,8 +3218,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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. @@ -3356,15 +3307,13 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3440,11 +3389,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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. @@ -3533,8 +3477,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3595,13 +3537,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3633,7 +3573,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_MASKLC_TOOLTIP;This 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. @@ -3682,6 +3622,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -3707,7 +3648,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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_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 @@ -3901,7 +3842,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -4039,16 +3979,6 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !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 @@ -4139,9 +4069,5 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 15c833742..6b0aa6ca0 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -124,6 +124,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Частичная вставка FILEBROWSER_PASTEPROFILE;Вставить профиль FILEBROWSER_POPUPCANCELJOB;Отменить задание FILEBROWSER_POPUPCOLORLABEL;Цветовая пометка +FILEBROWSER_POPUPCOLORLABEL0;Пометка: нет FILEBROWSER_POPUPCOLORLABEL1;Пометка: Красным FILEBROWSER_POPUPCOLORLABEL2;Пометка: Желтым FILEBROWSER_POPUPCOLORLABEL3;Пометка: Зеленым @@ -140,6 +141,7 @@ FILEBROWSER_POPUPPROCESS;Поместить в очередь на обрабо FILEBROWSER_POPUPPROCESSFAST;Поставить в очередь (Быстрый экспорт) FILEBROWSER_POPUPPROFILEOPERATIONS;Обработка операций профиля FILEBROWSER_POPUPRANK;Рейтинг +FILEBROWSER_POPUPRANK0;Снять FILEBROWSER_POPUPRANK1;Рейтинг 1 * FILEBROWSER_POPUPRANK2;Рейтинг 2 ** FILEBROWSER_POPUPRANK3;Рейтинг 3 *** @@ -1432,7 +1434,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. -!EXIFFILTER_PATH;File path !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1449,16 +1450,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. -!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. @@ -2364,21 +2362,17 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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 @@ -2393,8 +2387,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope !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_GAMUTMUNSEL;Local - Gamut-Munsell !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -2436,11 +2428,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -2480,7 +2467,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2540,7 +2526,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !PARTIALPASTE_FILMNEGATIVE;Film negative !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_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2553,13 +2538,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !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 @@ -2583,18 +2566,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_HISTOGRAM_TOOLTIP;If enabled, the working profile is used for rendering the main histogram and the Navigator panel, otherwise the gamma-corrected output profile is used. !PREFERENCES_INSPECTORWINDOW;Open inspector in own window or fullscreen !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONPROFILE;Default color profile @@ -2615,14 +2592,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2640,18 +2609,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -2672,7 +2633,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_COLORAPP_CATMOD;Mode !TP_COLORAPP_CATSYMGEN;Automatic Symmetric !TP_COLORAPP_CATSYMSPE;Mixed -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_DATACIE_TOOLTIP;Affects histograms shown in Color Appearance & Lightning curves. Does not affect RawTherapee's main histogram.\n\nEnabled: show approximate values for J and C, S or M after the CIECAM adjustments.\nDisabled: show L*a*b* values before CIECAM adjustments. !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). @@ -2724,7 +2684,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_COLORAPP_TCMODE_LIGHTNESS;Lightness !TP_COLORAPP_TCMODE_SATUR;Saturation !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_TONECIE;Use CIECAM for tone mapping !TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. @@ -2835,19 +2794,14 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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_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 @@ -2856,7 +2810,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !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 !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 @@ -2929,7 +2882,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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 is used. !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 @@ -2988,8 +2941,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. @@ -3079,15 +3030,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3163,11 +3112,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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. @@ -3256,8 +3200,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3318,13 +3260,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3356,7 +3296,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_MASKLC_TOOLTIP;This 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. @@ -3405,6 +3345,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 @@ -3430,7 +3371,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_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 @@ -3624,7 +3565,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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 @@ -3884,16 +3824,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !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_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 @@ -4144,10 +4074,6 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. !TP_WBALANCE_TEMPBIAS;AWB temperature bias diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 179759476..2c48f771b 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1194,7 +1194,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels @@ -1209,6 +1208,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_POPUPCOLORLABEL0;Label: None !FILEBROWSER_POPUPCOLORLABEL1;Label: Red !FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow !FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -1216,6 +1216,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILEBROWSER_POPUPCOLORLABEL5;Label: Purple !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_POPUPRANK1;Rank 1 * !FILEBROWSER_POPUPRANK2;Rank 2 ** !FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -1223,14 +1224,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILEBROWSER_POPUPRANK5;Rank 5 ***** !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 @@ -1242,7 +1241,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !GENERAL_EDIT;Edit !GENERAL_HELP;Help !GENERAL_OPEN;Open -!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2172,22 +2170,18 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2207,8 +2201,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2254,11 +2246,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2298,7 +2285,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2401,7 +2387,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2421,7 +2406,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2435,7 +2419,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2471,11 +2454,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -2485,7 +2463,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor @@ -2518,19 +2495,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2552,17 +2521,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 !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 @@ -2590,7 +2551,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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] @@ -2617,7 +2577,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -2763,11 +2722,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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? @@ -2775,10 +2732,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -2788,7 +2742,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_ICM_BPC;Black Point Compensation !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 !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_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. !TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 @@ -2871,7 +2824,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_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 is used. !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 @@ -2930,8 +2883,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -3021,15 +2972,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3105,11 +3054,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. @@ -3198,8 +3142,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3260,13 +3202,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3298,7 +3238,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_MASKLC_TOOLTIP;This 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. @@ -3347,6 +3287,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3372,7 +3313,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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_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 @@ -3566,7 +3507,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -3875,16 +3815,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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 @@ -4137,10 +4067,6 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index f47368abb..f3d71c543 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -135,6 +135,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Delno - prilepi FILEBROWSER_PASTEPROFILE;Prilepi FILEBROWSER_POPUPCANCELJOB;Prekliči ukaz FILEBROWSER_POPUPCOLORLABEL;Barvna oznaka +FILEBROWSER_POPUPCOLORLABEL0;Label: Brez FILEBROWSER_POPUPCOLORLABEL1;Label: Rdeča FILEBROWSER_POPUPCOLORLABEL2;Label: Rumena FILEBROWSER_POPUPCOLORLABEL3;Label: Zelena @@ -151,6 +152,7 @@ FILEBROWSER_POPUPPROCESS;Postavi v čakalno vrsto FILEBROWSER_POPUPPROCESSFAST;Postavi v čakalno vrsto (Hiter izvoz) FILEBROWSER_POPUPPROFILEOPERATIONS;Obdelujem profile FILEBROWSER_POPUPRANK;Rangiraj +FILEBROWSER_POPUPRANK0;Unrank FILEBROWSER_POPUPRANK1;Rang 1 * FILEBROWSER_POPUPRANK2;Rang 2 ** FILEBROWSER_POPUPRANK3;Rang 3 *** @@ -2269,14 +2271,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!EXIFFILTER_PATH;File path !FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!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. @@ -2954,19 +2952,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_COMPLEXRETI;Retinex complexity !HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation !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 @@ -2975,8 +2969,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 - Gamut-Munsell !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -3000,11 +2992,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -3044,19 +3031,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !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 @@ -3069,31 +3052,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_LENSPROFILESDIR;Lens profiles directory !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_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 @@ -3107,7 +3068,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_GEN;Settings @@ -3130,7 +3090,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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. @@ -3143,17 +3102,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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 @@ -3211,7 +3164,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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 is used. !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 @@ -3270,8 +3223,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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. @@ -3361,15 +3312,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3445,11 +3394,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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. @@ -3538,8 +3482,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3600,13 +3542,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3638,7 +3578,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_MASKLC_TOOLTIP;This 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. @@ -3687,6 +3627,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -3712,7 +3653,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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_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 @@ -3906,7 +3847,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -4037,16 +3977,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !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 @@ -4137,9 +4067,5 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_STUDLABEL;Correlation factor: %1 !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. diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index a1b70fbb5..de612ad73 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -105,6 +105,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Klistra in partiell profil FILEBROWSER_PASTEPROFILE;Klistra in profil FILEBROWSER_POPUPCANCELJOB;Avbryt FILEBROWSER_POPUPCOLORLABEL;Färgetikett +FILEBROWSER_POPUPCOLORLABEL0;Label: Ingen FILEBROWSER_POPUPCOLORLABEL1;Label: Röd FILEBROWSER_POPUPCOLORLABEL2;Label: Gul FILEBROWSER_POPUPCOLORLABEL3;Label: Grön @@ -121,6 +122,7 @@ FILEBROWSER_POPUPPROCESS;Flytta till behandlingskön FILEBROWSER_POPUPPROCESSFAST;Lägg till i kön (Snabbexport) FILEBROWSER_POPUPPROFILEOPERATIONS;Profilaktiviteter FILEBROWSER_POPUPRANK;Betyg +FILEBROWSER_POPUPRANK0;Ta bort betyg FILEBROWSER_POPUPRANK1;Betyg 1 * FILEBROWSER_POPUPRANK2;Betyg 2 ** FILEBROWSER_POPUPRANK3;Betyg 3 *** @@ -1726,7 +1728,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile !EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path !EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_PIPELINE;Processing pipeline @@ -1743,15 +1744,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. -!FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_CURRENT;Current !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit !GENERAL_HELP;Help -!GENERAL_OTHER;Other !GENERAL_RESET;Reset !GENERAL_SAVE_AS;Save as... !GENERAL_SLIDER;Slider @@ -2520,22 +2518,18 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2555,8 +2549,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 - Gamut-Munsell !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2602,11 +2594,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2646,7 +2633,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_WAVTHRDEN;Threshold local contrast !HISTORY_MSG_WAVTHREND;Threshold local contrast !HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° !ICCPROFCREATOR_COPYRIGHT;Copyright: !ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. !ICCPROFCREATOR_CUSTOM;Custom @@ -2735,7 +2721,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_FILMNEGATIVE;Film negative !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 @@ -2750,7 +2735,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2763,7 +2747,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -2791,16 +2774,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_INSPECTORWINDOW;Open inspector in own window or fullscreen !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_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_MONINTENT;Default rendering intent !PREFERENCES_MONITOR;Monitor !PREFERENCES_MONPROFILE;Default color profile @@ -2818,19 +2795,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings !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_ZOOMONSCROLL;Zoom images by scrolling !PROFILEPANEL_PDYNAMIC;Dynamic !PROGRESSBAR_DECODING;Decoding... @@ -2852,17 +2821,9 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 !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 @@ -2881,7 +2842,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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] @@ -2908,7 +2868,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -2977,23 +2936,17 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_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_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_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 @@ -3073,7 +3026,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_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 is used. !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 @@ -3132,8 +3085,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -3223,15 +3174,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 RT-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_DETAILTHR;Luma-chro detail threshold !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3307,11 +3256,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. @@ -3400,8 +3344,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3462,13 +3404,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3500,7 +3440,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_MASKLC_TOOLTIP;This 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. @@ -3549,6 +3489,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -3574,7 +3515,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_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 @@ -3768,7 +3709,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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 @@ -4001,16 +3941,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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_BALCHROM;Equalizer Color !TP_WAVELET_BALLUM;Denoise equalizer White-Black !TP_WAVELET_BL;Blur levels @@ -4139,10 +4069,6 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey !TP_WBALANCE_AUTO_HEADER;Automatic -!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_PICKER;Pick !TP_WBALANCE_STUDLABEL;Correlation factor: %1 !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. From f59122e05a05d528941b4b253ab71b7d5420cd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Fri, 21 Jul 2023 13:43:15 +0200 Subject: [PATCH 294/326] Removed irrelevant changes from 'rtdata/languages/default' --- rtdata/languages/default | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 73a0ae1cc..6788f52e3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -138,6 +138,7 @@ FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial FILEBROWSER_PASTEPROFILE;Paste FILEBROWSER_POPUPCANCELJOB;Cancel job FILEBROWSER_POPUPCOLORLABEL;Color label +FILEBROWSER_POPUPCOLORLABEL0;Label: None FILEBROWSER_POPUPCOLORLABEL1;Label: Red FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow FILEBROWSER_POPUPCOLORLABEL3;Label: Green @@ -155,6 +156,7 @@ FILEBROWSER_POPUPPROCESS;Put to queue FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations FILEBROWSER_POPUPRANK;Rank +FILEBROWSER_POPUPRANK0;Unrank FILEBROWSER_POPUPRANK1;Rank 1 * FILEBROWSER_POPUPRANK2;Rank 2 ** FILEBROWSER_POPUPRANK3;Rank 3 *** @@ -1441,8 +1443,8 @@ 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 - Gamut-Munsell +HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -1748,11 +1750,11 @@ PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_FILMNEGATIVE;Film negative PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection +PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control PARTIALPASTE_FLATFIELDFILE;Flat-field file -PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata PARTIALPASTE_GRADIENT;Graduated filter PARTIALPASTE_HSVEQUALIZER;HSV equalizer PARTIALPASTE_ICMSETTINGS;Color management settings @@ -1838,6 +1840,7 @@ PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic PREFERENCES_CHUNKSIZE_RGB;RGB processing PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Avoid artifacts +PREFERENCES_WBA;White Balance PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -2006,7 +2009,6 @@ PREFERENCES_TOOLPANEL_TOOL;Tool PREFERENCES_TP_LABEL;Tool panel: PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -PREFERENCES_WBA;White Balance PREFERENCES_WORKFLOW;Layout PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling PROFILEPANEL_COPYPPASTE;Parameters to copy @@ -2092,11 +2094,11 @@ SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sl 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_NAME;By Name 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_BY_LABEL;By Color Label SORT_DESCENDING;Descending TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By @@ -2281,8 +2283,8 @@ TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode TP_COLORAPP_TCMODE_LIGHTNESS;Lightness TP_COLORAPP_TCMODE_SATUR;Saturation 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_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_TONECIE;Use CIECAM for tone mapping TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. TP_COLORAPP_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. @@ -2757,8 +2759,6 @@ 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. @@ -2932,11 +2932,11 @@ 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_GAMUTLABRELA;Lab TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative +TP_LOCALLAB_GAMUTMUNSELL;Munsell only TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) TP_LOCALLAB_GRADANG;Gradient angle TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. @@ -3025,8 +3025,6 @@ TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the 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 @@ -3087,13 +3085,11 @@ TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the 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 @@ -3174,6 +3170,7 @@ 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 @@ -3183,6 +3180,12 @@ 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_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_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 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 @@ -3790,12 +3793,12 @@ 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_BANDS;Bands TP_TONE_EQUALIZER_DETAIL;Regularization TP_TONE_EQUALIZER_LABEL;Tone Equalizer TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) From 5b2811f42b751dfdc36139e441aed10beaa66285 Mon Sep 17 00:00:00 2001 From: Michael Jaschob Date: Sat, 22 Jul 2023 22:09:03 -0600 Subject: [PATCH 295/326] Allocate on Heap, Not Stack, in `gaussVertical` and Friends --- rtengine/gauss.cc | 150 +++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index 99201a860..e3b3fc5b3 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -1119,6 +1119,8 @@ template void gaussVerticalSsediv (T** src, T** dst, T** divBuffer, con template void gaussVertical (T** src, T** dst, const int W, const int H, const double sigma) { +#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] + double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1129,7 +1131,7 @@ template void gaussVertical (T** src, T** dst, const int W, const int H // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double temp2[H][numcols] ALIGNED16; + double *temp2 ALIGNED16 = new double[H * numcols]; double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; #ifdef _OPENMP #pragma omp for nowait @@ -1137,32 +1139,32 @@ template void gaussVertical (T** src, T** dst, const int W, const int H for (unsigned int i = 0; i < static_cast(std::max(0, W - numcols + 1)); i += numcols) { for (int k = 0; k < numcols; k++) { - temp2[0][k] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[1][k] = B * src[1][i + k] + b1 * temp2[0][k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[2][k] = B * src[2][i + k] + b1 * temp2[1][k] + b2 * temp2[0][k] + b3 * src[0][i + k]; + TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - temp2[j][k] = B * src[j][i + k] + b1 * temp2[j - 1][k] + b2 * temp2[j - 2][k] + b3 * temp2[j - 3][k]; + TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[0][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[0][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[1][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[1][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[2][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[2][2] * (temp2[H - 3][k] - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] = temp2[H - 1][k] = temp2Hm1[k]; - dst[H - 2][i + k] = temp2[H - 2][k] = B * temp2[H - 2][k] + b1 * temp2[H - 1][k] + b2 * temp2H[k] + b3 * temp2Hp1[k]; - dst[H - 3][i + k] = temp2[H - 3][k] = B * temp2[H - 3][k] + b1 * temp2[H - 2][k] + b2 * temp2[H - 1][k] + b3 * temp2H[k]; + dst[H - 1][i + k] = TEMP2(H - 1, k) = temp2Hm1[k]; + dst[H - 2][i + k] = TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]; + dst[H - 3][i + k] = TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]; } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] = temp2[j][k] = B * temp2[j][k] + b1 * temp2[j + 1][k] + b2 * temp2[j + 2][k] + b3 * temp2[j + 3][k]; + dst[j][i + k] = TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k); } } } @@ -1173,31 +1175,35 @@ template void gaussVertical (T** src, T** dst, const int W, const int H // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - temp2[0][0] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - temp2[1][0] = B * src[1][i] + b1 * temp2[0][0] + b2 * src[0][i] + b3 * src[0][i]; - temp2[2][0] = B * src[2][i] + b1 * temp2[1][0] + b2 * temp2[0][0] + b3 * src[0][i]; + TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; for (int j = 3; j < H; j++) { - temp2[j][0] = B * src[j][i] + b1 * temp2[j - 1][0] + b2 * temp2[j - 2][0] + b3 * temp2[j - 3][0]; + TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[0][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[0][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[1][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[1][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[2][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[2][2] * (temp2[H - 3][0] - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - dst[H - 1][i] = temp2[H - 1][0] = temp2Hm1; - dst[H - 2][i] = temp2[H - 2][0] = B * temp2[H - 2][0] + b1 * temp2[H - 1][0] + b2 * temp2H + b3 * temp2Hp1; - dst[H - 3][i] = temp2[H - 3][0] = B * temp2[H - 3][0] + b1 * temp2[H - 2][0] + b2 * temp2[H - 1][0] + b3 * temp2H; + dst[H - 1][i] = TEMP2(H - 1, 0) = temp2Hm1; + dst[H - 2][i] = TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1; + dst[H - 3][i] = TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H; for (int j = H - 4; j >= 0; j--) { - dst[j][i] = temp2[j][0] = B * temp2[j][0] + b1 * temp2[j + 1][0] + b2 * temp2[j + 2][0] + b3 * temp2[j + 3][0]; + dst[j][i] = TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0); } } + + delete [] temp2; } #ifndef __SSE2__ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const int W, const int H, const double sigma) { +#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] + double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1208,7 +1214,7 @@ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double temp2[H][numcols] ALIGNED16; + double *temp2 ALIGNED16 = new double[H * numcols]; double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; #ifdef _OPENMP #pragma omp for nowait @@ -1216,32 +1222,32 @@ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const for (int i = 0; i < W - numcols + 1; i += numcols) { for (int k = 0; k < numcols; k++) { - temp2[0][k] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[1][k] = B * src[1][i + k] + b1 * temp2[0][k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[2][k] = B * src[2][i + k] + b1 * temp2[1][k] + b2 * temp2[0][k] + b3 * src[0][i + k]; + TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - temp2[j][k] = B * src[j][i + k] + b1 * temp2[j - 1][k] + b2 * temp2[j - 2][k] + b3 * temp2[j - 3][k]; + TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[0][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[0][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[1][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[1][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[2][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[2][2] * (temp2[H - 3][k] - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] = rtengine::max(divBuffer[H - 1][i + k] / (temp2[H - 1][k] = temp2Hm1[k]), 0.0); - dst[H - 2][i + k] = rtengine::max(divBuffer[H - 2][i + k] / (temp2[H - 2][k] = B * temp2[H - 2][k] + b1 * temp2[H - 1][k] + b2 * temp2H[k] + b3 * temp2Hp1[k]), 0.0); - dst[H - 3][i + k] = rtengine::max(divBuffer[H - 3][i + k] / (temp2[H - 3][k] = B * temp2[H - 3][k] + b1 * temp2[H - 2][k] + b2 * temp2[H - 1][k] + b3 * temp2H[k]), 0.0); + dst[H - 1][i + k] = rtengine::max(divBuffer[H - 1][i + k] / (TEMP2(H - 1, k) = temp2Hm1[k]), 0.0); + dst[H - 2][i + k] = rtengine::max(divBuffer[H - 2][i + k] / (TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]), 0.0); + dst[H - 3][i + k] = rtengine::max(divBuffer[H - 3][i + k] / (TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]), 0.0); } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] = rtengine::max(divBuffer[j][i + k] / (temp2[j][k] = B * temp2[j][k] + b1 * temp2[j + 1][k] + b2 * temp2[j + 2][k] + b3 * temp2[j + 3][k]), 0.0); + dst[j][i + k] = rtengine::max(divBuffer[j][i + k] / (TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k)), 0.0); } } } @@ -1252,30 +1258,34 @@ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - temp2[0][0] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - temp2[1][0] = B * src[1][i] + b1 * temp2[0][0] + b2 * src[0][i] + b3 * src[0][i]; - temp2[2][0] = B * src[2][i] + b1 * temp2[1][0] + b2 * temp2[0][0] + b3 * src[0][i]; + TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; for (int j = 3; j < H; j++) { - temp2[j][0] = B * src[j][i] + b1 * temp2[j - 1][0] + b2 * temp2[j - 2][0] + b3 * temp2[j - 3][0]; + TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[0][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[0][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[1][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[1][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[2][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[2][2] * (temp2[H - 3][0] - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - dst[H - 1][i] = rtengine::max(divBuffer[H - 1][i] / (temp2[H - 1][0] = temp2Hm1), 0.0); - dst[H - 2][i] = rtengine::max(divBuffer[H - 2][i] / (temp2[H - 2][0] = B * temp2[H - 2][0] + b1 * temp2[H - 1][0] + b2 * temp2H + b3 * temp2Hp1), 0.0); - dst[H - 3][i] = rtengine::max(divBuffer[H - 3][i] / (temp2[H - 3][0] = B * temp2[H - 3][0] + b1 * temp2[H - 2][0] + b2 * temp2[H - 1][0] + b3 * temp2H), 0.0); + dst[H - 1][i] = rtengine::max(divBuffer[H - 1][i] / (TEMP2(H - 1, 0) = temp2Hm1), 0.0); + dst[H - 2][i] = rtengine::max(divBuffer[H - 2][i] / (TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1), 0.0); + dst[H - 3][i] = rtengine::max(divBuffer[H - 3][i] / (TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H), 0.0); for (int j = H - 4; j >= 0; j--) { - dst[j][i] = rtengine::max(divBuffer[j][i] / (temp2[j][0] = B * temp2[j][0] + b1 * temp2[j + 1][0] + b2 * temp2[j + 2][0] + b3 * temp2[j + 3][0]), 0.0); + dst[j][i] = rtengine::max(divBuffer[j][i] / (TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0)), 0.0); } } + + delete [] temp2; } template void gaussVerticalmult (T** src, T** dst, const int W, const int H, const double sigma) { +#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] + double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1286,7 +1296,7 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double temp2[H][numcols] ALIGNED16; + double *temp2 ALIGNED16 = new double[H * numcols]; double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; #ifdef _OPENMP #pragma omp for nowait @@ -1294,32 +1304,32 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i for (int i = 0; i < W - numcols + 1; i += numcols) { for (int k = 0; k < numcols; k++) { - temp2[0][k] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[1][k] = B * src[1][i + k] + b1 * temp2[0][k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - temp2[2][k] = B * src[2][i + k] + b1 * temp2[1][k] + b2 * temp2[0][k] + b3 * src[0][i + k]; + TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; + TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - temp2[j][k] = B * src[j][i + k] + b1 * temp2[j - 1][k] + b2 * temp2[j - 2][k] + b3 * temp2[j - 3][k]; + TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[0][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[0][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[1][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[1][2] * (temp2[H - 3][k] - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[H - 1][k] - src[H - 1][i + k]) + M[2][1] * (temp2[H - 2][k] - src[H - 1][i + k]) + M[2][2] * (temp2[H - 3][k] - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] *= temp2[H - 1][k] = temp2Hm1[k]; - dst[H - 2][i + k] *= temp2[H - 2][k] = B * temp2[H - 2][k] + b1 * temp2[H - 1][k] + b2 * temp2H[k] + b3 * temp2Hp1[k]; - dst[H - 3][i + k] *= temp2[H - 3][k] = B * temp2[H - 3][k] + b1 * temp2[H - 2][k] + b2 * temp2[H - 1][k] + b3 * temp2H[k]; + dst[H - 1][i + k] *= TEMP2(H - 1, k) = temp2Hm1[k]; + dst[H - 2][i + k] *= TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]; + dst[H - 3][i + k] *= TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]; } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] *= (temp2[j][k] = B * temp2[j][k] + b1 * temp2[j + 1][k] + b2 * temp2[j + 2][k] + b3 * temp2[j + 3][k]); + dst[j][i + k] *= (TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k)); } } } @@ -1330,26 +1340,28 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - temp2[0][0] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - temp2[1][0] = B * src[1][i] + b1 * temp2[0][0] + b2 * src[0][i] + b3 * src[0][i]; - temp2[2][0] = B * src[2][i] + b1 * temp2[1][0] + b2 * temp2[0][0] + b3 * src[0][i]; + TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; + TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; for (int j = 3; j < H; j++) { - temp2[j][0] = B * src[j][i] + b1 * temp2[j - 1][0] + b2 * temp2[j - 2][0] + b3 * temp2[j - 3][0]; + TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[0][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[0][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[1][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[1][2] * (temp2[H - 3][0] - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[H - 1][0] - src[H - 1][i]) + M[2][1] * (temp2[H - 2][0] - src[H - 1][i]) + M[2][2] * (temp2[H - 3][0] - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - dst[H - 1][i] *= temp2[H - 1][0] = temp2Hm1; - dst[H - 2][i] *= temp2[H - 2][0] = B * temp2[H - 2][0] + b1 * temp2[H - 1][0] + b2 * temp2H + b3 * temp2Hp1; - dst[H - 3][i] *= temp2[H - 3][0] = B * temp2[H - 3][0] + b1 * temp2[H - 2][0] + b2 * temp2[H - 1][0] + b3 * temp2H; + dst[H - 1][i] *= TEMP2(H - 1, 0) = temp2Hm1; + dst[H - 2][i] *= TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1; + dst[H - 3][i] *= TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H; for (int j = H - 4; j >= 0; j--) { - dst[j][i] *= (temp2[j][0] = B * temp2[j][0] + b1 * temp2[j + 1][0] + b2 * temp2[j + 2][0] + b3 * temp2[j + 3][0]); + dst[j][i] *= (TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0)); } } + + delete [] temp2; } #endif From 655447b0f1bcb5512bb72e5c597befdeddecb146 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 26 Jul 2023 17:19:35 +0700 Subject: [PATCH 296/326] macos: gitignore .DS_Store files A .DS_Store file is automatically generated by the macOS Finder that contains the parent folder's metadata (a database of icon positions and background image selections). Adding this to the .gitignore so we don't have to manually remove them when committing to the repository. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fc65c877c..043daf27a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .settings .directory .vscode +.DS_Store CMakeCache.txt CMakeFiles From 31bbe917609fd4e5061ddca7819bffb9767ad045 Mon Sep 17 00:00:00 2001 From: Michael Jaschob Date: Thu, 27 Jul 2023 14:31:53 -0600 Subject: [PATCH 297/326] Use `std::vector` Instead of Manually Managed Memory --- rtengine/gauss.cc | 166 ++++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 81 deletions(-) diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index e3b3fc5b3..0575f73c0 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include "gauss.h" @@ -1119,8 +1120,6 @@ template void gaussVerticalSsediv (T** src, T** dst, T** divBuffer, con template void gaussVertical (T** src, T** dst, const int W, const int H, const double sigma) { -#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] - double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1131,40 +1130,45 @@ template void gaussVertical (T** src, T** dst, const int W, const int H // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double *temp2 ALIGNED16 = new double[H * numcols]; + std::vector temp2(H * numcols); double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; + + auto coord = + [](const int &x, const int &y) -> int { + return x * numcols + y; + }; #ifdef _OPENMP #pragma omp for nowait #endif for (unsigned int i = 0; i < static_cast(std::max(0, W - numcols + 1)); i += numcols) { for (int k = 0; k < numcols; k++) { - TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; + temp2[coord(0, k)] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(1, k)] = B * src[1][i + k] + b1 * temp2[coord(0, k)] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(2, k)] = B * src[2][i + k] + b1 * temp2[coord(1, k)] + b2 * temp2[coord(0, k)] + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); + temp2[coord(j, k)] = B * src[j][i + k] + b1 * temp2[coord(j - 1, k)] + b2 * temp2[coord(j - 2, k)] + b3 * temp2[coord(j - 3, k)]; } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[0][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[0][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[1][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[1][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[2][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[2][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] = TEMP2(H - 1, k) = temp2Hm1[k]; - dst[H - 2][i + k] = TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]; - dst[H - 3][i + k] = TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]; + dst[H - 1][i + k] = temp2[coord(H - 1, k)] = temp2Hm1[k]; + dst[H - 2][i + k] = temp2[coord(H - 2, k)] = B * temp2[coord(H - 2, k)] + b1 * temp2[coord(H - 1, k)] + b2 * temp2H[k] + b3 * temp2Hp1[k]; + dst[H - 3][i + k] = temp2[coord(H - 3, k)] = B * temp2[coord(H - 3, k)] + b1 * temp2[coord(H - 2, k)] + b2 * temp2[coord(H - 1, k)] + b3 * temp2H[k]; } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] = TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k); + dst[j][i + k] = temp2[coord(j, k)] = B * temp2[coord(j, k)] + b1 * temp2[coord(j + 1, k)] + b2 * temp2[coord(j + 2, k)] + b3 * temp2[coord(j + 3, k)]; } } } @@ -1175,35 +1179,31 @@ template void gaussVertical (T** src, T** dst, const int W, const int H // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; + temp2[coord(0, 0)] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(1, 0)] = B * src[1][i] + b1 * temp2[coord(0, 0)] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(2, 0)] = B * src[2][i] + b1 * temp2[coord(1, 0)] + b2 * temp2[coord(0, 0)] + b3 * src[0][i]; for (int j = 3; j < H; j++) { - TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); + temp2[coord(j, 0)] = B * src[j][i] + b1 * temp2[coord(j - 1, 0)] + b2 * temp2[coord(j - 2, 0)] + b3 * temp2[coord(j - 3, 0)]; } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[0][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[0][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[1][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[1][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[2][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[2][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); - dst[H - 1][i] = TEMP2(H - 1, 0) = temp2Hm1; - dst[H - 2][i] = TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1; - dst[H - 3][i] = TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H; + dst[H - 1][i] = temp2[coord(H - 1, 0)] = temp2Hm1; + dst[H - 2][i] = temp2[coord(H - 2, 0)] = B * temp2[coord(H - 2, 0)] + b1 * temp2[coord(H - 1, 0)] + b2 * temp2H + b3 * temp2Hp1; + dst[H - 3][i] = temp2[coord(H - 3, 0)] = B * temp2[coord(H - 3, 0)] + b1 * temp2[coord(H - 2, 0)] + b2 * temp2[coord(H - 1, 0)] + b3 * temp2H; for (int j = H - 4; j >= 0; j--) { - dst[j][i] = TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0); + dst[j][i] = temp2[coord(j, 0)] = B * temp2[coord(j, 0)] + b1 * temp2[coord(j + 1, 0)] + b2 * temp2[coord(j + 2, 0)] + b3 * temp2[coord(j + 3, 0)]; } } - - delete [] temp2; } #ifndef __SSE2__ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const int W, const int H, const double sigma) { -#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] - double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1214,40 +1214,45 @@ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double *temp2 ALIGNED16 = new double[H * numcols]; + std::vector temp2(H * numcols); double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; + + auto coord = + [](const int &x, const int &y) -> int { + return x * numcols + y; + }; #ifdef _OPENMP #pragma omp for nowait #endif for (int i = 0; i < W - numcols + 1; i += numcols) { for (int k = 0; k < numcols; k++) { - TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; + temp2[coord(0, k)] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(1, k)] = B * src[1][i + k] + b1 * temp2[coord(0, k)] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(2, k)] = B * src[2][i + k] + b1 * temp2[coord(1, k)] + b2 * temp2[coord(0, k)] + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); + temp2[coord(j, k)] = B * src[j][i + k] + b1 * temp2[coord(j - 1, k)] + b2 * temp2[coord(j - 2, k)] + b3 * temp2[coord(j - 3, k)]; } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[0][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[0][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[1][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[1][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[2][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[2][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] = rtengine::max(divBuffer[H - 1][i + k] / (TEMP2(H - 1, k) = temp2Hm1[k]), 0.0); - dst[H - 2][i + k] = rtengine::max(divBuffer[H - 2][i + k] / (TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]), 0.0); - dst[H - 3][i + k] = rtengine::max(divBuffer[H - 3][i + k] / (TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]), 0.0); + dst[H - 1][i + k] = rtengine::max(divBuffer[H - 1][i + k] / (temp2[coord(H - 1, k)] = temp2Hm1[k]), 0.0); + dst[H - 2][i + k] = rtengine::max(divBuffer[H - 2][i + k] / (temp2[coord(H - 2, k)] = B * temp2[coord(H - 2, k)] + b1 * temp2[coord(H - 1, k)] + b2 * temp2H[k] + b3 * temp2Hp1[k]), 0.0); + dst[H - 3][i + k] = rtengine::max(divBuffer[H - 3][i + k] / (temp2[coord(H - 3, k)] = B * temp2[coord(H - 3, k)] + b1 * temp2[coord(H - 2, k)] + b2 * temp2[coord(H - 1, k)] + b3 * temp2H[k]), 0.0); } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] = rtengine::max(divBuffer[j][i + k] / (TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k)), 0.0); + dst[j][i + k] = rtengine::max(divBuffer[j][i + k] / (temp2[coord(j, k)] = B * temp2[coord(j, k)] + b1 * temp2[coord(j + 1, k)] + b2 * temp2[coord(j + 2, k)] + b3 * temp2[coord(j + 3, k)]), 0.0); } } } @@ -1258,34 +1263,30 @@ template void gaussVerticaldiv (T** src, T** dst, T** divBuffer, const // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; + temp2[coord(0, 0)] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(1, 0)] = B * src[1][i] + b1 * temp2[coord(0, 0)] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(2, 0)] = B * src[2][i] + b1 * temp2[coord(1, 0)] + b2 * temp2[coord(0, 0)] + b3 * src[0][i]; for (int j = 3; j < H; j++) { - TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); + temp2[coord(j, 0)] = B * src[j][i] + b1 * temp2[coord(j - 1, 0)] + b2 * temp2[coord(j - 2, 0)] + b3 * temp2[coord(j - 3, 0)]; } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[0][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[0][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[1][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[1][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[2][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[2][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); - dst[H - 1][i] = rtengine::max(divBuffer[H - 1][i] / (TEMP2(H - 1, 0) = temp2Hm1), 0.0); - dst[H - 2][i] = rtengine::max(divBuffer[H - 2][i] / (TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1), 0.0); - dst[H - 3][i] = rtengine::max(divBuffer[H - 3][i] / (TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H), 0.0); + dst[H - 1][i] = rtengine::max(divBuffer[H - 1][i] / (temp2[coord(H - 1, 0)] = temp2Hm1), 0.0); + dst[H - 2][i] = rtengine::max(divBuffer[H - 2][i] / (temp2[coord(H - 2, 0)] = B * temp2[coord(H - 2, 0)] + b1 * temp2[coord(H - 1, 0)] + b2 * temp2H + b3 * temp2Hp1), 0.0); + dst[H - 3][i] = rtengine::max(divBuffer[H - 3][i] / (temp2[coord(H - 3, 0)] = B * temp2[coord(H - 3, 0)] + b1 * temp2[coord(H - 2, 0)] + b2 * temp2[coord(H - 1, 0)] + b3 * temp2H), 0.0); for (int j = H - 4; j >= 0; j--) { - dst[j][i] = rtengine::max(divBuffer[j][i] / (TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0)), 0.0); + dst[j][i] = rtengine::max(divBuffer[j][i] / (temp2[coord(j, 0)] = B * temp2[coord(j, 0)] + b1 * temp2[coord(j + 1, 0)] + b2 * temp2[coord(j + 2, 0)] + b3 * temp2[coord(j + 3, 0)]), 0.0); } } - - delete [] temp2; } template void gaussVerticalmult (T** src, T** dst, const int W, const int H, const double sigma) { -#define TEMP2(X, Y) temp2[(X) * numcols + (Y)] - double b1, b2, b3, B, M[3][3]; calculateYvVFactors(sigma, b1, b2, b3, B, M); @@ -1296,40 +1297,45 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i // process 'numcols' columns for better usage of L1 cpu cache (especially faster for large values of H) static const int numcols = 8; - double *temp2 ALIGNED16 = new double[H * numcols]; + std::vector temp2(H * numcols); double temp2Hm1[numcols], temp2H[numcols], temp2Hp1[numcols]; + + auto coord = + [](const int &x, const int &y) -> int { + return x * numcols + y; + }; #ifdef _OPENMP #pragma omp for nowait #endif for (int i = 0; i < W - numcols + 1; i += numcols) { for (int k = 0; k < numcols; k++) { - TEMP2(0, k) = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(1, k) = B * src[1][i + k] + b1 * TEMP2(0, k) + b2 * src[0][i + k] + b3 * src[0][i + k]; - TEMP2(2, k) = B * src[2][i + k] + b1 * TEMP2(1, k) + b2 * TEMP2(0, k) + b3 * src[0][i + k]; + temp2[coord(0, k)] = B * src[0][i + k] + b1 * src[0][i + k] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(1, k)] = B * src[1][i + k] + b1 * temp2[coord(0, k)] + b2 * src[0][i + k] + b3 * src[0][i + k]; + temp2[coord(2, k)] = B * src[2][i + k] + b1 * temp2[coord(1, k)] + b2 * temp2[coord(0, k)] + b3 * src[0][i + k]; } for (int j = 3; j < H; j++) { for (int k = 0; k < numcols; k++) { - TEMP2(j, k) = B * src[j][i + k] + b1 * TEMP2(j - 1, k) + b2 * TEMP2(j - 2, k) + b3 * TEMP2(j - 3, k); + temp2[coord(j, k)] = B * src[j][i + k] + b1 * temp2[coord(j - 1, k)] + b2 * temp2[coord(j - 2, k)] + b3 * temp2[coord(j - 3, k)]; } } for (int k = 0; k < numcols; k++) { - temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[0][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[0][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2H[k] = src[H - 1][i + k] + M[1][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[1][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[1][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); - temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (TEMP2(H - 1, k) - src[H - 1][i + k]) + M[2][1] * (TEMP2(H - 2, k) - src[H - 1][i + k]) + M[2][2] * (TEMP2(H - 3, k) - src[H - 1][i + k]); + temp2Hm1[k] = src[H - 1][i + k] + M[0][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[0][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[0][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2H[k] = src[H - 1][i + k] + M[1][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[1][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[1][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); + temp2Hp1[k] = src[H - 1][i + k] + M[2][0] * (temp2[coord(H - 1, k)] - src[H - 1][i + k]) + M[2][1] * (temp2[coord(H - 2, k)] - src[H - 1][i + k]) + M[2][2] * (temp2[coord(H - 3, k)] - src[H - 1][i + k]); } for (int k = 0; k < numcols; k++) { - dst[H - 1][i + k] *= TEMP2(H - 1, k) = temp2Hm1[k]; - dst[H - 2][i + k] *= TEMP2(H - 2, k) = B * TEMP2(H - 2, k) + b1 * TEMP2(H - 1, k) + b2 * temp2H[k] + b3 * temp2Hp1[k]; - dst[H - 3][i + k] *= TEMP2(H - 3, k) = B * TEMP2(H - 3, k) + b1 * TEMP2(H - 2, k) + b2 * TEMP2(H - 1, k) + b3 * temp2H[k]; + dst[H - 1][i + k] *= temp2[coord(H - 1, k)] = temp2Hm1[k]; + dst[H - 2][i + k] *= temp2[coord(H - 2, k)] = B * temp2[coord(H - 2, k)] + b1 * temp2[coord(H - 1, k)] + b2 * temp2H[k] + b3 * temp2Hp1[k]; + dst[H - 3][i + k] *= temp2[coord(H - 3, k)] = B * temp2[coord(H - 3, k)] + b1 * temp2[coord(H - 2, k)] + b2 * temp2[coord(H - 1, k)] + b3 * temp2H[k]; } for (int j = H - 4; j >= 0; j--) { for (int k = 0; k < numcols; k++) { - dst[j][i + k] *= (TEMP2(j, k) = B * TEMP2(j, k) + b1 * TEMP2(j + 1, k) + b2 * TEMP2(j + 2, k) + b3 * TEMP2(j + 3, k)); + dst[j][i + k] *= (temp2[coord(j, k)] = B * temp2[coord(j, k)] + b1 * temp2[coord(j + 1, k)] + b2 * temp2[coord(j + 2, k)] + b3 * temp2[coord(j + 3, k)]); } } } @@ -1340,28 +1346,26 @@ template void gaussVerticalmult (T** src, T** dst, const int W, const i // process remaining columns for (int i = W - (W % numcols); i < W; i++) { - TEMP2(0, 0) = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(1, 0) = B * src[1][i] + b1 * TEMP2(0, 0) + b2 * src[0][i] + b3 * src[0][i]; - TEMP2(2, 0) = B * src[2][i] + b1 * TEMP2(1, 0) + b2 * TEMP2(0, 0) + b3 * src[0][i]; + temp2[coord(0, 0)] = B * src[0][i] + b1 * src[0][i] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(1, 0)] = B * src[1][i] + b1 * temp2[coord(0, 0)] + b2 * src[0][i] + b3 * src[0][i]; + temp2[coord(2, 0)] = B * src[2][i] + b1 * temp2[coord(1, 0)] + b2 * temp2[coord(0, 0)] + b3 * src[0][i]; for (int j = 3; j < H; j++) { - TEMP2(j, 0) = B * src[j][i] + b1 * TEMP2(j - 1, 0) + b2 * TEMP2(j - 2, 0) + b3 * TEMP2(j - 3, 0); + temp2[coord(j, 0)] = B * src[j][i] + b1 * temp2[coord(j - 1, 0)] + b2 * temp2[coord(j - 2, 0)] + b3 * temp2[coord(j - 3, 0)]; } - double temp2Hm1 = src[H - 1][i] + M[0][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[0][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[0][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2H = src[H - 1][i] + M[1][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[1][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[1][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); - double temp2Hp1 = src[H - 1][i] + M[2][0] * (TEMP2(H - 1, 0) - src[H - 1][i]) + M[2][1] * (TEMP2(H - 2, 0) - src[H - 1][i]) + M[2][2] * (TEMP2(H - 3, 0) - src[H - 1][i]); + double temp2Hm1 = src[H - 1][i] + M[0][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[0][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[0][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2H = src[H - 1][i] + M[1][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[1][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[1][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); + double temp2Hp1 = src[H - 1][i] + M[2][0] * (temp2[coord(H - 1, 0)] - src[H - 1][i]) + M[2][1] * (temp2[coord(H - 2, 0)] - src[H - 1][i]) + M[2][2] * (temp2[coord(H - 3, 0)] - src[H - 1][i]); - dst[H - 1][i] *= TEMP2(H - 1, 0) = temp2Hm1; - dst[H - 2][i] *= TEMP2(H - 2, 0) = B * TEMP2(H - 2, 0) + b1 * TEMP2(H - 1, 0) + b2 * temp2H + b3 * temp2Hp1; - dst[H - 3][i] *= TEMP2(H - 3, 0) = B * TEMP2(H - 3, 0) + b1 * TEMP2(H - 2, 0) + b2 * TEMP2(H - 1, 0) + b3 * temp2H; + dst[H - 1][i] *= temp2[coord(H - 1, 0)] = temp2Hm1; + dst[H - 2][i] *= temp2[coord(H - 2, 0)] = B * temp2[coord(H - 2, 0)] + b1 * temp2[coord(H - 1, 0)] + b2 * temp2H + b3 * temp2Hp1; + dst[H - 3][i] *= temp2[coord(H - 3, 0)] = B * temp2[coord(H - 3, 0)] + b1 * temp2[coord(H - 2, 0)] + b2 * temp2[coord(H - 1, 0)] + b3 * temp2H; for (int j = H - 4; j >= 0; j--) { - dst[j][i] *= (TEMP2(j, 0) = B * TEMP2(j, 0) + b1 * TEMP2(j + 1, 0) + b2 * TEMP2(j + 2, 0) + b3 * TEMP2(j + 3, 0)); + dst[j][i] *= (temp2[coord(j, 0)] = B * temp2[coord(j, 0)] + b1 * temp2[coord(j + 1, 0)] + b2 * temp2[coord(j + 2, 0)] + b3 * temp2[coord(j + 3, 0)]); } } - - delete [] temp2; } #endif From 5c42a50204dda19e244ed2d0a880cf0ea4a68dd7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 30 Jul 2023 14:25:17 -0700 Subject: [PATCH 298/326] Fix PDAF lines pattern for Sony ILCE-7RM2 --- rtengine/camconst.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index a7e589416..3026775e3 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2993,8 +2993,8 @@ Camera constants: "dcraw_matrix": [ 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 ], // DNG_v9.1.1 D65 "raw_crop": [ 0, 0, -36, 0 ], // full raw frame 8000x5320 - 36 rightmost columns are garbage "ranges": { "black": 512, "white": 16300 }, - // PDAF info provided by Horshack with the rawshack tool (http://testcams.com/rawshack/) - "pdaf_pattern" : [ 0,24,36,60,84,120,132,156,192,204,240,252,276,300,324,360,372,396,420 ], + // PDAF lines pattern detected from image provided by elite4jonny at https://github.com/Beep6581/RawTherapee/issues/6801. + "pdaf_pattern" : [ 0,24,36,60,84,120,132,156,192,204,240,252,276,300,324,360,372,396,420,444,480,492,504,540,564,576,612,636,660,696,720,732,756,780,804,840 ], "pdaf_offset" : 31 }, From a592b2dfc3c39f663d98f4757acd78ff8bfedf97 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 30 Jul 2023 17:54:52 -0700 Subject: [PATCH 299/326] Fix invisible separator in file browser Places Set minimum height and color for the TreeView separator for the RawTherapee and legacy RawTherapee themes. --- rtdata/themes/RawTherapee - Legacy-GTK3-20_.css | 2 ++ rtdata/themes/RawTherapee-GTK3-20_.css | 2 ++ 2 files changed, 4 insertions(+) diff --git a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css b/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css index 07a0bd65d..ba62fd366 100644 --- a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css +++ b/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css @@ -227,6 +227,8 @@ menu separator { } #PlacesPaned .view.separator { + min-height: 0.16666666666666666em; + color: #363636; } #MetaPanelNotebook separator { diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index 2e314510a..e909eb33f 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -207,6 +207,8 @@ menu separator { } #PlacesPaned .view.separator { + min-height: 0.16666666666666666em; + color: #363636; } #MetaPanelNotebook separator { From 3e13e77b6f657d76533a676f3bfbe60e885dba94 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 30 Jul 2023 18:09:19 -0700 Subject: [PATCH 300/326] Move favorited places to the top of the list --- rtgui/placesbrowser.cc | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 3440080f8..f1209a3a0 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -106,9 +106,32 @@ void PlacesBrowser::refreshPlacesList () { placesModel->clear (); + // append favorites + for (size_t i = 0; i < options.favoriteDirs.size(); i++) { + Glib::RefPtr fav = Gio::File::create_for_path (options.favoriteDirs[i]); + + if (fav && fav->query_exists()) { + try { + if (auto info = fav->query_info ()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = fav->get_parse_name (); + newrow[placesColumns.type] = 5; + newrow[placesColumns.rowSeparator] = false; + } + } catch(Gio::Error&) {} + } + } + // append home directory Glib::RefPtr hfile = Gio::File::create_for_path (userHomeDir()); // Will send back "My documents" on Windows now, which has no restricted access + if (!placesModel->children().empty()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.rowSeparator] = true; + } + if (hfile && hfile->query_exists()) { try { if (auto info = hfile->query_info ()) { @@ -223,29 +246,6 @@ void PlacesBrowser::refreshPlacesList () newrow[placesColumns.rowSeparator] = false; } } - - // append favorites - if (!placesModel->children().empty()) { - Gtk::TreeModel::Row newrow = *(placesModel->append()); - newrow[placesColumns.rowSeparator] = true; - } - - for (size_t i = 0; i < options.favoriteDirs.size(); i++) { - Glib::RefPtr fav = Gio::File::create_for_path (options.favoriteDirs[i]); - - if (fav && fav->query_exists()) { - try { - if (auto info = fav->query_info ()) { - Gtk::TreeModel::Row newrow = *(placesModel->append()); - newrow[placesColumns.label] = info->get_display_name (); - newrow[placesColumns.icon] = info->get_icon (); - newrow[placesColumns.root] = fav->get_parse_name (); - newrow[placesColumns.type] = 5; - newrow[placesColumns.rowSeparator] = false; - } - } catch(Gio::Error&) {} - } - } } bool PlacesBrowser::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) From a626bdae3e379bd049d12675667741462c540773 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 31 Jul 2023 22:57:57 -0700 Subject: [PATCH 301/326] Fix external editor on macOS Avoid using Gio::AppInfo. --- rtgui/editorpanel.cc | 20 ++++++++++++------ rtgui/editorpanel.h | 4 ++-- rtgui/externaleditorpreferences.cc | 33 ++++++++++++++++++++++++------ rtgui/extprog.cc | 13 +++++++----- rtgui/extprog.h | 9 +++++++- 5 files changed, 59 insertions(+), 20 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 420717b7e..d91e2d7e3 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2249,8 +2249,10 @@ void EditorPanel::sendToExternalPressed() dialog->show(); } else { struct ExternalEditor editor = options.externalEditors.at(options.externalEditorIndex); - external_editor_info = Gio::AppInfo::create_from_commandline(editor.command, editor.name, Gio::APP_INFO_CREATE_NONE); - external_editor_native_command = editor.native_command; + external_editor_info = { + editor.name, + editor.command, + editor.native_command}; sendToExternal(); } } @@ -2416,7 +2418,7 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef setUserOnlyPermission(Gio::File::create_for_path(filename), false); - success = ExtProgStore::openInExternalEditor(filename, external_editor_info, external_editor_native_command); + success = ExtProgStore::openInExternalEditor(filename, external_editor_info); if (!success) { Gtk::MessageDialog msgd (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); @@ -2445,12 +2447,16 @@ RTAppChooserDialog *EditorPanel::getAppChooserDialog() void EditorPanel::onAppChooserDialogResponse(int responseId) { switch (responseId) { - case Gtk::RESPONSE_OK: + case Gtk::RESPONSE_OK: { getAppChooserDialog()->close(); - external_editor_info = getAppChooserDialog()->get_app_info(); - external_editor_native_command = false; + const auto app_info = getAppChooserDialog()->get_app_info(); + external_editor_info = { + app_info->get_name(), + app_info->get_commandline(), + false}; sendToExternal(); break; + } case Gtk::RESPONSE_CANCEL: case Gtk::RESPONSE_CLOSE: getAppChooserDialog()->close(); @@ -2781,7 +2787,9 @@ void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vecto send_to_external->insertEntry(i, "palette-brush.png", name, &send_to_external_radio_group); } } +#ifndef __APPLE__ send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER"), &send_to_external_radio_group); +#endif send_to_external->setSelected(selectedIndex); send_to_external->show(); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 309f14e8c..b895585ad 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -21,6 +21,7 @@ #include +#include "extprog.h" #include "histogrampanel.h" #include "history.h" #include "imageareapanel.h" @@ -252,8 +253,7 @@ private: Gtk::Button* navSync; Gtk::Button* navNext; Gtk::Button* navPrev; - Glib::RefPtr external_editor_info; - bool external_editor_native_command; + EditorInfo external_editor_info; std::unique_ptr app_chooser_dialog; ExternalEditorChangedSignal *externalEditorChangedSignal; sigc::connection externalEditorChangedSignalConnection; diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 5d9b45c5d..df48d1466 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -37,7 +37,9 @@ ExternalEditorPreferences::ExternalEditorPreferences(): list_view = Gtk::manage(new Gtk::TreeView()); list_view->set_model(list_model); list_view->append_column(*Gtk::manage(makeAppColumn())); +#ifndef __APPLE__ list_view->append_column(*Gtk::manage(makeNativeCommandColumn())); +#endif list_view->append_column(*Gtk::manage(makeCommandColumn())); for (auto &&column : list_view->get_columns()) { @@ -59,11 +61,18 @@ ExternalEditorPreferences::ExternalEditorPreferences(): button_remove = Gtk::manage(new Gtk::Button()); button_add->set_image(*add_image); button_remove->set_image(*remove_image); - button_app_chooser = Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE"))); + button_app_chooser = +#ifdef __APPLE__ + nullptr; +#else + Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE"))); +#endif button_file_chooser = Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE_FILE"))); - button_app_chooser->signal_pressed().connect(sigc::mem_fun( - *this, &ExternalEditorPreferences::openAppChooserDialog)); + if (button_app_chooser) { + button_app_chooser->signal_pressed().connect(sigc::mem_fun( + *this, &ExternalEditorPreferences::openAppChooserDialog)); + } button_add->signal_pressed().connect(sigc::mem_fun( *this, &ExternalEditorPreferences::addEditor)); button_file_chooser->signal_pressed().connect(sigc::mem_fun( @@ -77,7 +86,9 @@ ExternalEditorPreferences::ExternalEditorPreferences(): // Toolbar. toolbar.set_halign(Gtk::Align::ALIGN_END); - toolbar.add(*button_app_chooser); + if (button_app_chooser) { + toolbar.add(*button_app_chooser); + } toolbar.add(*button_file_chooser); toolbar.add(*button_add); toolbar.add(*button_remove); @@ -156,6 +167,9 @@ void ExternalEditorPreferences::addEditor() } row[model_columns.name] = "-"; +#ifdef __APPLE__ + row[model_columns.native_command] = true; +#endif list_view->get_selection()->select(row); } @@ -244,7 +258,12 @@ void ExternalEditorPreferences::onFileChooserDialogResponse( for (const auto &selected : selection) { auto row = *list_model->get_iter(selected); row[model_columns.icon] = Glib::RefPtr(nullptr); - row[model_columns.native_command] = false; + row[model_columns.native_command] = +#ifdef __APPLE__ + true; +#else + false; +#endif row[model_columns.command] = #ifdef WIN32 '"' + dialog->get_filename() + '"'; @@ -360,7 +379,9 @@ void ExternalEditorPreferences::setAppName( void ExternalEditorPreferences::updateToolbarSensitivity() { bool selected = list_view->get_selection()->count_selected_rows(); - button_app_chooser->set_sensitive(selected); + if (button_app_chooser) { + button_app_chooser->set_sensitive(selected); + } button_file_chooser->set_sensitive(selected); button_remove->set_sensitive(selected); } diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index ea1800638..4af8ceeed 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -344,13 +344,13 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName, const Glib } -bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo, bool nativeCommand) +bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const EditorInfo &editorInfo) { - if (nativeCommand) { + if (editorInfo.isNativeCommand) { if (rtengine::settings->verbose) { std::cout << "Launching external editor as native command." << std::endl; } - const Glib::ustring command = editorInfo->get_commandline(); + const Glib::ustring command = editorInfo.commandline; return openInCustomEditor(fileName, &command); } @@ -361,7 +361,10 @@ bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Gli bool success = false; try { - success = editorInfo->launch(Gio::File::create_for_path(fileName)); + Glib::RefPtr appInfo = + Gio::AppInfo::create_from_commandline( + editorInfo.commandline, editorInfo.name, Gio::APP_INFO_CREATE_NONE); + success = appInfo->launch(Gio::File::create_for_path(fileName)); } catch (const Glib::Error &e) { std::cerr << "Error launching external editor.\n" @@ -377,7 +380,7 @@ bool ExtProgStore::openInExternalEditor(const Glib::ustring &fileName, const Gli if (rtengine::settings->verbose) { std::cout << "Unable to launch external editor with Gio. Trying custom launcher." << std::endl; } - Glib::ustring command = editorInfo->get_commandline(); + Glib::ustring command = editorInfo.commandline; #if defined WIN32 if (command.length() > 2 && command[0] == '"' && command[command.length() - 1] == '"') { command = command.substr(1, command.length() - 2); diff --git a/rtgui/extprog.h b/rtgui/extprog.h index 5336c4703..df54f8cc5 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -42,6 +42,13 @@ struct ExtProgAction bool execute (const std::vector& fileNames) const; }; +struct EditorInfo +{ + Glib::ustring name; + Glib::ustring commandline; + bool isNativeCommand; +}; + // Stores all external programs that could be called by the user class ExtProgStore { @@ -70,7 +77,7 @@ public: static bool openInGimp (const Glib::ustring& fileName); static bool openInPhotoshop (const Glib::ustring& fileName); static bool openInCustomEditor (const Glib::ustring& fileName, const Glib::ustring* command = nullptr); - static bool openInExternalEditor(const Glib::ustring &fileName, const Glib::RefPtr &editorInfo, bool nativeCommand); + static bool openInExternalEditor(const Glib::ustring &fileName, const EditorInfo &editorInfo); }; #define extProgStore ExtProgStore::getInstance() From 961c2d09d5c56e701a7559eb8c331292b6ccd5ac Mon Sep 17 00:00:00 2001 From: Benitoite Date: Wed, 2 Aug 2023 16:05:45 -0700 Subject: [PATCH 302/326] Mac bundle: handle harfbuzz update Harfbuzz was recently upgraded and it broke the default link to graphite. --- tools/osx/macosx_bundle.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index ca381ec14..d5dd71319 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -225,8 +225,11 @@ ModifyInstallNames 2>&1 # Copy libpng16 to the app bundle cp ${LOCAL_PREFIX}/lib/libpng16.16.dylib "${CONTENTS}/Frameworks/libpng16.16.dylib" -# Copy libtiff 5 into the app bundle -cp ${LOCAL_PREFIX}/lib/libtiff.5.dylib "${CONTENTS}/Frameworks/libtiff.5.dylib" +# Copy graphite to Frameworks +cp ${LOCAL_PREFIX}/lib/libgraphite2.3.dylib "${CONTENTS}/Frameworks" + +# Copy libtiff 6 into the app bundle +cp ${LOCAL_PREFIX}/lib/libtiff.6.dylib "${CONTENTS}/Frameworks/libtiff.6.dylib" # Copy libomp to Frameworks cp ${LOCAL_PREFIX}/lib/libomp.dylib "${CONTENTS}/Frameworks" From 4f752154cf226d73c3c051c64eb822064b39d470 Mon Sep 17 00:00:00 2001 From: Hombre57 Date: Thu, 3 Aug 2023 20:12:52 +0200 Subject: [PATCH 303/326] Moving FileBrowserEntry static variable initialization to a dedicated method. Fixes a crash introduced by PR #5435. --- rtgui/filebrowserentry.cc | 19 +++++++++---------- rtgui/filebrowserentry.h | 2 +- rtgui/rtwindow.cc | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index b89fe340d..7df29dd92 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -37,7 +37,6 @@ //extern Glib::Threads::Thread* mainThread; -bool FileBrowserEntry::iconsLoaded(false); Glib::RefPtr FileBrowserEntry::editedIcon; Glib::RefPtr FileBrowserEntry::recentlySavedIcon; Glib::RefPtr FileBrowserEntry::enqueuedIcon; @@ -58,15 +57,6 @@ 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"); - iconsLoaded = true; - } - thumbnail->addThumbnailListener (this); } @@ -90,6 +80,15 @@ FileBrowserEntry::~FileBrowserEntry () } } +void FileBrowserEntry::init () +{ + 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"); +} + void FileBrowserEntry::refreshThumbnailImage () { diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 67b953514..f8fca4db1 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -50,7 +50,6 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase, { double scale; - static bool iconsLoaded; bool wasInside; ImageAreaToolListener* iatlistener; int press_x, press_y, action_x, action_y; @@ -80,6 +79,7 @@ public: FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); ~FileBrowserEntry () override; + static void init (); void draw (Cairo::RefPtr cc) override; void setImageAreaToolListener (ImageAreaToolListener* l) diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index d588d6aa5..dcfc2f05c 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -241,6 +241,7 @@ RTWindow::RTWindow () RTImage::init(); WhiteBalance::init(); MyExpander::init(); + FileBrowserEntry::init(); #ifndef WIN32 const std::vector> appIcons = { From 3d00f86b1684b4306503fc96fd0b07ac857f74d6 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 3 Aug 2023 22:03:40 -0700 Subject: [PATCH 304/326] Add language metadata description to README --- rtdata/languages/README | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rtdata/languages/README b/rtdata/languages/README index bffdb994b..68431b4ac 100644 --- a/rtdata/languages/README +++ b/rtdata/languages/README @@ -45,6 +45,13 @@ comments in the right order, e.g.: #01 Line 2... #02 3, etc. +Metadata for the language file appear in comments with the following syntax: + #10 @KEY=VALUE +The @ character must appear immediately after the whitespace following the +numeric prefix. KEY is the metadata name and VALUE is value for that metadata +name. The following key(s) are recognized: + a) LANGUAGE_DISPLAY_NAME: The language name as shown in preferences. + To create a file with only Latin characters from a non-Latin one, you can use sed with the "y" command. For example, to create a latin-only "Polish (Latin Characters)" file from the non-latin "Polish" one: From 7ad414aa63cbb57bf19ab54218ca56a813b863e9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 4 Aug 2023 22:32:39 -0700 Subject: [PATCH 305/326] Fix macOS external editor app chooser popping up --- rtgui/editorpanel.cc | 9 +++++---- rtgui/preferences.cc | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index d91e2d7e3..829bb21c5 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2030,7 +2030,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc, msgd.run (); saveimgas->set_sensitive (true); - send_to_external->set_sensitive(true); + send_to_external->set_sensitive(send_to_external->getEntryCount()); isProcessing = false; } @@ -2058,7 +2058,7 @@ bool EditorPanel::idle_imageSaved (ProgressConnector *pc, rtengine::IImagef } saveimgas->set_sensitive (true); - send_to_external->set_sensitive(true); + send_to_external->set_sensitive(send_to_external->getEntryCount()); parent->setProgressStr (""); parent->setProgress (0.); @@ -2390,7 +2390,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); saveimgas->set_sensitive (true); - send_to_external->set_sensitive(true); + send_to_external->set_sensitive(send_to_external->getEntryCount()); } return false; @@ -2411,7 +2411,7 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImagef if ((!img && Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR)) || (img && !errore)) { saveimgas->set_sensitive (true); - send_to_external->set_sensitive(true); + send_to_external->set_sensitive(send_to_external->getEntryCount()); parent->setProgressStr (""); parent->setProgress (0.); bool success = false; @@ -2790,6 +2790,7 @@ void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vecto #ifndef __APPLE__ send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER"), &send_to_external_radio_group); #endif + send_to_external->set_sensitive(send_to_external->getEntryCount()); send_to_external->setSelected(selectedIndex); send_to_external->show(); } diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c9737704e..ab155b7dd 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1755,7 +1755,12 @@ void Preferences::storePreferences() const std::vector &editors = externalEditors->getEditors(); moptions.externalEditors.resize(editors.size()); - moptions.externalEditorIndex = -1; + moptions.externalEditorIndex = +#ifdef __APPLE__ + editors.empty() ? -1 : 0; +#else + -1; +#endif for (unsigned i = 0; i < editors.size(); i++) { moptions.externalEditors[i] = (ExternalEditor( editors[i].name, editors[i].command, editors[i].native_command, editors[i].icon_serialized)); From c82369843e325782fcb43a2ee268c0cc0abd8bce Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 5 Aug 2023 10:11:54 -0700 Subject: [PATCH 306/326] Show icon in external editor button when disabled --- rtgui/editorpanel.cc | 1 + rtgui/popupcommon.cc | 24 ++++++++++++++++++++++-- rtgui/popupcommon.h | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 829bb21c5..6aae2f9a9 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -904,6 +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"); 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/popupcommon.cc b/rtgui/popupcommon.cc index a6d9b6046..2517a0a76 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -136,6 +136,21 @@ bool PopUpCommon::insertEntryImpl(int position, const Glib::ustring& fileName, c return true; } +void PopUpCommon::setEmptyImage(const Glib::ustring &fileName) +{ + emptyImageFilename = fileName; + + if (getEntryCount()) { + return; + } + if (fileName.empty()) { + buttonImage->hide(); + } else { + changeImage(emptyImageFilename, Glib::RefPtr()); + buttonImage->show(); + } +} + void PopUpCommon::removeEntry(int position) { if (position < 0 || position >= getEntryCount()) { @@ -147,8 +162,13 @@ void PopUpCommon::removeEntry(int position) button->get_style_context()->remove_class("Left"); arrowButton->hide(); hasMenu = false; - // Remove the button image. - buttonImage->hide(); + if (emptyImageFilename.empty()) { + // Remove the button image. + buttonImage->hide(); + } else { + // Show the empty icon. + changeImage(emptyImageFilename, Glib::RefPtr()); + } selected = -1; } else if (position < selected) { diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 9ca6b2030..228e0fba0 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -64,6 +64,8 @@ public: 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 insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); + /// Sets the button image to show when there are no entries. + void setEmptyImage(const Glib::ustring &fileName); int getEntryCount () const; bool setSelected (int entryNum); int getSelected () const; @@ -77,6 +79,7 @@ private: type_signal_changed messageChanged; type_signal_item_selected messageItemSelected; + Glib::ustring emptyImageFilename; std::vector> imageIcons; std::vector imageFilenames; std::vector images; From 8d0333120e8caec1364362b5516289bba879d6d1 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 6 Aug 2023 13:44:48 +0200 Subject: [PATCH 307/326] Research and development - WB auto -temperature correlation - tests - finding the optimum settings (#6643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change estimchrom estim hue final * Itcw observer checkbox * 8 spectral colors * 11 spectral colors * 6 spectral colors * Small change to correction green * Fixed various bad behavior - settings itcwb_deltaspec * 4 spectral colors green * 3 green spectral colors * 3 spectral colors green * 5 spectral colors red green * 3 spectral colors red green * 3 spectral colrs green red * Chnage slider choice deltaE - to size color patch * display more info in console * Display more info in console - comment code * Clean - comment code * 8 spectral colors green red * 8 spectral colors blue * 8 spectral colors blue * 3 spectral colors * 6 spectral colors * 4 spectal colors * 2 spectral colors * Eliminate high Y - increse temp iteration - recenter selection inside patch * compatibility 5.9 * Modify dislay and place selected dats in patch * Dispaly in console hue chroma image selection * First optimization * optimization code - clean unused variables * Remove sorted in chroma order - some others changes * 5.9 compatibility * Clean and optimize code * Clean code - more display info in console * More info in console - set itcwb_minsize in option * Display patch chroma in GUI * Change some default settings * Minsize patch GUI * Display GUI patch size * Chroma patch variations * Display in GUI min and max dats found in patch * Some adjustments * Remove too low datas in patch * Various improvment - ponderate * Clean code colortemp comment spectral datas * Comment code - correc gren * Comment and refine code * Fixed bug in improcoordinator * fixes a malfunction of AWB bias in improcoordinator * Various improvments - clean code * 2 improvments green and find patch * Allows parametrind ponder and Ypurple in options * Update autowb - filter on magenta purple * Clean and optimize code * Read colors in GUI * Denoise median 5x5 image datas before Itcwb * Change to GUI * Replace median5x5 by 2 median3x3 - clean GUI code * Work around to recalculate wbauto * Remove work around - change params->wb related change * Disabled low_sampling 5.9 * First try for compatibility Low sampling 5.9 * Re-enable WB autogrey * Change reference image to autogrey if camera settings probably out * Clean code aand adjust settings camera out * Format astylert rawimagesource.cc - various small adjustments * Small correction * Small green correction * Change default settings - correction to autowb bias in improccoordinator * Save provisory work * Save provisory work 2 * Try to find good tempitc with iterate when temptitc very different 5000K * Change 2 default settings * Work around awb temp bias * Limit work around bias - small other changes * 3 spectral colors deep blue * 4 spectral color deep blue * 4 color spectral yellow * 5 spectral colors neutral red-magenta * 5 spectral color neutral red magenta * Change threshold tempitc * 5.9 compatibility * Work around bad claculation Planck's formula * Fixed bad behavior when using blackbody spectal * 6 spectral color - checkbutton remove 2 passes * Fixed various bugs * Format rawimagesource.cc * Various improvment before to find the good selection * First new optimization (perhaps?) * Display GUI patc deltaE * Various optimzation and tooltip * Default observer 2°- Simplify GUI - improve display GUI - remove too low numbers datas * 4 spectral colors - change 2 settings * Change calculation threshold 2 passes * 6 spectral colors magenta * 13 spectral colors * Improvment GUI display * remove checkbutton no_purple * 2 spectral colors - remove in GUI low sampling 5.9 * Change default setting display in console * Change behavior when temp near stdA * 4 spectral colors - settings Itcwb_tempstdA * Gamut control on image histogram * Clean code and format rawimagesource.cc * Comment and format colortemp.cc * Remove unused fileds from GUI - change tooltips * Add tooltips * Various changes * Change settings when camera temperature is out * improvment extra and tooltip * Small change when using auto grey as start reference * Remove itcwb_fgreen from GUI * Various change - and 'unsatisfactory' test to take into account Custom * Change second temp when < 4000 - replace automatic by automatic and refinement * Neutralize 'Use custom tempertaure and green' * Green refinement * Clean code - small changes * Other clean code * Added forgotten itcw_green in procparams.cc * Fixed a bug dispaly deltaE * Change threshold settings - change code for Custom * various change in case of using camera settings * Change way to estimate range green * clean code and message in console * Clean and optimize * Disable 2 passes if custom * Improve GUI 2 passes * Increase sampling and number of temperature above 9400K * Hide AWB temperature bais and green refinement when Custom temerature ans green * marks out the code with past time markers * Improve time processing with spectral colors temp calculations * Replace in console msec by nsec * Scan temp 5.9 * Change max temp and behavior if temp > 15000k * Refine temp near 14000K * Increase sampling temperature 132 to 167 * Increase sampling temperature * Set in preference choice for itcwb_custom * White point calculated with observer instead of table * More on whitepoint calculation - informations * Clean and format code with astyle colortemp.cc rawimagesource.cc improccoordinator.cc * Small change tooltip * Improve update auto-wb * Remove 'use custom temperature and tin' - simplify sampling to 2 choice * Small change to rand AWB bias - green refinement - tooltips * slightly modify the parameters upstream of the algo - do not use camera in some cases * Mixed initial green * Refine init green and temp when no camera * Refine temp and green in do not use camera settings * Change tint threshold and various improvments (tooltips, wrong values..) * Refinment and clean code * Improve mode No use camera settings * Init nocam * Refine use no camera settings * Small change * 5.9 compatibility - and format * Refine sampling temperature around 7000 - 8000K * Format astylert rawimagesource colortemp * 5.9 settings * 5.9 settings 2 * Various change - 5.9 - format * Improve pre and post algorithm * Fixed correction temp > 8000K * Fixed bad behavior Tppat.minchroma * Change sampling choices and tooltip * Change name wp wp2 wip to wb wb2 iwb to avoid misunderstood * Small Change settings - limit display studgood to 0.0001 * Improvment display GUI temp * Change default sampling * Change ACESP0 to JDCmax * Improve GUI abstract profile * Allows dispaly in console xy values thanks to Reffort * Remove bruce rgb in wp and abstract * Change wp abstract and save itcwb with dispaly cellxy * Change prim = 13 improccoordinator iplab2rgb * remove display datas in console - fixed wrong display Y xyY * Fixed ifferences in GUI maxhist minhist * Change limits x y in function sampling * fixed a dizziness * Change after algorithm rule when temp > 6000K * Harmonize limx limy for oldsampling 5.9 * Added Cam xyz matrix to sampling - thanks to Reffort * Display in console xyz matrix * Forgotten instruction when mix camera and autowb grey * Change rgbloc with Camera matrix Dcraw when no input profile * Change rep to repref in rgbxyz * Remove message in console * 5.9 compat * 5.9 compat 2 * 5.9 compat 3 * 5.9 compat 4 * 5.9 compat 5 format * 5.9 compta 6 * Improve code * Diasble itcwb_sampling in GUI * Comment code * Clean and comment code * 5 spectral colors * 9 spectral colors * 2 spectral colors * Various improvments * 5 spectral colors * 5 spectral colors * First changes review lawrence37 * Second changes review Lawrence37 * 3rd changes review Lawrence37 * 4th changes review Lawrence37 * Change windows and appimage yml * Re-enable Rtv4_Bruce in procparams.cc * test for 5.9 compatibility * Try to fixed crash * Slightly improve the management of 5.9 * test for 5.9 compatibility by passing parameters via the GUI * Forgotten parameter * Change ref_spec limit and remove pac_start for itcwb_sampling * Puts back the old Planck formula - the same as in dev * Revert "test for 5.9 compatibility by passing parameters via the GUI" This reverts commit d6b5a8feda31b93a5574cee6ebf4d3e9d58bbcfb. * Switch to new ITCWB only when changing WB method Prevents sudden changing of the white balance if ITCWB is selected and the image is reopened. * Fix spelling in comment * Suggested change from Lawrence37 to whitebalance - small change to improcoordinator * tempbias Set_sentive(false) if itcwb_smapling - clean whitebalance * Another clean whitebalance.cc --------- Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 83 +- rtengine/camconst.json | 6 +- rtengine/colortemp.cc | 3123 +++++++++++++++++++++++----- rtengine/colortemp.h | 261 ++- rtengine/dcraw.cc | 3 +- rtengine/iccmatrices.h | 13 + rtengine/iccstore.cc | 6 +- rtengine/iimage.h | 2 +- rtengine/imagesource.h | 4 +- rtengine/improccoordinator.cc | 735 +++++-- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 2 +- rtengine/iplab2rgb.cc | 21 +- rtengine/procparams.cc | 52 +- rtengine/procparams.h | 11 +- rtengine/rawimagesource.cc | 3520 ++++++++++++++++++++++---------- rtengine/rawimagesource.h | 6 +- rtengine/rtengine.h | 2 +- rtengine/settings.h | 6 +- rtengine/stdimagesource.cc | 6 +- rtengine/stdimagesource.h | 4 +- rtgui/icmpanel.cc | 57 +- rtgui/icmpanel.h | 2 + rtgui/options.cc | 15 +- rtgui/paramsedited.cc | 48 +- rtgui/paramsedited.h | 10 +- rtgui/preferences.cc | 19 + rtgui/preferences.h | 4 +- rtgui/whitebalance.cc | 221 +- rtgui/whitebalance.h | 18 +- 32 files changed, 6275 insertions(+), 1990 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 6b286b68b..9ad9a6cbd 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' + publish_pre_dev_labels: '[]' jobs: build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index bdcd98c1c..fb0a45028 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' + publish_pre_dev_labels: '[]' jobs: build: runs-on: windows-2022 diff --git a/rtdata/languages/default b/rtdata/languages/default index 050836d21..2f372bf42 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1535,6 +1535,22 @@ 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_OBS;Remove algo 2 passes +HISTORY_MSG_WBITC_CUSTOM;Itcwb Custom +HISTORY_MSG_WBITC_SAMPLING;Low sampling +HISTORY_MSG_WBITC_THRES;Itcwb Theshold +HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple +HISTORY_MSG_WBITC_PRIM;Primaries +HISTORY_MSG_WBITC_SORTED;Itcwb ponderated +HISTORY_MSG_WBITC_FORCE;Itcwb Force +HISTORY_MSG_WBITC_SIZE;Itcwb Size +HISTORY_MSG_WBITC_PRECIS;Itcwb Precision +HISTORY_MSG_WBITC_DELTA;Itcwb Delta green +HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student +HISTORY_MSG_WBITC_RGREEN;Itcwb Green range +HISTORY_MSG_WBITC_MINSIZE;Patch min size +HISTORY_MSG_WBITC_PONDER;Itcwb ponderated +HISTORY_MSG_WBITC_GREEN;Grren refinement HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1841,6 +1857,17 @@ PREFERENCES_CHUNKSIZE_RGB;RGB processing PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Avoid artifacts 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_WBAPATCH;Number maximum of colors used in picture +PREFERENCES_WBAFORC;Forces Extra algoritm +PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) +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_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -2616,6 +2643,7 @@ 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 @@ -4077,7 +4105,7 @@ TP_WAVELET_WAVOFFSET;Offset TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Temperature correlation TP_WBALANCE_AUTOOLD;RGB grey -TP_WBALANCE_AUTO_HEADER;Automatic +TP_WBALANCE_AUTO_HEADER;Automatic & Refinement TP_WBALANCE_CAMERA;Camera TP_WBALANCE_CLOUDY;Cloudy TP_WBALANCE_CUSTOM;Custom @@ -4104,6 +4132,47 @@ TP_WBALANCE_FLUO_HEADER;Fluorescent TP_WBALANCE_GREEN;Tint TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI +TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop +TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. +//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram +TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram +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_ITCWB_FGREEN;Find green student +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_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. +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_ITCWBMINSIZEPATCH_TOOLTIP;Allows you to set the minimum patch value. values that are too low can lead to a lack of correlation. +TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple 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_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_ITCWB_ALG;Remove 2 pass algorithm +TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint +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_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. +TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used +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_ITCWB_PRIM_SRGB;Low sampling & No use Camera settings +TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling +TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - near Pointer's gamut +TP_WBALANCE_ITCWB_PRIM_REC;High sampling +TP_WBALANCE_ITCWB_PRIM_ACE;Forces use of the entire CIE diagram +TP_WBALANCE_ITCWB_PRIM_JDCMAX;Close to full CIE diagram +TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ matrix +TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax after Camera XYZ matrix +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_ITCWB_RGREEN;Green range +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_ITCWB_SAMPLING;Low sampling 5.9 +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_ITCWB_SIZE;Size of ref. color compare to histogram +TP_WBALANCE_ITCWB_SIZEPATCH;Size of color patch +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_ITCWB_THRES;Colors used in picture (preset) +TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;White Balance TP_WBALANCE_LAMP_HEADER;Lamp @@ -4115,6 +4184,10 @@ 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_SHADE;Shade TP_WBALANCE_SIZE;Size: @@ -4123,10 +4196,12 @@ TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Use the pipette to pick the white balance from a neutral patch in the preview. -TP_WBALANCE_STUDLABEL;Correlation factor: %1 -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. +TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 +TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 +TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 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'. +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. TP_WBALANCE_TEMPERATURE;Temperature TP_WBALANCE_TUNGSTEN;Tungsten TP_WBALANCE_WATER1;UnderWater 1 diff --git a/rtengine/camconst.json b/rtengine/camconst.json index a7e589416..217015e5f 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1755,7 +1755,7 @@ Camera constants: { // Quality B, lacks aperture and ISO scaling, known to exist, but little to gain as the levels are so close to white_max "make_model": "Nikon D7000", "dcraw_matrix": [ 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 ], // matrix provided by Tanveer(tsk1979) - //"dcraw_matrix": [ 8198, -2239, -725, -4871, 12388, 2798, -1043, 2050, 7181 ], // DNG v13.2 + // "dcraw_matrix": [ 8198, -2239, -725, -4871, 12388, 2798, -1043, 2050, 7181 ], // DNG v13.2 "ranges": { // measured at ISO 100. ISO differences not measured, but known to exist "white": [ 16300, 15700, 16300 ], // typical R 16383, G 15778, B 16383 @@ -2203,8 +2203,8 @@ Camera constants: { // Quality B "make_model": [ "Panasonic DC-LX100M2" ], - "dcraw_matrix": [ 11577, -4230, -1106, -3967, 12211, 1957, -759, 1762, 5610 ], // DNG v13.2 - //"dcraw_matrix": [ 8585, -3127, -833, -4005, 12250, 1953, -650, 1494, 4862 ], // DNG v13.2 alternate + //"dcraw_matrix": [ 11577, -4230, -1106, -3967, 12211, 1957, -759, 1762, 5610 ], // DNG v13.2 + "dcraw_matrix": [ 8585, -3127, -833, -4005, 12250, 1953, -650, 1494, 4862 ], // DNG v13.2 alternate "raw_crop": [ 0, 0, 0, 0 ], "ranges": { "black": 15 } }, diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 756fdf906..1c98b3e8b 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -71,127 +71,127 @@ static const color_match_type cie_colour_match_jd2 = {//350nm to 830nm 5 nm J. static const color_match_type cie_colour_match_jd = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. -{0.000000000000, 0.000000000000, 0.000000000000}, -{0.000000000000, 0.000000000000, 0.000000000000}, -{0.000000122200, 0.000000013398, 0.000000535027}, -{0.000000919270, 0.000000100650, 0.000004028300}, -{0.000005958600, 0.000000651100, 0.000026143700}, -{0.000033266000, 0.000003625000, 0.000146220000}, -{0.000159952000, 0.000017364000, 0.000704776000}, -{0.000662440000, 0.000071560000, 0.002927800000}, -{0.002361600000, 0.000253400000, 0.010482200000}, -{0.007242300000, 0.000768500000, 0.032344000000}, -{0.019109700000, 0.002004400000, 0.086010900000}, -{0.043400000000, 0.004509000000, 0.197120000000}, -{0.084736000000, 0.008756000000, 0.389366000000}, -{0.140638000000, 0.014456000000, 0.656760000000}, -{0.204492000000, 0.021391000000, 0.972542000000}, -{0.264737000000, 0.029497000000, 1.282500000000}, -{0.314679000000, 0.038676000000, 1.553480000000}, -{0.357719000000, 0.049602000000, 1.798500000000}, -{0.383734000000, 0.062077000000, 1.967280000000}, -{0.386726000000, 0.074704000000, 2.027300000000}, -{0.370702000000, 0.089456000000, 1.994800000000}, -{0.342957000000, 0.106256000000, 1.900700000000}, -{0.302273000000, 0.128201000000, 1.745370000000}, -{0.254085000000, 0.152761000000, 1.554900000000}, -{0.195618000000, 0.185190000000, 1.317560000000}, -{0.132349000000, 0.219940000000, 1.030200000000}, -{0.080507000000, 0.253589000000, 0.772125000000}, -{0.041072000000, 0.297665000000, 0.570060000000}, -{0.016172000000, 0.339133000000, 0.415254000000}, -{0.005132000000, 0.395379000000, 0.302356000000}, -{0.003816000000, 0.460777000000, 0.218502000000}, -{0.015444000000, 0.531360000000, 0.159249000000}, -{0.037465000000, 0.606741000000, 0.112044000000}, -{0.071358000000, 0.685660000000, 0.082248000000}, -{0.117749000000, 0.761757000000, 0.060709000000}, -{0.172953000000, 0.823330000000, 0.043050000000}, -{0.236491000000, 0.875211000000, 0.030451000000}, -{0.304213000000, 0.923810000000, 0.020584000000}, -{0.376772000000, 0.961988000000, 0.013676000000}, -{0.451584000000, 0.982200000000, 0.007918000000}, -{0.529826000000, 0.991761000000, 0.003988000000}, -{0.616053000000, 0.999110000000, 0.001091000000}, -{0.793832000000, 0.982380000000, 0.000000000000}, -{0.878655000000, 0.955552000000, 0.000000000000}, -{0.951162000000, 0.915175000000, 0.000000000000}, -{1.014160000000, 0.868934000000, 0.000000000000}, -{1.074300000000, 0.825623000000, 0.000000000000}, -{1.118520000000, 0.777405000000, 0.000000000000}, -{1.134300000000, 0.720353000000, 0.000000000000}, -{1.123990000000, 0.658341000000, 0.000000000000}, -{1.089100000000, 0.593878000000, 0.000000000000}, -{1.030480000000, 0.527963000000, 0.000000000000}, -{0.950740000000, 0.461834000000, 0.000000000000}, -{0.856297000000, 0.398057000000, 0.000000000000}, -{0.754930000000, 0.339554000000, 0.000000000000}, -{0.647467000000, 0.283493000000, 0.000000000000}, -{0.535110000000, 0.228254000000, 0.000000000000}, -{0.431567000000, 0.179828000000, 0.000000000000}, -{0.343690000000, 0.140211000000, 0.000000000000}, -{0.268329000000, 0.107633000000, 0.000000000000}, -{0.204300000000, 0.081187000000, 0.000000000000}, -{0.152568000000, 0.060281000000, 0.000000000000}, -{0.112210000000, 0.044096000000, 0.000000000000}, -{0.081260600000, 0.031800400000, 0.000000000000}, -{0.057930000000, 0.022601700000, 0.000000000000}, -{0.040850800000, 0.015905100000, 0.000000000000}, -{0.028623000000, 0.011130300000, 0.000000000000}, -{0.019941300000, 0.007748800000, 0.000000000000}, -{0.013842000000, 0.005375100000, 0.000000000000}, -{0.009576880000, 0.003717740000, 0.000000000000}, -{0.006605200000, 0.002564560000, 0.000000000000}, -{0.004552630000, 0.001768470000, 0.000000000000}, -{0.003144700000, 0.001222390000, 0.000000000000}, -{0.002174960000, 0.000846190000, 0.000000000000}, -{0.001505700000, 0.000586440000, 0.000000000000}, -{0.001044760000, 0.000407410000, 0.000000000000}, -{0.000727450000, 0.000284041000, 0.000000000000}, -{0.000508258000, 0.000198730000, 0.000000000000}, -{0.000356380000, 0.000139550000, 0.000000000000}, -{0.000250969000, 0.000098428000, 0.000000000000}, -{0.000177730000, 0.000069819000, 0.000000000000}, -{0.000126390000, 0.000049737000, 0.000000000000}, -{0.000090151000, 0.000035540500, 0.000000000000}, -{0.000064525800, 0.000025486000, 0.000000000000}, -{0.000046339000, 0.000018338400, 0.000000000000}, -{0.000033411700, 0.000013249000, 0.000000000000}, -{0.000024209000, 0.000009619600, 0.000000000000}, -{0.000017611500, 0.000007012800, 0.000000000000}, -{0.000012855000, 0.000005129800, 0.000000000000}, -{0.000009413630, 0.000003764730, 0.000000000000}, -{0.000006913000, 0.000002770810, 0.000000000000}, -{0.000005093470, 0.000002046130, 0.000000000000}, -{0.000003767100, 0.000001516770, 0.000000000000}, -{0.000002795310, 0.000001128090, 0.000000000000}, -{0.000002082000, 0.000000842160, 0.000000000000}, -{0.000001553140, 0.000000629700, 0.000000000000} + {0.000000000000, 0.000000000000, 0.000000000000}, + {0.000000000000, 0.000000000000, 0.000000000000}, + {0.000000122200, 0.000000013398, 0.000000535027}, + {0.000000919270, 0.000000100650, 0.000004028300}, + {0.000005958600, 0.000000651100, 0.000026143700}, + {0.000033266000, 0.000003625000, 0.000146220000}, + {0.000159952000, 0.000017364000, 0.000704776000}, + {0.000662440000, 0.000071560000, 0.002927800000}, + {0.002361600000, 0.000253400000, 0.010482200000}, + {0.007242300000, 0.000768500000, 0.032344000000}, + {0.019109700000, 0.002004400000, 0.086010900000}, + {0.043400000000, 0.004509000000, 0.197120000000}, + {0.084736000000, 0.008756000000, 0.389366000000}, + {0.140638000000, 0.014456000000, 0.656760000000}, + {0.204492000000, 0.021391000000, 0.972542000000}, + {0.264737000000, 0.029497000000, 1.282500000000}, + {0.314679000000, 0.038676000000, 1.553480000000}, + {0.357719000000, 0.049602000000, 1.798500000000}, + {0.383734000000, 0.062077000000, 1.967280000000}, + {0.386726000000, 0.074704000000, 2.027300000000}, + {0.370702000000, 0.089456000000, 1.994800000000}, + {0.342957000000, 0.106256000000, 1.900700000000}, + {0.302273000000, 0.128201000000, 1.745370000000}, + {0.254085000000, 0.152761000000, 1.554900000000}, + {0.195618000000, 0.185190000000, 1.317560000000}, + {0.132349000000, 0.219940000000, 1.030200000000}, + {0.080507000000, 0.253589000000, 0.772125000000}, + {0.041072000000, 0.297665000000, 0.570060000000}, + {0.016172000000, 0.339133000000, 0.415254000000}, + {0.005132000000, 0.395379000000, 0.302356000000}, + {0.003816000000, 0.460777000000, 0.218502000000}, + {0.015444000000, 0.531360000000, 0.159249000000}, + {0.037465000000, 0.606741000000, 0.112044000000}, + {0.071358000000, 0.685660000000, 0.082248000000}, + {0.117749000000, 0.761757000000, 0.060709000000}, + {0.172953000000, 0.823330000000, 0.043050000000}, + {0.236491000000, 0.875211000000, 0.030451000000}, + {0.304213000000, 0.923810000000, 0.020584000000}, + {0.376772000000, 0.961988000000, 0.013676000000}, + {0.451584000000, 0.982200000000, 0.007918000000}, + {0.529826000000, 0.991761000000, 0.003988000000}, + {0.616053000000, 0.999110000000, 0.001091000000}, + {0.793832000000, 0.982380000000, 0.000000000000}, + {0.878655000000, 0.955552000000, 0.000000000000}, + {0.951162000000, 0.915175000000, 0.000000000000}, + {1.014160000000, 0.868934000000, 0.000000000000}, + {1.074300000000, 0.825623000000, 0.000000000000}, + {1.118520000000, 0.777405000000, 0.000000000000}, + {1.134300000000, 0.720353000000, 0.000000000000}, + {1.123990000000, 0.658341000000, 0.000000000000}, + {1.089100000000, 0.593878000000, 0.000000000000}, + {1.030480000000, 0.527963000000, 0.000000000000}, + {0.950740000000, 0.461834000000, 0.000000000000}, + {0.856297000000, 0.398057000000, 0.000000000000}, + {0.754930000000, 0.339554000000, 0.000000000000}, + {0.647467000000, 0.283493000000, 0.000000000000}, + {0.535110000000, 0.228254000000, 0.000000000000}, + {0.431567000000, 0.179828000000, 0.000000000000}, + {0.343690000000, 0.140211000000, 0.000000000000}, + {0.268329000000, 0.107633000000, 0.000000000000}, + {0.204300000000, 0.081187000000, 0.000000000000}, + {0.152568000000, 0.060281000000, 0.000000000000}, + {0.112210000000, 0.044096000000, 0.000000000000}, + {0.081260600000, 0.031800400000, 0.000000000000}, + {0.057930000000, 0.022601700000, 0.000000000000}, + {0.040850800000, 0.015905100000, 0.000000000000}, + {0.028623000000, 0.011130300000, 0.000000000000}, + {0.019941300000, 0.007748800000, 0.000000000000}, + {0.013842000000, 0.005375100000, 0.000000000000}, + {0.009576880000, 0.003717740000, 0.000000000000}, + {0.006605200000, 0.002564560000, 0.000000000000}, + {0.004552630000, 0.001768470000, 0.000000000000}, + {0.003144700000, 0.001222390000, 0.000000000000}, + {0.002174960000, 0.000846190000, 0.000000000000}, + {0.001505700000, 0.000586440000, 0.000000000000}, + {0.001044760000, 0.000407410000, 0.000000000000}, + {0.000727450000, 0.000284041000, 0.000000000000}, + {0.000508258000, 0.000198730000, 0.000000000000}, + {0.000356380000, 0.000139550000, 0.000000000000}, + {0.000250969000, 0.000098428000, 0.000000000000}, + {0.000177730000, 0.000069819000, 0.000000000000}, + {0.000126390000, 0.000049737000, 0.000000000000}, + {0.000090151000, 0.000035540500, 0.000000000000}, + {0.000064525800, 0.000025486000, 0.000000000000}, + {0.000046339000, 0.000018338400, 0.000000000000}, + {0.000033411700, 0.000013249000, 0.000000000000}, + {0.000024209000, 0.000009619600, 0.000000000000}, + {0.000017611500, 0.000007012800, 0.000000000000}, + {0.000012855000, 0.000005129800, 0.000000000000}, + {0.000009413630, 0.000003764730, 0.000000000000}, + {0.000006913000, 0.000002770810, 0.000000000000}, + {0.000005093470, 0.000002046130, 0.000000000000}, + {0.000003767100, 0.000001516770, 0.000000000000}, + {0.000002795310, 0.000001128090, 0.000000000000}, + {0.000002082000, 0.000000842160, 0.000000000000}, + {0.000001553140, 0.000000629700, 0.000000000000} }; -ColorTemp::ColorTemp (double t, double g, double e, const std::string &m, StandardObserver o) : temp(t), green(g), equal(e), method(m), observer(o) +ColorTemp::ColorTemp(double t, double g, double e, const std::string &m, StandardObserver o) : temp(t), green(g), equal(e), method(m), observer(o) { - clip (temp, green, equal); + clip(temp, green, equal); } -void ColorTemp::clip (double &temp, double &green) +void ColorTemp::clip(double &temp, double &green) { temp = rtengine::LIM(temp, MINTEMP, MAXTEMP); green = rtengine::LIM(green, MINGREEN, MAXGREEN); } -void ColorTemp::clip (double &temp, double &green, double &equal) +void ColorTemp::clip(double &temp, double &green, double &equal) { temp = rtengine::LIM(temp, MINTEMP, MAXTEMP); green = rtengine::LIM(green, MINGREEN, MAXGREEN); equal = rtengine::LIM(equal, MINEQUAL, MAXEQUAL); } -ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e, StandardObserver observer) : equal(e), method("Custom"), observer(observer) +ColorTemp::ColorTemp(double mulr, double mulg, double mulb, double e, StandardObserver observer) : equal(e), method("Custom"), observer(observer) { - mul2temp (mulr, mulg, mulb, equal, observer, temp, green); + mul2temp(mulr, mulg, mulb, equal, observer, temp, green); } ColorTemp ColorTemp::convertObserver(StandardObserver observer) const @@ -199,6 +199,7 @@ ColorTemp ColorTemp::convertObserver(StandardObserver observer) const if (observer == this->observer) { return *this; } + double r; double g; double b; @@ -206,7 +207,7 @@ ColorTemp ColorTemp::convertObserver(StandardObserver observer) const return ColorTemp(r, g, b, equal, observer); } -void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, double& temp, double& green) const +void ColorTemp::mul2temp(const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, double& temp, double& green) const { double maxtemp = MAXTEMP, mintemp = MINTEMP; @@ -214,7 +215,7 @@ void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmu temp = (maxtemp + mintemp) / 2; while (maxtemp - mintemp > 1) { - temp2mul (temp, 1.0, equal, observer, tmpr, tmpg, tmpb); + temp2mul(temp, 1.0, equal, observer, tmpr, tmpg, tmpb); if (tmpb / tmpr > bmul / rmul) { maxtemp = temp; @@ -226,7 +227,7 @@ void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmu } green = (tmpg / tmpr) / (gmul / rmul); - clip (temp, green); + clip(temp, green); } @@ -441,41 +442,40 @@ const double ColorTemp::Flash6500_spect[97] = { 55.72, 51.97, 54.72, 57.46, 58.89, 60.33 }; -const std::map ColorTemp::spectMap = { - {"Daylight", Daylight5300_spect}, - {"Cloudy", Cloudy6200_spect}, - {"Shade", Shade7600_spect}, - {"Tungsten", A2856_spect}, - {"Fluo F1", FluoF1_spect}, - {"Fluo F2", FluoF2_spect}, - {"Fluo F3", FluoF3_spect}, - {"Fluo F4", FluoF4_spect}, - {"Fluo F5", FluoF5_spect}, - {"Fluo F6", FluoF6_spect}, - {"Fluo F7", FluoF7_spect}, - {"Fluo F8", FluoF8_spect}, - {"Fluo F9", FluoF9_spect}, - {"Fluo F10", FluoF10_spect}, - {"Fluo F11", FluoF11_spect}, - {"Fluo F12", FluoF12_spect}, - {"HMI Lamp", HMI_spect}, - {"GTI Lamp", GTI_spect}, - {"JudgeIII Lamp", JudgeIII_spect}, - {"Solux Lamp 3500K", Solux3500_spect}, - {"Solux Lamp 4100K", Solux4100_spect}, - {"Solux Lamp 4700K", Solux4700_spect}, - {"NG Solux Lamp 4700K", NG_Solux4700_spect}, - {"LED LSI Lumelex 2040", NG_LEDLSI2040_spect}, - {"LED CRS SP12 WWMR16", NG_CRSSP12WWMR16_spect}, - {"Flash 5500K", Flash5500_spect}, - {"Flash 6000K", Flash6000_spect}, - {"Flash 6500K", Flash6500_spect} - }; +const std::map ColorTemp::spectMap = { + {"Daylight", Daylight5300_spect}, + {"Cloudy", Cloudy6200_spect}, + {"Shade", Shade7600_spect}, + {"Tungsten", A2856_spect}, + {"Fluo F1", FluoF1_spect}, + {"Fluo F2", FluoF2_spect}, + {"Fluo F3", FluoF3_spect}, + {"Fluo F4", FluoF4_spect}, + {"Fluo F5", FluoF5_spect}, + {"Fluo F6", FluoF6_spect}, + {"Fluo F7", FluoF7_spect}, + {"Fluo F8", FluoF8_spect}, + {"Fluo F9", FluoF9_spect}, + {"Fluo F10", FluoF10_spect}, + {"Fluo F11", FluoF11_spect}, + {"Fluo F12", FluoF12_spect}, + {"HMI Lamp", HMI_spect}, + {"GTI Lamp", GTI_spect}, + {"JudgeIII Lamp", JudgeIII_spect}, + {"Solux Lamp 3500K", Solux3500_spect}, + {"Solux Lamp 4100K", Solux4100_spect}, + {"Solux Lamp 4700K", Solux4700_spect}, + {"NG Solux Lamp 4700K", NG_Solux4700_spect}, + {"LED LSI Lumelex 2040", NG_LEDLSI2040_spect}, + {"LED CRS SP12 WWMR16", NG_CRSSP12WWMR16_spect}, + {"Flash 5500K", Flash5500_spect}, + {"Flash 6000K", Flash6000_spect}, + {"Flash 6500K", Flash6500_spect} +}; // Data for Color ==> CRI (Color Rendering Index and Palette // actually 20 color that must be good enough for CRI -// I think 40 color for palette (Skin, Sky, gray) //spectral data Colorchecker24 : Red C3 const double ColorTemp::ColorchechredC3_spect[97] = { @@ -517,7 +517,7 @@ const double ColorTemp::ColorGreenM25_spect[97] = { 0.1758, 0.1673, 0.1606, 0.1505, 0.1384, 0.1317, 0.1230, 0.1149, 0.1081, 0.0992, 0.0882, 0.0785, 0.0709, 0.0629, 0.0550, 0.0502, 0.0486, 0.0474, 0.0445, 0.0434, 0.0429, 0.0423, 0.0411, 0.0405, 0.0397, 0.0387, 0.0399, 0.0398, 0.0398, 0.0407, 0.0408, 0.0426, 0.0445, 0.0443, 0.0468, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0 658 45 0 0 131 98 84 123 104 131 112 121 121 139 128 148 199 296 389 476 689 945 1132 1326 1490 1674 1741 1775 1868 1914 1928 1961 1972 1992 2045 2064 2053 2048 2072 2086 2081 2069 2056 2073 2096 2114 2067 2089 2100 2061 2019 1983 1971 1961 2016 1956 1946 1922 1983 1991 + const double ColorTemp::ColorYellowkeltano_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0658, 0.0045, 0.0, 0.0, 0.0131, 0.0098, 0.0084, 0.0123, 0.0104, 0.0131, 0.0112, 0.0121, 0.0121, 0.0139, @@ -535,8 +535,7 @@ const double ColorTemp::ColorGreenalsi_spect[97] = { 0.0424, 0.0417, 0.0389, 0.0380, 0.0378, 0.0371, 0.0350, 0.0333, 0.0350, 0.0394, 0.0379, 0.0446, 0.0491, 0.0575, 0.0734, 0.0953, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//1890 1097 855 899 987 881 807 804 787 691 643 549 465 404 385 302 244 195 165 159 123 129 108 111 114 126 126 134 162 170 213 248 279 351 412 566 752 909 1069 1270 1526 -//1707 1858 1999 2112 2293 2422 2471 2611 2718 2710 2778 2807 2825 2856 2909 2901 2974 3042 3044 3075 + const double ColorTemp::ColorRedpetunia_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1890, 0.1097, 0.0855, 0.0899, 0.0987, 0.0881, 0.0807, 0.0804, 0.0787, 0.0691, 0.0643, 0.0549, 0.0465, 0.0404, 0.0385, @@ -546,7 +545,6 @@ const double ColorTemp::ColorRedpetunia_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.1588 0.1980 0.2789 0.4585 0.6059 0.6609 0.6674 0.6599 0.6551 0.6472 0.6423 0.6485 0.6515 0.6379 0.6193 0.6121 0.6026 0.5678 0.5310 0.5245 0.5305 0.5324 0.5262 0.5219 0.5247 0.5312 0.5436 0.5634 0.5832 0.5943 0.5953 0.5902 0.5805 0.5754 0.5901 0.6262 const double ColorTemp::JDC468_B14_75Redspect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -567,8 +565,6 @@ const double ColorTemp::ColorRedkurttu_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#light red flower (lupiini) -//1792 1553 1684 1882 1909 1847 2053 2084 2045 2052 2039 2084 2041 2044 2007 1984 1906 1876 1886 1855 1859 1875 1816 1800 1811 1780 1802 1816 1838 1915 1973 2018 2083 2114 2133 2226 2304 2385 2458 2494 2571 2689 2738 2774 2734 2759 2781 2831 2844 2857 2878 2876 2884 2920 2932 2860 2894 2934 2925 2928 2921 const double ColorTemp::ColorRedlupiini_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1792, 0.1553, 0.1684, 0.1882, 0.1909, 0.1847, 0.2053, 0.2084, 0.2045, 0.2052, 0.2039, 0.2084, 0.2041, 0.2044, 0.2007, 0.1984, 0.1906, 0.1876, @@ -577,8 +573,6 @@ const double ColorTemp::ColorRedlupiini_spect[97] = { 0.2932, 0.2860, 0.2894, 0.2934, 0.2925, 0.2928, 0.2921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red flower (hevosminttu) -//1280 706 612 462 391 339 253 285 261 264 239 208 201 186 185 161 156 149 146 148 161 144 143 151 147 146 139 148 173 185 185 197 222 238 283 322 384 439 519 633 792 922 1061 1186 1235 1342 1538 1691 1839 1974 2024 2098 2128 2187 2204 2217 2267 2299 2339 2331 2322 const double ColorTemp::ColorRedhevosminttu_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1280, 0.0706, 0.0612, 0.0462, 0.0391, 0.0339, 0.0253, 0.0285, 0.0261, 0.0264, 0.0239, 0.0208, 0.0201, 0.0186, 0.0185, 0.0161, 0.0156, 0.0149, @@ -587,8 +581,6 @@ const double ColorTemp::ColorRedhevosminttu_spect[97] = { 0.2217, 0.2267, 0.2299, 0.2339, 0.2331, 0.2322, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red flower (neilikka) -//0 0 394 0 245 95 174 149 194 171 181 175 172 167 147 137 107 108 100 87 93 87 83 77 80 67 72 64 83 84 88 90 91 94 114 133 178 241 309 419 612 823 992 1153 1222 1366 1503 1658 1767 1841 1884 1992 2035 2007 2009 2045 2065 2229 2290 2395 2449 const double ColorTemp::ColorRedneilikka_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0394, 0.0, 0.0245, 0.0095, 0.0174, 0.0149, 0.0194, 0.0171, 0.0181, 0.0175, 0.0172, 0.0167, 0.0147, 0.0137, 0.0107, 0.0108, 0.0100, @@ -598,8 +590,6 @@ const double ColorTemp::ColorRedneilikka_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red petal (pelargonia) -//2529 2048 2087 2698 2452 2372 2531 2475 2296 2294 2159 2111 1986 1898 1854 1729 1586 1501 1392 1332 1343 1255 1217 1182 1183 1203 1230 1277 1381 1474 1615 1762 1876 2028 2214 2464 2657 2919 3051 3172 3293 3421 3395 3494 3438 3495 3506 3490 3454 3487 3431 3452 3484 3438 3422 3368 3325 3441 3356 3432 3320 const double ColorTemp::ColorRedpelagornia_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2529, 0.2048, 0.2087, 0.2698, 0.2452, 0.2372, 0.2531, 0.2475, 0.2296, 0.2294, 0.2159, 0.2111, 0.1986, 0.1898, 0.1854, 0.1729, 0.1586, 0.1501, 0.1392, 0.1332, 0.1343, @@ -608,8 +598,6 @@ const double ColorTemp::ColorRedpelagornia_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red flower (talvio) -//3131 2199 2559 2540 2844 2530 2694 2765 2594 2673 2617 2629 2491 2384 2308 2256 2081 1973 1857 1752 1719 1652 1527 1477 1459 1386 1341 1283 1318 1334 1354 1424 1495 1543 1634 1773 1950 2129 2272 2431 2642 2827 2941 3045 3082 3158 3216 3307 3364 3388 3387 3517 3573 3501 3499 3523 3495 3606 3493 3518 3522 const double ColorTemp::ColorRedtalvio_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3131, 0.2199, 0.2559, 0.2540, 0.2844, 0.2530, 0.2694, 0.2765, 0.2594, 0.2673, 0.2617, 0.2629, 0.2491, 0.2384, 0.2308, 0.2256, 0.2081, 0.1973, 0.1857, 0.1752, 0.1719, @@ -619,9 +607,6 @@ const double ColorTemp::ColorRedtalvio_spect[97] = { }; -//#brown dry leaf (poimulehti) -//964 520 223 244 261 247 196 199 200 207 202 198 209 204 207 222 205 218 213 212 224 218 230 235 251 250 245 250 263 273 271 275 281 264 274 288 287 307 303 307 323 304 335 335 346 345 347 348 370 364 380 393 384 407 419 421 419 433 431 461 465 -//RIs 67 const double ColorTemp::ColorBrownpoimulehti_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0964, 0.0520, 0.0223, 0.0244, 0.0261, 0.0247, 0.0196, 0.0199, 0.0200, 0.0207, 0.0202, 0.0198, 0.0209, 0.0204, 0.0207, 0.0222, 0.0205, 0.0218, 0.0213, @@ -631,8 +616,6 @@ const double ColorTemp::ColorBrownpoimulehti_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#orange leaf (koristepensas, tuntematon) -//241 195 223 489 574 565 634 605 574 613 645 636 644 628 621 603 614 654 676 719 776 795 862 879 918 918 955 980 1013 1055 1132 1225 1258 1362 1427 1579 1796 1936 2079 2258 2440 2597 2728 2790 2777 2857 2923 2991 3031 3040 3037 3094 3066 3023 3093 3044 3082 3085 3147 3226 3192 const double ColorTemp::ColorOrangetuntematon_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0241, 0.0195, 0.0223, 0.0489, 0.0574, 0.0565, 0.0634, 0.0605, 0.0574, 0.0613, 0.0645, 0.0636, 0.0644, 0.0628, 0.0621, 0.0603, 0.0614, 0.0654, 0.0676, @@ -640,8 +623,7 @@ const double ColorTemp::ColorOrangetuntematon_spect[97] = { 0.2258, 0.2440, 0.2597, 0.2728, 0.2790, 0.2777, 0.2857, 0.2923, 0.2991, 0.3031, 0.3040, 0.3037, 0.3094, 0.3066, 0.3023, 0.3093, 0.3044, 0.3082, 0.3085, 0.3147, 0.3226, 0.3192, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//,#orange leaf (lehmus) -//1062 866 443 544 496 485 492 458 450 425 458 477 497 461 451 481 454 500 515 538 529 593 638 670 686 711 718 729 741 760 796 833 895 958 1016 1128 1246 1344 1450 1505 1596 1636 1621 1631 1627 1628 1658 1583 1486 1415 1322 1265 1159 1062 975 974 1063 1326 1736 2141 2568 + const double ColorTemp::ColorOrangetlehmus_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1062, 0.0866, 0.0443, 0.0544, 0.0496, 0.0485, 0.0492, 0.0458, 0.0450, 0.0425, 0.0458, 0.0477, 0.0497, 0.0461, 0.0451, 0.0481, 0.0454, 0.0500, 0.0515, @@ -650,8 +632,6 @@ const double ColorTemp::ColorOrangetlehmus_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#orange leaf (vaahtera) -//1517 551 664 659 521 585 460 385 424 389 375 374 359 380 371 373 379 387 378 394 405 416 463 496 536 542 577 579 619 642 678 710 777 829 894 1035 1174 1334 1484 1611 1798 1941 2012 2065 2135 2229 2286 2317 2332 2357 2323 2330 2292 2236 2137 2093 2180 2240 2368 2487 2528 const double ColorTemp::ColorOrangvaahtera_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1517, 0.0551, 0.0664, 0.0659, 0.0521, 0.0585, 0.0460, 0.0385, 0.0424, 0.0389, 0.0375, 0.0374, 0.0359, 0.0380, 0.0371, 0.0373, 0.0379, 0.0387, 0.0378, @@ -660,8 +640,6 @@ const double ColorTemp::ColorOrangvaahtera_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#brown dry leaf (lehmus) -//758 236 148 430 347 435 438 495 439 454 472 471 461 459 458 479 492 482 499 513 520 545 567 594 623 647 698 717 744 792 803 834 864 876 916 932 963 1013 1025 1060 1099 1118 1153 1175 1207 1242 1268 1266 1284 1305 1305 1304 1353 1360 1330 1332 1413 1502 1610 1682 1737 const double ColorTemp::ColorBrownlehmus_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0758, 0.0236, 0.0148, 0.0430, 0.0347, 0.0435, 0.0438, 0.0495, 0.0439, 0.0454, 0.0472, 0.0471, 0.0461, 0.0459, 0.0458, 0.0479, 0.0492, 0.0482, 0.0499, 0.0513, @@ -670,9 +648,6 @@ const double ColorTemp::ColorBrownlehmus_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#brown moss (nuotiosammal) -//482 260 178 92 104 88 92 40 43 52 58 64 70 63 67 67 62 76 82 82 91 96 104 116 135 141 142 155 168 179 198 199 193 201 212 218 226 240 242 238 255 265 277 266 265 283 289 275 289 277 291 288 277 252 262 260 264 299 375 411 446 const double ColorTemp::ColorBrownuotiosammal_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0482, 0.0260, 0.0178, 0.0092, 0.0104, 0.0088, 0.0092, 0.0040, 0.0043, 0.0052, 0.0058, 0.0064, 0.0070, 0.0063, 0.0067, 0.0067, 0.0062, 0.0076, 0.0082, 0.0082, 0.0091, 0.0096, @@ -681,8 +656,6 @@ const double ColorTemp::ColorBrownuotiosammal_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#black soil -//0 0 89 122 52 53 104 127 130 134 137 137 134 136 138 139 134 140 142 148 154 153 152 150 151 156 153 166 154 171 163 163 166 166 169 169 166 174 174 170 170 168 176 177 176 174 179 180 180 183 177 193 178 187 194 193 182 196 184 195 195 const double ColorTemp::ColorBlacksoil_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0089, 0.0122, 0.0052, 0.0053, 0.0104, 0.0127, 0.0130, 0.0134, 0.0137, 0.0137, 0.0134, 0.0136, 0.0138, 0.0139, 0.0134, 0.0140, 0.0142, 0.0148, 0.0154, 0.0153, @@ -691,8 +664,6 @@ const double ColorTemp::ColorBlacksoil_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#black, dry leaf (pihlaja) -//0 79 111 172 174 201 214 211 207 207 191 200 196 206 196 194 203 207 204 208 210 212 211 208 209 219 222 224 231 241 232 244 249 250 267 264 262 269 282 277 289 284 279 302 289 308 313 315 310 325 313 319 356 340 331 347 356 352 364 373 352 const double ColorTemp::ColorBlackpihlaja[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0079, 0.0111, 0.0172, 0.0174, 0.0201, 0.0214, 0.0211, 0.0207, 0.0207, 0.0191, 0.0200, 0.0196, 0.0206, 0.0196, 0.0194, 0.0203, 0.0207, 0.0204, 0.0208, 0.0210, 0.0212, @@ -701,11 +672,6 @@ const double ColorTemp::ColorBlackpihlaja[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//#gray lichen (nahkajaekaelae) -//1204 585 1113 733 600 653 715 685 726 682 713 691 719 691 683 693 711 715 701 700 720 697 706 696 723 714 726 738 729 735 737 739 742 746 746 761 743 735 722 717 728 749 721 712 705 737 733 758 780 785 775 771 755 744 743 742 755 779 849 940 1042 -//RIS 74 const double ColorTemp::ColorGraynahjajaekaelae_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1204, 0.0585, 0.1113, 0.0733, 0.0600, 0.0653, 0.0715, 0.0685, 0.0726, 0.0682, 0.0713, 0.0691, 0.0719, 0.0691, 0.0683, 0.0693, 0.0711, 0.0715, 0.0701, 0.0700, @@ -714,8 +680,6 @@ const double ColorTemp::ColorGraynahjajaekaelae_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green moss (nuotiosammal) -//120 65 134 31 209 124 104 96 97 95 76 79 83 93 83 95 95 104 117 127 140 161 214 252 290 310 328 343 347 373 365 351 347 343 311 301 285 283 263 256 255 251 257 235 227 224 233 208 194 186 165 160 151 149 157 161 185 243 309 425 543 const double ColorTemp::ColorGreennuotisammal_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0120, 0.0065, 0.0134, 0.0031, 0.0209, 0.0124, 0.0104, 0.0096, 0.0097, 0.0095, 0.0076, 0.0079, 0.0083, 0.0093, 0.0083, 0.0095, 0.0095, 0.0104, 0.0117, 0.0127, 0.0140, 0.0161, @@ -724,9 +688,6 @@ const double ColorTemp::ColorGreennuotisammal_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#green leaf (leskenlehti) -//525 273 0 378 318 164 224 276 316 266 303 290 305 286 290 303 323 323 352 383 405 482 614 743 920 1015 1139 1192 1175 1216 1195 1145 1116 1009 947 867 802 754 741 709 675 625 574 579 561 565 557 511 471 419 399 372 365 395 375 382 458 555 716 1002 1407 const double ColorTemp::ColorGreenleskenlehti_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0525, 0.0273, 0.0, 0.0378, 0.0318, 0.0164, 0.0224, 0.0276, 0.0316, 0.0266, 0.0303, 0.0290, 0.0305, 0.0286, 0.0290, 0.0303, 0.0323, 0.0323, 0.0352, 0.0383, 0.0405, 0.0482, @@ -735,9 +696,6 @@ const double ColorTemp::ColorGreenleskenlehti_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green leaf (linnunkaali) -//602 0 267 306 339 335 300 247 292 289 295 298 292 318 312 289 299 307 310 320 350 375 446 499 574 634 698 725 736 754 736 702 668 633 590 551 514 499 467 460 445 424 415 409 399 412 393 380 370 362 366 343 342 350 333 350 364 418 494 670 914 -//RIS 77 const double ColorTemp::ColorGreenlinnunkaali_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0602, 0.0, 0.0267, 0.0306, 0.0339, 0.0335, 0.0300, 0.0247, 0.0292, 0.0289, 0.0295, 0.0298, 0.0292, 0.0318, 0.0312, 0.0289, 0.0299, 0.0307, 0.0310, 0.0320, @@ -745,8 +703,7 @@ const double ColorTemp::ColorGreenlinnunkaali_spect[97] = { 0.0445, 0.0424, 0.0415, 0.0409, 0.0399, 0.0412, 0.0393, 0.0380, 0.0370, 0.0362, 0.0366, 0.0343, 0.0342, 0.0350, 0.0333, 0.0350, 0.0364, 0.0418, 0.0494, 0.0670, 0.0914, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green leaf (pelto-ohake) -//0 366 360 233 173 179 157 175 206 205 180 179 173 178 187 189 184 171 195 204 193 219 253 297 365 431 467 489 493 516 500 466 426 406 380 343 316 295 276 282 265 253 239 228 226 229 238 237 216 221 219 217 212 219 229 258 284 309 375 487 732 + const double ColorTemp::ColorGreenpelto_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0366, 0.0360, 0.0233, 0.0173, 0.0179, 0.0157, 0.0175, 0.0206, 0.0205, 0.0180, 0.0179, 0.0173, 0.0178, 0.0187, 0.0189, 0.0184, 0.0171, 0.0195, 0.0204, 0.0193, 0.0219, @@ -755,8 +712,6 @@ const double ColorTemp::ColorGreenpelto_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green rod (voikukka), -//2205 1755 1710 1365 1159 1207 1024 1118 1127 1141 1134 1125 1149 1140 1120 1128 1139 1156 1212 1273 1262 1359 1461 1519 1568 1599 1660 1668 1680 1718 1697 1690 1672 1675 1663 1644 1642 1652 1626 1623 1653 1621 1614 1590 1625 1609 1615 1576 1509 1483 1418 1391 1324 1294 1267 1220 1315 1417 1650 1861 2006 const double ColorTemp::ColorGreenrodvoikukka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2205, 0.1755, 0.1710, 0.1365, 0.1159, 0.1207, 0.1024, 0.1118, 0.1127, 0.1141, 0.1134, 0.1125, 0.1149, 0.1140, 0.1120, 0.1128, 0.1139, 0.1156, 0.1212, 0.1273, 0.1262, 0.1359, @@ -765,8 +720,6 @@ const double ColorTemp::ColorGreenrodvoikukka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green leaf (lehmus) -//2362 1024 945 666 617 604 591 580 648 631 656 607 616 653 643 626 643 656 710 753 801 929 1105 1277 1437 1601 1742 1774 1798 1848 1832 1820 1787 1730 1663 1593 1541 1461 1446 1419 1335 1298 1247 1192 1197 1199 1156 1072 1007 942 899 832 824 793 755 801 860 1031 1305 1809 2260 const double ColorTemp::ColorGreenlehmus[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2362, 0.1024, 0.0945, 0.0666, 0.0617, 0.0604, 0.0591, 0.0580, 0.0648, 0.0631, 0.0656, 0.0607, 0.0616, 0.0653, 0.0643, 0.0626, 0.0643, 0.0656, 0.0710, 0.0753, @@ -775,8 +728,6 @@ const double ColorTemp::ColorGreenlehmus[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green leaf (koristeherukka) -//945 292 315 433 321 294 295 321 278 261 282 272 270 278 285 274 277 268 269 283 275 309 325 389 450 493 551 557 587 585 567 554 515 487 460 424 409 387 353 349 353 333 309 309 312 315 321 298 304 304 281 273 293 311 314 333 355 392 439 595 811 const double ColorTemp::ColorGreenkoriste[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0945, 0.0292, 0.0315, 0.0433, 0.0321, 0.0294, 0.0295, 0.0321, 0.0278, 0.0261, 0.0282, 0.0272, 0.0270, 0.0278, 0.0285, 0.0274, 0.0277, 0.0268, 0.0269, 0.0283, @@ -785,9 +736,6 @@ const double ColorTemp::ColorGreenkoriste[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#green leaf (poimulehti) -//1102 146 630 266 247 261 285 238 273 281 272 260 262 254 274 263 273 278 296 309 322 388 493 607 712 840 953 986 1006 1034 999 981 918 855 794 711 649 627 604 563 531 515 467 450 448 466 445 421 402 385 369 345 346 319 330 359 378 439 578 835 1177 const double ColorTemp::ColorGreenpoimulehti[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1102, 0.0146, 0.0630, 0.0266, 0.0247, 0.0261, 0.0285, 0.0238, 0.0273, 0.0281, 0.0272, 0.0260, 0.0262, 0.0254, 0.0274, 0.0263, 0.0273, 0.0278, 0.0296, 0.0309, 0.0322, @@ -796,9 +744,6 @@ const double ColorTemp::ColorGreenpoimulehti[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#green leaf (hopeapaju) -//787 512 1260 1032 765 881 994 908 983 985 941 985 971 967 964 937 928 959 973 992 1004 1017 1053 1102 1180 1227 1281 1309 1317 1328 1318 1271 1238 1222 1179 1152 1131 1092 1086 1078 1083 1020 1015 1000 1027 1037 1028 970 962 977 952 963 955 935 980 979 963 1028 1059 1228 1401 const double ColorTemp::ColorGreenhopeapaju[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0787, 0.0512, 0.1260, 0.1032, 0.0765, 0.0881, 0.0994, 0.0908, 0.0983, 0.0985, 0.0941, 0.0985, 0.0971, 0.0967, 0.0964, 0.0937, 0.0928, 0.0959, 0.0973, 0.0992, 0.1004, @@ -807,8 +752,6 @@ const double ColorTemp::ColorGreenhopeapaju[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red flower (uuden guinean liisa) -//2288 1861 2364 2229 2783 2842 2842 2923 2902 2990 2828 2871 2772 2723 2639 2558 2424 2315 2169 2094 2064 1964 1865 1739 1680 1624 1548 1457 1424 1408 1434 1451 1492 1528 1597 1755 1951 2147 2367 2648 2986 3236 3393 3596 3665 3786 3879 3915 3926 3994 3987 4017 4026 4112 4067 4125 4139 4121 4050 4040 4095 const double ColorTemp::ColorReduuden[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2288, 0.1861, 0.2364, 0.2229, 0.2783, 0.2842, 0.2842, 0.2923, 0.2902, 0.2990, 0.2828, 0.2871, 0.2772, 0.2723, 0.2639, 0.2558, 0.2424, 0.2315, 0.2169, 0.2094, 0.2064, @@ -817,9 +760,6 @@ const double ColorTemp::ColorReduuden[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#red flower (pajuangervo) -//445 1024 605 833 937 959 1052 1028 1049 1029 1017 975 948 882 865 812 757 718 658 638 628 597 554 523 509 509 485 475 469 492 479 477 490 525 555 597 641 704 756 846 948 1055 1164 1221 1266 1339 1393 1491 1553 1604 1608 1650 1643 1652 1655 1658 1651 1739 1813 1818 1938 const double ColorTemp::ColorRedpajuan[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0445, 0.1024, 0.0605, 0.0833, 0.0937, 0.0959, 0.1052, 0.1028, 0.1049, 0.1029, 0.1017, 0.0975, 0.0948, 0.0882, 0.0865, 0.0812, 0.0757, 0.0718, 0.0658, 0.0638, 0.0628, 0.0597, @@ -828,9 +768,6 @@ const double ColorTemp::ColorRedpajuan[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#red flower (jaloangervo) -//120 152 512 635 662 538 749 713 743 792 777 785 733 726 728 749 709 674 661 657 645 635 598 570 553 544 545 538 546 514 540 567 585 577 602 651 690 765 836 907 980 1089 1147 1188 1212 1253 1318 1371 1412 1473 1459 1478 1548 1582 1564 1590 1595 1714 1728 1814 1837 const double ColorTemp::ColorRedjaloan[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0120, 0.0152, 0.0512, 0.0635, 0.0662, 0.0538, 0.0749, 0.0713, 0.0743, 0.0792, 0.0777, 0.0785, 0.0733, 0.0726, 0.0728, 0.0749, 0.0709, 0.0674, 0.0661, 0.0657, 0.0645, 0.0635, @@ -839,9 +776,6 @@ const double ColorTemp::ColorRedjaloan[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#blue flower (ukonhattu) -//801 682 1070 1319 1311 1420 1453 1394 1318 1292 1268 1179 1132 1054 1015 948 846 780 731 709 705 667 621 598 555 522 505 493 498 500 494 471 479 463 450 461 487 515 546 574 555 562 539 558 546 552 567 626 715 807 862 978 1086 1199 1313 1323 1350 1366 1358 1320 1365 const double ColorTemp::ColorBlueukon[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0801, 0.0682, 0.1070, 0.1319, 0.1311, 0.1420, 0.1453, 0.1394, 0.1318, 0.1292, 0.1268, 0.1179, 0.1132, 0.1054, 0.1015, 0.0948, 0.0846, 0.0780, 0.0731, 0.0709, 0.0705, 0.0667, @@ -850,9 +784,6 @@ const double ColorTemp::ColorBlueukon[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#blue flower (orvokki) -//292 528 645 1000 932 1439 1752 1947 2077 2158 2169 2153 2164 2132 2091 1993 1916 1876 1803 1702 1659 1554 1503 1425 1330 1229 1186 1134 1065 1031 1014 993 989 980 939 936 945 995 1055 1104 1180 1247 1284 1343 1349 1403 1458 1538 1634 1790 1880 2006 2218 2396 2556 2612 2735 2811 2765 2840 2877 const double ColorTemp::ColorBlueorvokki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0292, 0.0528, 0.0645, 0.1000, 0.0932, 0.1439, 0.1752, 0.1947, 0.2077, 0.2158, 0.2169, 0.2153, 0.2164, 0.2132, 0.2091, 0.1993, 0.1916, 0.1876, 0.1803, 0.1702, 0.1659, 0.1554, @@ -861,9 +792,6 @@ const double ColorTemp::ColorBlueorvokki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#blue flower (malvikki) -//1062 528 749 571 512 538 455 445 431 384 353 299 249 212 190 162 123 105 90 81 83 75 78 72 59 56 61 54 71 69 70 62 63 65 70 74 78 73 76 87 90 104 119 119 131 145 156 184 225 255 314 414 538 669 849 1068 1247 1467 1701 1885 2032 const double ColorTemp::ColorBluemalvikki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1062, 0.0528, 0.0749, 0.0571, 0.0512, 0.0538, 0.0455, 0.0445, 0.0431, 0.0384, 0.0353, 0.0299, 0.0249, 0.0212, 0.0190, 0.0162, 0.0123, 0.0105, 0.0090, 0.0081, 0.0083, 0.0075, @@ -872,8 +800,6 @@ const double ColorTemp::ColorBluemalvikki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#black dry leaf (maitohorsma) -//256 0 172 356 213 270 203 203 195 208 202 201 210 210 203 204 209 203 209 201 205 201 194 210 206 197 203 198 207 201 204 202 198 200 198 197 186 203 202 198 200 208 206 231 235 223 244 254 278 289 297 309 338 335 338 368 412 524 686 926 1185 const double ColorTemp::ColorBlackmaito[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0256, 0.0, 0.0172, 0.0356, 0.0213, 0.0270, 0.0203, 0.0203, 0.0195, 0.0208, 0.0202, 0.0201, 0.0210, 0.0210, 0.0203, 0.0204, 0.0209, 0.0203, 0.0209, 0.0201, 0.0205, 0.0201, @@ -882,9 +808,6 @@ const double ColorTemp::ColorBlackmaito[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#orange berry (pihlaja) -//945 731 585 433 247 408 266 314 293 305 289 288 280 297 262 298 277 274 291 293 285 303 300 310 324 336 364 377 426 465 499 561 602 667 741 890 1028 1164 1275 1465 1602 1640 1695 1744 1812 1837 1859 1805 1791 1822 1796 1751 1715 1655 1575 1600 1560 1618 1666 1740 1838 const double ColorTemp::ColorOrangpihlaja[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0945, 0.0731, 0.0585, 0.0433, 0.0247, 0.0408, 0.0266, 0.0314, 0.0293, 0.0305, 0.0289, 0.0288, 0.0280, 0.0297, 0.0262, 0.0298, 0.0277, 0.0274, 0.0291, 0.0293, 0.0285, 0.0303, @@ -893,9 +816,6 @@ const double ColorTemp::ColorOrangpihlaja[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#green flower (lehmus=linden) -//2677 1682 1170 1032 1085 816 728 755 833 832 813 845 857 884 855 882 914 997 1084 1179 1231 1437 1661 1873 2048 2209 2378 2408 2442 2509 2503 2452 2457 2418 2383 2348 2277 2213 2221 2169 2146 2048 1977 1960 2000 1993 1961 1899 1784 1748 1625 1517 1389 1260 1165 1143 1244 1522 1870 2324 2586 -//RIS 81 const double ColorTemp::ColorGreenlinden[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2677, 0.1682, 0.1170, 0.1032, 0.1085, 0.0816, 0.0728, 0.0755, 0.0833, 0.0832, 0.0813, 0.0845, 0.0857, 0.0884, 0.0855, 0.0882, 0.0914, 0.0997, 0.1084, 0.1179, 0.1231, 0.1437, @@ -904,8 +824,6 @@ const double ColorTemp::ColorGreenlinden[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#yellow petal (lehmus) -//1890 1097 900 832 814 799 758 853 803 808 833 862 916 943 960 969 1039 1162 1283 1370 1427 1529 1689 1781 1894 1950 2105 2118 2140 2185 2191 2199 2234 2266 2263 2297 2328 2312 2298 2332 2344 2312 2288 2347 2384 2390 2358 2280 2306 2315 2310 2253 2274 2271 2242 2292 2254 2208 2319 2314 2264 const double ColorTemp::ColorYellowlehmus[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1890, 0.1097, 0.0900, 0.0832, 0.0814, 0.0799, 0.0758, 0.0853, 0.0803, 0.0808, 0.0833, 0.0862, 0.0916, 0.0943, 0.0960, 0.0969, 0.1039, 0.1162, 0.1283, 0.1370, 0.1427, @@ -914,8 +832,6 @@ const double ColorTemp::ColorYellowlehmus[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#yellow flower (suikeroalpi) -//2048 1666 1140 1210 699 680 615 566 567 561 609 585 614 572 599 575 636 730 982 1194 1360 1766 2222 2558 2849 3048 3201 3395 3395 3484 3576 3623 3606 3672 3651 3634 3647 3669 3715 3660 3720 3692 3704 3784 3683 3731 3681 3697 3635 3694 3617 3610 3632 3663 3616 3595 3599 3584 3588 3613 3527 const double ColorTemp::ColorYellowsuikeroalpi[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2048, 0.1666, 0.1140, 0.1210, 0.0699, 0.0680, 0.0615, 0.0566, 0.0567, 0.0561, 0.0609, 0.0585, 0.0614, 0.0572, 0.0599, 0.0575, 0.0636, 0.0730, 0.0982, 0.1194, 0.1360, 0.1766, @@ -924,8 +840,6 @@ const double ColorTemp::ColorYellowsuikeroalpi[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#yellow flower (pensashanhikki) -//356 1365 1024 902 535 387 355 247 365 307 321 330 319 332 317 336 408 487 709 963 1235 1631 2111 2436 2718 2950 3151 3262 3313 3420 3448 3475 3491 3534 3520 3565 3622 3631 3626 3657 3640 3607 3641 3627 3601 3591 3588 3667 3618 3601 3630 3613 3592 3609 3569 3590 3568 3563 3588 3480 3471 const double ColorTemp::ColorYellowpensashanhikki1[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0356, 0.1365, 0.1024, 0.0902, 0.0535, 0.0387, 0.0355, 0.0247, 0.0365, 0.0307, 0.0321, 0.0330, 0.0319, 0.0332, 0.0317, 0.0336, 0.0408, 0.0487, 0.0709, 0.0963, 0.1235, @@ -934,8 +848,6 @@ const double ColorTemp::ColorYellowpensashanhikki1[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#yellow sepal (pensashanhikki) -//1068 427 326 416 428 590 503 470 539 526 546 540 539 526 497 546 555 603 753 903 1010 1268 1563 1868 2068 2226 2429 2495 2560 2625 2636 2610 2655 2667 2635 2630 2612 2560 2597 2588 2543 2478 2499 2472 2438 2431 2379 2406 2361 2319 2264 2174 2128 2010 1942 1912 1930 2148 2334 2585 2764 const double ColorTemp::ColorYellowpensashanhikki2[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1068, 0.0427, 0.0326, 0.0416, 0.0428, 0.0590, 0.0503, 0.0470, 0.0539, 0.0526, 0.0546, 0.0540, 0.0539, 0.0526, 0.0497, 0.0546, 0.0555, 0.0603, 0.0753, 0.0903, 0.1010, 0.1268, @@ -944,8 +856,6 @@ const double ColorTemp::ColorYellowpensashanhikki2[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#blue flower (hiidenvirna) -//315 512 675 832 765 865 807 867 911 904 852 826 780 753 711 661 595 528 513 476 431 391 361 331 305 276 240 229 237 223 212 208 215 205 203 195 209 212 222 266 296 322 356 352 388 391 411 425 473 532 550 630 669 748 823 879 904 917 930 950 942 const double ColorTemp::ColorBluehiidenvirna[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0315, 0.0512, 0.0675, 0.0832, 0.0765, 0.0865, 0.0807, 0.0867, 0.0911, 0.0904, 0.0852, 0.0826, 0.0780, 0.0753, 0.0711, 0.0661, 0.0595, 0.0528, 0.0513, 0.0476, 0.0431, 0.0391, @@ -954,9 +864,6 @@ const double ColorTemp::ColorBluehiidenvirna[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#blue flower (kurkkuyrtti) -//2687 1553 2181 2246 2209 2263 2442 2347 2261 2353 2292 2230 2095 2008 1896 1782 1569 1443 1333 1223 1177 1074 992 902 813 755 701 626 577 548 525 498 469 445 456 448 428 441 448 447 455 467 496 534 527 586 668 798 966 1126 1289 1469 1679 1870 2013 2040 2060 2077 2104 2155 2119 -//RIS 87 const double ColorTemp::ColorBluekurkkuyrtti[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2687, 0.1553, 0.2181, 0.2246, 0.2209, 0.2263, 0.2442, 0.2347, 0.2261, 0.2353, 0.2292, 0.2230, 0.2095, 0.2008, 0.1896, 0.1782, 0.1569, 0.1443, 0.1333, 0.1223, 0.1177, 0.1074, @@ -965,8 +872,6 @@ const double ColorTemp::ColorBluekurkkuyrtti[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#pink (siankaersaemoe) -//585 859 758 1094 780 1012 987 1067 1059 1034 1098 1110 1097 1040 1058 1048 1028 1014 1068 1024 1023 1025 1032 1029 1011 1007 986 973 946 906 949 923 943 949 956 998 1051 1107 1166 1242 1284 1355 1394 1438 1451 1543 1589 1588 1612 1616 1562 1534 1562 1541 1494 1492 1518 1650 1749 1907 1991 const double ColorTemp::ColorPinksiankaersaemoe[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0585, 0.0859, 0.0758, 0.1094, 0.0780, 0.1012, 0.0987, 0.1067, 0.1059, 0.1034, 0.1098, 0.1110, 0.1097, 0.1040, 0.1058, 0.1048, 0.1028, 0.1014, 0.1068, 0.1024, 0.1023, 0.1025, @@ -975,10 +880,6 @@ const double ColorTemp::ColorPinksiankaersaemoe[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#violet flower (harakankello) -//2520 1462 1890 1898 1751 1713 1555 1516 1471 1403 1282 1209 1144 1135 1069 976 895 823 782 762 713 685 661 635 603 559 551 550 541 567 562 574 580 589 586 620 670 690 718 801 786 769 773 739 800 806 837 845 971 1043 1102 1241 1359 1502 1611 1726 1793 1859 1909 1969 2014 -//RIS 89 const double ColorTemp::ColorVioletharakankello[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2520, 0.1462, 0.1890, 0.1898, 0.1751, 0.1713, 0.1555, 0.1516, 0.1471, 0.1403, 0.1282, 0.1209, 0.1144, 0.1135, 0.1069, 0.0976, 0.0895, 0.0823, 0.0782, 0.0762, 0.0713, @@ -987,8 +888,6 @@ const double ColorTemp::ColorVioletharakankello[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#violet flower (alsikeapila) -//1260 585 765 1065 937 881 847 943 1075 1053 1020 994 1008 1026 1015 980 962 949 925 908 880 864 843 814 802 749 698 691 677 660 653 660 631 633 644 692 743 809 889 1005 1160 1325 1396 1450 1526 1583 1655 1674 1689 1707 1675 1674 1624 1576 1564 1591 1613 1717 1851 1962 2033 const double ColorTemp::ColorVioletalsikeapila[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1260, 0.0585, 0.0765, 0.1065, 0.0937, 0.0881, 0.0847, 0.0943, 0.1075, 0.1053, 0.1020, 0.0994, 0.1008, 0.1026, 0.1015, 0.0980, 0.0962, 0.0949, 0.0925, 0.0908, 0.0880, 0.0864, @@ -997,8 +896,6 @@ const double ColorTemp::ColorVioletalsikeapila[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#violet flower (akilleija) -//843 1340 1393 1254 1290 1452 1508 1519 1454 1384 1301 1256 1178 1113 1056 985 884 827 743 720 691 664 605 578 540 507 499 475 485 494 492 479 487 493 471 495 559 595 645 689 720 732 716 723 734 750 804 849 948 1041 1169 1362 1525 1693 1761 1935 2071 2235 2376 2493 2604 const double ColorTemp::ColorVioletakilleija[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0843, 0.1340, 0.1393, 0.1254, 0.1290, 0.1452, 0.1508, 0.1519, 0.1454, 0.1384, 0.1301, 0.1256, 0.1178, 0.1113, 0.1056, 0.0985, 0.0884, 0.0827, 0.0743, 0.0720, 0.0691, 0.0664, @@ -1007,8 +904,6 @@ const double ColorTemp::ColorVioletakilleija[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#orange flower (kehaekukka) -//0 0 0 0 0 0 102 58 128 125 137 122 122 134 123 136 159 138 163 151 167 178 192 177 206 226 315 451 707 1045 1446 1707 1944 2131 2276 2524 2719 2841 2968 3052 3199 3264 3282 3429 3451 3454 3477 3556 3478 3565 3595 3569 3582 3582 3559 3610 3626 3668 3733 3692 3722 const double ColorTemp::ColorOrangekehaekukka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0102, 0.0058, 0.0128, 0.0125, 0.0137, 0.0122, 0.0122, 0.0134, 0.0123, 0.0136, 0.0159, 0.0138, 0.0163, 0.0151, 0.0167, 0.0178, 0.0192, @@ -1017,8 +912,6 @@ const double ColorTemp::ColorOrangekehaekukka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#red berry (pihlaja) -//0 0 0 0 25 84 128 87 165 130 167 147 155 146 148 165 158 159 164 160 158 158 157 157 173 173 179 195 210 234 264 302 349 386 461 572 735 886 1038 1216 1376 1521 1607 1691 1728 1769 1842 1843 1865 1910 1881 1920 1909 1909 1891 1879 1915 1879 1878 1843 1832 const double ColorTemp::ColorRedpihlaja[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0025, 0.0084, 0.0128, 0.0087, 0.0165, 0.0130, 0.0167, 0.0147, 0.0155, 0.0146, 0.0148, 0.0165, 0.0158, 0.0159, 0.0164, 0.0160, 0.0158, 0.0158, @@ -1026,9 +919,7 @@ const double ColorTemp::ColorRedpihlaja[97] = { 0.1728, 0.1769, 0.1842, 0.1843, 0.1865, 0.1910, 0.1881, 0.1920, 0.1909, 0.1909, 0.1891, 0.1879, 0.1915, 0.1879, 0.1878, 0.1843, 0.1832, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#violet flower (petunia) -//292 66 227 313 325 332 310 319 300 268 229 193 164 137 127 104 67 50 49 37 34 34 44 32 33 31 38 41 33 34 45 44 37 42 44 49 49 67 80 89 110 130 137 145 153 171 194 223 275 321 391 464 580 720 907 1055 1230 1436 1548 1777 1933 -//RIS 94 + const double ColorTemp::ColorVioletpetunia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0292, 0.0066, 0.0227, 0.0313, 0.0325, 0.0332, 0.0310, 0.0319, 0.0300, 0.0268, 0.0229, 0.0193, 0.0164, 0.0137, 0.0127, 0.0104, 0.0067, 0.0050, 0.0049, 0.0037, 0.0034, 0.0034, @@ -1037,8 +928,6 @@ const double ColorTemp::ColorVioletpetunia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#violet flower (orvokki) -//195 0 152 31 22 32 77 69 45 20 27 26 13 12 14 11 15 23 16 18 16 12 16 10 16 15 13 15 15 16 14 20 14 17 15 17 15 17 17 17 23 24 29 38 36 38 37 43 58 65 70 86 113 155 222 285 405 506 645 817 1035 const double ColorTemp::ColorVioletorvokki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0195, 0.0, 0.0152, 0.0031, 0.0022, 0.0032, 0.0077, 0.0069, 0.0045, 0.0020, 0.0027, 0.0026, 0.0013, 0.0012, 0.0014, 0.0011, 0.0015, 0.0023, 0.0016, 0.0018, 0.0016, 0.0012, 0.0016, @@ -1047,9 +936,6 @@ const double ColorTemp::ColorVioletorvokki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#blue flower (sinisievikki) -//801 1109 1861 2325 2329 2380 2562 2565 2558 2611 2517 2567 2475 2397 2337 2294 2195 2001 1881 1892 1854 1746 1668 1580 1491 1362 1229 1178 1110 1094 1072 1019 994 960 928 879 836 859 863 951 1046 1102 1154 1193 1174 1166 1153 1199 1275 1316 1376 1550 1739 1918 2104 2228 2364 2377 2423 2394 2334 const double ColorTemp::ColorBluesinisievikki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0801, 0.1109, 0.1861, 0.2325, 0.2329, 0.2380, 0.2562, 0.2565, 0.2558, 0.2611, 0.2517, 0.2567, 0.2475, 0.2397, 0.2337, 0.2294, 0.2195, 0.2001, 0.1881, 0.1892, 0.1854, 0.1746, @@ -1058,8 +944,6 @@ const double ColorTemp::ColorBluesinisievikki[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#blue flower (iisoppi) -//623 85 605 833 776 756 755 781 774 775 697 724 697 654 617 575 536 494 460 469 442 436 400 393 380 358 369 352 342 368 357 360 342 342 341 335 355 353 365 376 382 392 412 412 407 414 420 449 487 504 517 571 651 734 806 885 968 1088 1210 1296 1411 const double ColorTemp::ColorBlueiisoppi[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0623, 0.0085, 0.0605, 0.0833, 0.0776, 0.0756, 0.0755, 0.0781, 0.0774, 0.0775, 0.0697, 0.0724, 0.0697, 0.0654, 0.0617, 0.0575, 0.0536, 0.0494, 0.0460, 0.0469, 0.0442, 0.0436, @@ -1067,8 +951,7 @@ const double ColorTemp::ColorBlueiisoppi[97] = { 0.0407, 0.0414, 0.0420, 0.0449, 0.0487, 0.0504, 0.0517, 0.0571, 0.0651, 0.0734, 0.0806, 0.0885, 0.0968, 0.1088, 0.1210, 0.1296, 0.1411, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#white petal (ojakaersaemoe) -//1732 951 1800 1365 1801 1697 1762 2103 2243 2218 2200 2206 2255 2254 2269 2261 2272 2251 2254 2260 2256 2266 2247 2269 2310 2273 2345 2312 2301 2323 2302 2314 2362 2355 2348 2362 2396 2374 2362 2381 2396 2440 2383 2347 2422 2419 2472 2423 2406 2425 2377 2381 2380 2398 2390 2404 2370 2375 2364 2411 2417 + const double ColorTemp::ColorWhiteojaka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1732, 0.0951, 0.1800, 0.1365, 0.1801, 0.1697, 0.1762, 0.2103, 0.2243, 0.2218, 0.2200, 0.2206, 0.2255, 0.2254, 0.2269, 0.2261, 0.2272, 0.2251, 0.2254, 0.2260, 0.2256, 0.2266, @@ -1077,9 +960,6 @@ const double ColorTemp::ColorWhiteojaka[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//#white flower (petunia) -//4095 4022 4410 4095 4095 4095 4193 4207 4388 4328 4223 4168 4221 4304 4245 4210 4212 4192 4181 4233 4207 4224 4197 4262 4243 4241 4274 4257 4204 4285 4265 4241 4267 4275 4245 4276 4260 4217 4217 4244 4240 4186 4160 4156 4227 4286 4237 4137 4202 4187 4100 4112 4103 4090 4125 4115 4098 4036 4047 4105 4050 const double ColorTemp::ColorWhitepetunia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4095, 0.4022, 0.4410, 0.4095, 0.4095, 0.4095, 0.4193, 0.4207, 0.4388, 0.4328, 0.4223, 0.4168, 0.4221, 0.4304, 0.4245, 0.4210, 0.4212, 0.4192, 0.4181, 0.4233, 0.4207, 0.4224, @@ -1089,10 +969,6 @@ const double ColorTemp::ColorWhitepetunia[97] = { }; - -//#blue flower (lobelia dortmanna) -//0 660 1277 1544 1612 1961 1909 1950 1901 1907 1809 1785 1685 1622 1522 1377 1178 1054 931 898 850 732 610 508 434 370 343 329 303 265 232 199 183 169 172 177 200 233 214 214 199 186 199 228 249 321 435 684 1006 1345 1703 2082 2432 2661 2843 2936 3079 3015 3003 3045 3038 -//RIS 98 const double ColorTemp::ColorBluelobelia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0660, 0.1277, 0.1544, 0.1612, 0.1961, 0.1909, 0.1950, 0.1901, 0.1907, 0.1809, 0.1785, 0.1685, 0.1622, 0.1522, 0.1377, 0.1178, 0.1054, 0.0931, 0.0898, 0.0850, 0.0732, @@ -1101,8 +977,6 @@ const double ColorTemp::ColorBluelobelia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//#white petal (pelargonia) -//3493 2882 2284 2730 2869 2609 2781 2869 2861 2869 2795 2810 2740 2716 2650 2631 2539 2554 2450 2453 2447 2451 2343 2408 2404 2367 2343 2401 2474 2549 2668 2759 2843 2883 2989 3106 3209 3344 3383 3404 3453 3521 3495 3571 3521 3548 3582 3557 3581 3539 3563 3589 3597 3579 3502 3546 3507 3554 3490 3561 3518 const double ColorTemp::ColorWhitepelargonia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3493, 0.2882, 0.2284, 0.2730, 0.2869, 0.2609, 0.2781, 0.2869, 0.2861, 0.2869, 0.2795, 0.2810, 0.2740, 0.2716, 0.2650, 0.2631, 0.2539, 0.2554, 0.2450, 0.2453, 0.2447, @@ -1111,10 +985,6 @@ const double ColorTemp::ColorWhitepelargonia[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -/* -#white petal (paeivaenkakkara) -2168 1365 1969 2095 2231 2530 2944 3092 3107 3148 3188 3207 3195 3216 3225 3261 3211 3228 3260 3237 3258 3276 3265 3316 3327 3291 3315 3324 3355 3255 3264 3308 3324 3328 3282 3253 3220 3257 3289 3265 3245 3297 3284 3292 3228 3312 3290 3277 3278 3284 3182 3244 3273 3291 3212 3256 3154 3243 3306 3234 3155 -*/ const double ColorTemp::ColorWhitepaeivaen[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2168, 0.1365, 0.1969, 0.2095, 0.2231, 0.2530, 0.2944, 0.3092, 0.3107, 0.3148, 0.3188, 0.3207, 0.3195, 0.3216, 0.3225, 0.3261, 0.3211, 0.3228, 0.3260, 0.3237, 0.3258, @@ -1123,8 +993,6 @@ const double ColorTemp::ColorWhitepaeivaen[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//spectral data Colorchecker24 : Green B3 const double ColorTemp::ColorchechGreB3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0531, 0.0545, 0.0559, 0.0563, 0.0566, 0.0571, 0.0576, 0.0576, 0.0575, 0.0581, 0.0586, 0.0596, 0.0606, 0.0629, 0.0652, 0.0699, 0.0745, 0.0839, 0.0932, 0.1101, 0.1270, 0.1521, 0.1771, 0.2098, 0.2424, @@ -1133,7 +1001,6 @@ const double ColorTemp::ColorchechGreB3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : Cyan F3 const double ColorTemp::ColorchechCyaF3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0813, 0.1048, 0.1282, 0.1611, 0.1940, 0.2198, 0.2456, 0.2575, 0.2693, 0.2807, 0.2921, 0.3079, 0.3237, 0.3424, 0.3611, 0.3820, 0.4029, 0.4234, 0.4439, 0.4547, 0.4654, 0.4638, 0.4621, 0.4482, 0.4342, 0.4119, 0.3895, @@ -1141,7 +1008,20 @@ const double ColorTemp::ColorchechCyaF3_spect[97] = { 0.0732, 0.0745, 0.0757, 0.0763, 0.0768, 0.0764, 0.0759, 0.0748, 0.0736, 0.0723, 0.0710, 0.0703, 0.0696, 0.0707, 0.0718, 0.0756, 0.0793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : Purple D2 +const double ColorTemp::ColorchechCyaF3_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0813, 0.1048, 0.1382, 0.1711, 0.1940, 0.2298, 0.2456, 0.2575, 0.2693, 0.2907, 0.3021, 0.3079, 0.3237, 0.3624, 0.3611, 0.3820, 0.4029, 0.4234, 0.4439, 0.4547, 0.4654, 0.4638, 0.4621, 0.4482, 0.4342, 0.4119, 0.3895, + 0.3656, 0.3417, 0.3160, 0.2903, 0.2654, 0.2404, 0.2167, 0.1929, 0.1720, 0.1510, 0.1368, 0.1226, 0.1138, 0.1049, 0.0993, 0.0936, 0.0890, 0.0844, 0.0810, 0.0776, 0.0759, 0.0742, 0.0733, 0.0724, 0.0723, 0.0722, 0.0727, + 0.0732, 0.0745, 0.0757, 0.0763, 0.0768, 0.0764, 0.0759, 0.0748, 0.0736, 0.0723, 0.0710, 0.0703, 0.0696, 0.0707, 0.0718, 0.0756, 0.0793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorchechCyaF3_spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0813, 0.1048, 0.1282, 0.1411, 0.1840, 0.2098, 0.2356, 0.2575, 0.2593, 0.2807, 0.2821, 0.3079, 0.3137, 0.3424, 0.3611, 0.3820, 0.4029, 0.4234, 0.4439, 0.4547, 0.4654, 0.4638, 0.4621, 0.4482, 0.4342, 0.4119, 0.3895, + 0.3656, 0.3417, 0.3160, 0.2903, 0.2654, 0.2404, 0.2167, 0.1929, 0.1720, 0.1510, 0.1368, 0.1226, 0.1138, 0.1049, 0.0993, 0.0936, 0.0890, 0.0844, 0.0810, 0.0776, 0.0759, 0.0742, 0.0733, 0.0724, 0.0723, 0.0722, 0.0727, + 0.0732, 0.0745, 0.0757, 0.0763, 0.0768, 0.0764, 0.0759, 0.0748, 0.0736, 0.0723, 0.0710, 0.0703, 0.0696, 0.0707, 0.0718, 0.0756, 0.0793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::ColorchechPurD2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0854, 0.1047, 0.1240, 0.1468, 0.1696, 0.1826, 0.1955, 0.1963, 0.1970, 0.1910, 0.1849, 0.1750, 0.1651, 0.1541, 0.1430, 0.1322, 0.1213, 0.1117, 0.1020, 0.0944, 0.0868, 0.0809, 0.0750, 0.0703, 0.0655, @@ -1149,7 +1029,6 @@ const double ColorTemp::ColorchechPurD2_spect[97] = { 0.1117, 0.1222, 0.1327, 0.1469, 0.1610, 0.1796, 0.1981, 0.2173, 0.2365, 0.2532, 0.2698, 0.2826, 0.2953, 0.3022, 0.3090, 0.3126, 0.3161, 0.3238, 0.3314, 0.3504, 0.3694, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : Magenta E3 const double ColorTemp::ColorchechMagE3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1112, 0.1438, 0.1763, 0.2294, 0.2824, 0.3188, 0.3552, 0.3623, 0.3693, 0.3653, 0.3612, 0.3510, 0.3407, 0.3269, 0.3130, 0.2981, 0.2832, 0.2686, 0.2539, 0.2385, 0.2230, 0.2083, 0.1935, 0.1818, 0.1700, 0.1600, 0.1499, @@ -1157,8 +1036,6 @@ const double ColorTemp::ColorchechMagE3_spect[97] = { 0.7232, 0.7391, 0.7550, 0.7629, 0.7707, 0.7737, 0.7766, 0.7778, 0.7790, 0.7803, 0.7815, 0.7835, 0.7854, 0.7896, 0.7937, 0.8026, 0.8114, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : Skin A1 -//use also for palette WB const double ColorTemp::ColorchechSkiA138_13_14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0479, 0.051, 0.0553, 0.058, 0.0610, 0.062, 0.0626, 0.0622, 0.0619, 0.0617, 0.0616, 0.0615, 0.0614, 0.0614, 0.0615, 0.0617, 0.0618, 0.0618, 0.0619, 0.0618, 0.0618, 0.062, 0.0622, 0.063, 0.0638, 0.066, 0.0696, @@ -1166,14 +1043,13 @@ const double ColorTemp::ColorchechSkiA138_13_14_spect[97] = { 0.173, 0.1772, 0.181, 0.1842, 0.1846, 0.1853, 0.1831, 0.1811, 0.1788, 0.1765, 0.1769, 0.1773, 0.181, 0.1834, 0.1874, 0.1914, 0.1965, 0.2018, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : Gray C4 L=67 -//use also for palette WB const double ColorTemp::ColorchechGraC4_67_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1074, 0.1380, 0.1704, 0.22, 0.2705, 0.305, 0.3409, 0.35, 0.3601, 0.3628, 0.3655, 0.3675, 0.3698, 0.371, 0.3724, 0.373, 0.3733, 0.3725, 0.3715, 0.3705, 0.3692, 0.369, 0.3689, 0.368, 0.3673, 0.3678, 0.3684, 0.37, 0.3711, 0.3712, 0.3714, 0.3714, 0.3714, 0.371, 0.3707, 0.37, 0.3694, 0.3697, 0.3703, 0.3697, 0.3692, 0.3688, 0.3685, 0.3675, 0.3669, 0.3657, 0.3647, 0.3635, 0.3625, 0.361, 0.3596, 0.3585, 0.3579, 0.357, 0.3560, 0.3555, 0.3548, 0.3535, 0.3526, 0.3513, 0.3500, 0.349, 0.3475, 0.3467, 0.3460, 0.3452, 0.3444, 0.3431, 0.3421, 0.3411, 0.3403, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + const double ColorTemp::Fictif_61greyspect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, @@ -1188,10 +1064,7 @@ const double ColorTemp::JDC468_K15_87greyspect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//K15 275 275 0.1984 0.2448 0.3415 0.5707 0.7619 0.8275 0.8292 0.8156 0.8076 0.7982 0.7954 0.8083 0.8184 0.8137 0.8026 0.7988 0.7942 0.7765 0.7603 0.7681 0.7827 0.7923 0.7945 0.7964 0.7982 0.8017 0.8090 0.8191 0.8269 0.8327 0.8359 0.8390 0.8421 0.8452 0.8504 0.8611 -//spectral data Colorchecker24 : Skin B1 -//use also for palette WB const double ColorTemp::ColorchechSkiB166_18_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0962, 0.114, 0.1328, 0.152, 0.1706, 0.1755, 0.1877, 0.189, 0.1903, 0.1913, 0.1923, 0.1946, 0.1971, 0.2015, 0.2064, 0.215, 0.2245, 0.239, 0.2535, 0.273, 0.2922, 0.31, 0.3274, 0.337, 0.3473, @@ -1200,8 +1073,6 @@ const double ColorTemp::ColorchechSkiB166_18_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorchecker24 : blue sky C1 -//use also for palette WB const double ColorTemp::ColorchechBluC150_m5_m22_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1053, 0.134, 0.1633, 0.2075, 0.2518, 0.283, 0.3163, 0.324, 0.3325, 0.334, 0.3355, 0.3352, 0.3349, 0.332, 0.3294, 0.325, 0.3199, 0.3127, 0.3055, 0.2955, 0.2863, 0.28, 0.2737, 0.267, 0.2612, 0.249, 0.2378, 0.228, 0.2199, @@ -1209,8 +1080,6 @@ const double ColorTemp::ColorchechBluC150_m5_m22_spect[97] = { 0.1367, 0.1372, 0.1356, 0.1340, 0.1311, 0.1288, 0.1253, 0.1227, 0.1205, 0.1187, 0.1195, 0.1205, 0.1255, 0.1303, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorcheckerDC : blue sky N8 -//use also for palette WB const double ColorTemp::ColorchechDCBluN881_m7_m14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1371, 0.17, 0.2029, 0.291, 0.3790, 0.495, 0.6100, 0.67, 0.7249, 0.737, 0.7501, 0.7545, 0.7597, 0.764, 0.7677, 0.7685, 0.7693, 0.7677, 0.7662, 0.763, 0.7593, 0.753, 0.7471, 0.737, 0.7289, 0.718, 0.7077, 0.705, 0.6819, 0.666, 0.6515, 0.636, 0.6244, @@ -1218,16 +1087,12 @@ const double ColorTemp::ColorchechDCBluN881_m7_m14_spect[97] = { 0.5375, 0.531, 0.5244, 0.522, 0.5207, 0.524, 0.5264, 0.532, 0.5369, 0.542, 0.5505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorcheckerSG : Skin F7 -//use also for palette WB const double ColorTemp::ColorchechSGSkiF763_14_26_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0508, 0.064, 0.0776, 0.903, 0.1099, 0.1128, 0.1256, 0.128, 0.1307, 0.133, 0.1357, 0.139, 0.1425, 0.148, 0.1523, 0.159, 0.1669, 0.177, 0.1871, 0.20, 0.2118, 0.2235, 0.2355, 0.2445, 0.2537, 0.259, 0.2655, 0.268, 0.2700, 0.2708, 0.2716, 0.2743, 0.2770, 0.2803, 0.2827, 0.283, 0.2832, 0.283, 0.2828, 0.295, 0.3079, 0.344, 0.3803, 0.4105, 0.4409, 0.455, 0.4694, 0.477, 0.4851, 0.4896, 0.4962, 0.501, 0.5066, 0.511, 0.5160, 0.521, 0.5256, 0.529, 0.5318, 0.535, 0.5383, 0.541, 0.5451, 0.549, 0.5524, 0.556, 0.5597, 0.562, 0.5650, 0.568, 0.5709, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorcheckerSG : Skin K2 85 11 17 -//use also for palette WB const double ColorTemp::ColorchechSGSkiK285_11_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1122, 0.149, 0.1866, 0.259, 0.3318, 0.393, 0.4547, 0.469, 0.4846, 0.4845, 0.4844, 0.4838, 0.4834, 0.4837, 0.4840, 0.4847, 0.4854, 0.4852, 0.4849, 0.4842, 0.4835, 0.4832, 0.4828, 0.485, @@ -1236,8 +1101,6 @@ const double ColorTemp::ColorchechSGSkiK285_11_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorcheck24 : White A4 L=96 -//use also for palette WB const double ColorTemp::ColorchechWhiA496_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1267, 0.172, 0.2179, 0.317, 0.4164, 0.505, 0.6780, 0.758, 0.8397, 0.865, 0.8911, 0.897, 0.9035, 0.9062, 0.9092, 0.9124, 0.9154, 0.9167, 0.9180, 0.9187, 0.9194, 0.92, 0.9225, 0.9217, 0.9209, 0.921, @@ -1246,7 +1109,6 @@ const double ColorTemp::ColorchechWhiA496_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data Colorcheck24 : foliage Green D1 const double ColorTemp::ColorchechGreD1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0477, 0.0492, 0.0507, 0.0517, 0.0527, 0.0532, 0.0537, 0.054, 0.0544, 0.0554, 0.0563, 0.0573, 0.0584, 0.0592, 0.0601, 0.0607, 0.0611, 0.0613, 0.0619, 0.626, 0.0634, 0.0646, 0.0659, 0.069, @@ -1255,8 +1117,6 @@ const double ColorTemp::ColorchechGreD1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorchecSG : black N3 L=6 -//use also for palette WB const double ColorTemp::ColorchechSGBlaN3_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0066, 0.0069, 0.0071, 0.0072, 0.0074, 0.0073, 0.0072, 0.0073, 0.0074, 0.0074, 0.0074, 0.0074, 0.0074, 0.0073, 0.0073, 0.0073, 0.0073, 0.0072, 0.0072, 0.0072, 0.0072, 0.0071, 0.0071, 0.0071, @@ -1265,8 +1125,6 @@ const double ColorTemp::ColorchechSGBlaN3_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data 468 color : gray K14 L=44 -//use also for palette WB const double ColorTemp::JDC468_GraK14_44_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04240, 0.0485, 0.05500, 0.0624, 0.06930, 0.084, 0.09820, 0.109, 0.12160, 0.127, 0.13300, 0.13490, 0.13690, 0.1379, 0.13890, 0.1396, 0.14060, 0.1407, 0.14080, 0.1423, 0.14380, 0.1488, 0.15370, 0.157, 0.16040, @@ -1282,10 +1140,6 @@ const double ColorTemp::JDC468_BluM5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//m5 317 //0.1510 0.2069 0.3047 0.5069 0.6747 0.7351 0.7338 0.7063 0.6732 0.6261 0.5723 0.5401 -// 0.5106 0.4504 0.3907 0.3799 0.3695 0.3005 0.2382 0.2389 0.2610 0.2662 0.2541 -// 0.2426 0.2434 0.2523 0.2692 0.2996 0.3329 0.3498 0.3442 0.3266 0.2996 0.2831 0.3070 0.3799 - const double ColorTemp::JDC468_RedG21va_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1207, 0.141, 0.1585, 0.1810, 0.2073, 0.2529, 0.2959, 0.3210, 0.3476, 0.3350, 0.3232, 0.2845, 0.2564, 0.2140, 0.1823, 0.1523, 0.1266, 0.1001, 0.0792, 0.061, 0.0439, 0.0349, 0.0295, 0.0260, 0.0222, @@ -1293,8 +1147,7 @@ const double ColorTemp::JDC468_RedG21va_spect[97] = { 0.6546, 0.6659, 0.6775, 0.6881, 0.6982, 0.7081, 0.7150, 0.7201, 0.7217, 0.7232, 0.7222, 0.7215, 0.7187, 0.7157, 0.7144, 0.7131, 0.7196, 0.7269, 0.7303, 0.7599, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//g21 177 0.1207 0.1585 0.2073 0.2959 0.3476 0.3232 0.2564 0.1823 0.1266 0.0792 0.0439 0.0295 0.0222 0.0135 0.0087 0.0094 0.0109 0.0086 0.0091 0.0321 -// 0.1368 0.3256 0.4958 0.5884 0.6264 0.6473 0.6659 0.6881 0.7081 0.7201 0.7232 0.7215 0.7157 0.7131 0.7269 0.7599 + const double ColorTemp::JDC468_RedI9_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0258, 0.023, 0.0220, 0.0205, 0.0189, 0.0183, 0.0174, 0.0168, 0.0162, 0.0152, 0.0148, 0.0145, 0.0139, 0.0136, 0.0133, 0.0130, 0.0127, 0.0130, 0.0133, 0.0151, 0.0168, 0.0218, 0.0268, 0.0317, 0.0367, 0.0330, @@ -1303,8 +1156,6 @@ const double ColorTemp::JDC468_RedI9_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//I9 RED 217 0.0258 0.0220 0.0189 0.0174 0.0162 0.0148 0.0139 0.0133 0.0127 0.0133 0.0168 0.0268 0.0367 0.0313 0.0227 0.0255 0.0302 0.0225 0.0209 0.0639 0.2131 0.4369 0.6265 0.7336 0.7784 0.7994 0.8146 0.8277 0.8362 0.8439 0.8504 0.8572 0.8653 0.8715 0.8747 0.8788 - const double ColorTemp::JDC468_YelN10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0531, 0.0520, 0.0504, 0.0510, 0.0518, 0.0608, 0.0628, 0.0669, 0.0699, 0.0705, 0.0716, 0.0720, 0.0735, 0.0755, 0.0775, 0.0800, 0.0825, 0.0896, 0.0969, 0.1260, 0.1563, 0.2312, 0.3096, 0.4132, 0.5177, 0.5905, 0.6637, @@ -1313,8 +1164,6 @@ const double ColorTemp::JDC468_YelN10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//n10 348 0.0531 0.0504 0.0518 0.0628 0.0699 0.0716 0.0735 0.0775 0.0825 0.0969 0.1563 0.3096 0.5177 0.6637 0.7251 0.7458 0.7507 0.7414 0.7301 0.7347 0.7438 0.7500 0.7515 0.7538 0.7563 0.7607 0.7686 0.7791 0.7872 0.7935 0.7979 0.8021 0.8058 0.8090 0.8143 0.8259 const double ColorTemp::JDC468_GreN7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0112, 0.0102, 0.0094, 0.0096, 0.0099, 0.0100, 0.0100, 0.0100, 0.0100, 0.0099, 0.0099, 0.0099, 0.0099, 0.0099, 0.0099, 0.0100, 0.0100, 0.0103, 0.0107, 0.0129, 0.0151, 0.0312, 0.0462, 0.1015, 0.1571, 0.2270, 0.2977, @@ -1323,8 +1172,6 @@ const double ColorTemp::JDC468_GreN7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//n7 345 0.0112 0.0094 0.0099 0.0100 0.0100 0.0099 0.0099 0.0099 0.0100 0.0107 0.0151 0.0462 0.1571 0.2977 0.3558 0.3321 0.2710 0.1954 0.1251 0.0794 0.0563 0.0452 0.0378 0.0337 0.0335 0.0358 0.0405 0.0497 0.0612 0.0670 0.0644 0.0574 0.0483 0.0436 0.0532 0.0870 - const double ColorTemp::JDC468_GreA10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0958, 0.1010, 0.1090, 0.1172, 0.1352, 0.1954, 0.1957, 0.2178, 0.2402, 0.2477, 0.2553, 0.2594, 0.2622, 0.2667, 0.2707, 0.2760, 0.2805, 0.2913, 0.3023, 0.3376, 0.3715, 0.4345, 0.5030, 0.5702, 0.6376, 0.6724, 0.7072, @@ -1341,7 +1188,6 @@ const double ColorTemp::JDC468_GreQ7_spect[97] = { //468 Q7 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//a10 Green 10 0.0958 0.1090 0.1352 0.1957 0.2402 0.2553 0.2622 0.2707 0.2805 0.3023 0.3715 0.5030 0.6376 0.7072 0.7216 0.7110 0.6865 0.6446 0.5921 0.5511 0.5238 0.5070 0.4918 0.4830 0.4838 0.4906 0.5046 0.5279 0.5519 0.5649 0.5639 0.5552 0.5407 0.5326 0.5498 0.5966 const double ColorTemp::JDC468_GreK7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0114, 0.0111, 0.0109, 0.0107, 0.0105, 0.0106, 0.0108, 0.0107, 0.0106, 0.0105, 0.0104, 0.0103, 0.0103, 0.0106, 0.0109, 0.0112, 0.0118, 0.0135, 0.0153, 0.0244, 0.0334, 0.0666, 0.0984, 0.1534, 0.2082, 0.2412, 0.2835, @@ -1350,8 +1196,6 @@ const double ColorTemp::JDC468_GreK7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//k7 Green 267 0.0114 0.0109 0.0105 0.0108 0.0106 0.0104 0.0103 0.0109 0.0118 0.0153 0.0334 0.0984 0.2082 0.2835 0.2959 0.2735 0.2305 0.1728 0.1156 0.0772 0.0570 0.0468 0.0397 0.0354 0.0355 0.0380 0.0426 0.0523 0.0643 0.0704 0.0676 0.0609 0.0514 0.0468 0.0567 0.0902 - const double ColorTemp::JDC468_PurE24_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0677, 0.901, 0.1043, 0.1298, 0.1534, 0.1913, 0.2297, 0.2553, 0.2756, 0.2789, 0.2620, 0.2380, 0.2135, 0.1837, 0.1536, 0.1312, 0.1068, 0.0867, 0.0663, 0.0517, 0.0368, 0.0309, 0.0247, 0.0214, 0.0186, 0.0151, 0.0116, @@ -1359,10 +1203,7 @@ const double ColorTemp::JDC468_PurE24_spect[97] = { 0.1936, 0.1996, 0.2057, 0.2036, 0.2015, 0.1954, 0.1890, 0.1798, 0.1706, 0.1651, 0.1603, 0.1692, 0.1788, 0.2075, 0.2363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//E24 Pur 128 0.0677 0.1043 0.1534 0.2297 0.2756 0.2620 0.2135 0.1536 0.1068 0.0663 0.0368 0.0247 0.0186 0.0116 0.0077 0.0079 0.0086 0.0071 0.0072 0.0147 0.0440 0.0880 0.1152 0.1236 0.1287 0.1366 0.1489 0.1697 0.1936 0.2057 0.2015 0.1890 0.1706 0.1603 0.1788 0.2363 - -//spectral data 468 color : Blue H10 - Gamut > WidegamutRGB const double ColorTemp::JDC468_BluH10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01590, 0.028, 0.03970, 0.0697, 0.09970, 0.1526, 0.20550, 0.253, 0.30110, 0.3412, 0.38180, 0.423, 0.46610, 0.4683, 0.51030, 0.5005, 0.49950, 0.4785, 0.45810, 0.429, 0.39950, 0.374, 0.35010, 0.3135, 0.29630, @@ -1370,9 +1211,6 @@ const double ColorTemp::JDC468_BluH10_spect[97] = { 0.0029, 0.00300, 0.0029, 0.00290, 0.0029, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.0031, 0.00320, 0.0035, 0.00380, 0.0047, 0.00560, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.0159, 0.028, 0.0397, 0.0697, 0.0997, 0.1526, 0.2055, 0.253, 0.3011, 0.3412, 0.3818, 0.423, 0.4661, 0.5103 0.4995 0.4581 0.3995 0.3501 0.2963 -//0.2207 0.1445 0.0906 0.0481 0.0174 0.0052 0.0029 0.0027 0.0027 0.0028 0.0027 0.0028 0.0030 0.0029 0.0029 0.0029 0.0029 0.0029 0.0029 -//0.0029 0.0032 0.0038 0.0056 const double ColorTemp::JDC468_BluD6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1380,52 +1218,39 @@ const double ColorTemp::JDC468_BluD6_spect[97] = { 0.5352, 0.5009, 0.4655, 0.4356, 0.4191, 0.3923, 0.3619, 0.3145, 0.2653, 0.2245, 0.1744, 0.1499, 0.1255, 0.1124, 0.1014, 0.0972, 0.0855, 0.0786, 0.0715, 0.0659, 0.0626, 0.0625, 0.0624, 0.0645, 0.0670, 0.0714, 0.0769, 0.0865, 0.0964, 0.1086, 0.1200, 0.123, 0.1327, 0.1309, 0.1281, 0.1214, 0.1146, 0.1023, 0.0950, 0.0901, 0.0839, 0.0918, 0.1009, 0.1260, 0.1597, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - - }; -//d6 blue 84 0.1127 0.1773 0.2813 0.4782 0.6470 0.7270 0.7593 0.7591 0.7402 0.7054 0.6617 0.6302 0.5962 0.5352 0.4655 0.4191 0.3619 0.2653 0.1744 0.1255 0.1014 0.0855 0.0715 0.0626 0.0624 0.0670 0.0769 0.0964 0.1200 0.1327 0.1281 0.1146 0.0950 0.0839 0.1009 0.1597 + const double ColorTemp::JDC468_BluF4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0180, 0.0270, 0.0324, 0.0453, 0.0611, 0.0845, 0.1066, 0.1234, 0.1446, 0.1567, 0.1718, 0.1867, 0.1954, 0.2024, 0.2083, 0.2090, 0.2096, 0.2060, 0.2036, 0.1990, 0.1947, 0.1920, 0.1901, 0.1856, 0.1794, 0.1667, 0.1516, 0.1321, 0.1167, 0.1032, 0.0876, 0.0730, 0.0584, 0.0445, 0.0296, 0.0212, 0.0125, 0.0099, 0.0069, 0.0060, 0.0053, 0.0050, 0.0049, 0.0047, 0.0046, 0.0045, 0.0044, 0.0043, 0.0043, 0.0043, 0.0043, 0.0046, 0.0049, 0.0050, 0.0052, 0.0057, 0.0063, 0.0066, 0.0069, 0.0067, 0.0066, 0.0063, 0.0059, 0.0056, 0.0053, 0.0054, 0.0055, 0.0062, 0.0069, 0.0099, 0.0122, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - }; - -// f4 blue 134 0.0180 0.0324 0.0611 0.1066 0.1446 0.1718 0.1954 0.2083 0.2096 0.2036 0.1947 0.1901 0.1794 0.1516 0.1167 0.0876 0.0584 0.0296 0.0125 0.0069 0.0053 0.0049 0.0046 0.0044 0.0043 0.0043 0.0049 0.0052 0.0063 0.0069 0.0066 0.0059 0.0053 0.0055 0.0069 0.0122 const double ColorTemp::JDC468_GreI8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0230, 0.0232, 0.0234, 0.0254, 0.0263, 0.0298, 0.0329, 0.0367, 0.0377, 0.0388, 0.0399, 0.0410, 0.0421, 0.0440, 0.0460, 0.0481, 0.0496, 0.0523, 0.0559, 0.0645, 0.0727, 0.0878, 0.1020, 0.1156, 0.1288, 0.1334, 0.1394, 0.1398, 0.1402, 0.1407, 0.1413, 0.1409, 0.1396, 0.1334, 0.1276, 0.1200, 0.1129, 0.1095, 0.1064, 0.1053, 0.1043, 0.1031, 0.1021, 0.1001, 0.0980, 0.0970, 0.0952, 0.0963, 0.0967, 0.0990, 0.1009, 0.1042, 0.1078, 0.1130, 0.1188, 0.1251, 0.1307, 0.1335, 0.1374, 0.1376, 0.1378, 0.1362, 0.1345, 0.1312, 0.1278, 0.1257, 0.1240, 0.1290, 0.1345, 0.1476, 0.1615, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - }; -// i8 green215 215 0.0230 0.0234 0.0263 0.0329 0.0377 0.0399 0.0421 0.0460 0.0496 0.0559 0.0727 0.1020 0.1288 0.1394 0.1402 0.1413 0.1396 0.1276 0.1129 0.1064 0.1043 0.1021 0.0980 0.0952 0.0967 0.1009 0.1078 0.1188 0.1307 0.1374 0.1378 0.1345 0.1278 0.1240 0.1345 0.1615 - const double ColorTemp::JDC468_OraO18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0826, 0.0830, 0.0832, 0.0861, 0.0892, 0.0993, 0.1108, 0.1180, 0.1248, 0.1253, 0.1263, 0.1261, 0.1259, 0.1267, 0.1289, 0.1304, 0.1319, 0.1370, 0.1419, 0.1631, 0.1851, 0.2311, 0.2743, 0.3131, 0.3536, 0.3551, 0.3585, 0.3488, 0.3322, 0.3470, 0.3575, 0.3680, 0.3498, 0.3316, 0.3224, 0.3129, 0.3578, 0.4013, 0.4734, 0.5454, 0.5978, 0.6502, 0.6745, 0.6982, 0.7080, 0.7182, 0.7273, 0.7269, 0.7308, 0.7342, 0.7393, 0.7436, 0.7498, 0.7550, 0.7597, 0.7640, 0.7680, 0.7713, 0.7766, 0.7786, 0.7816, 0.7841, 0.7863, 0.7889, 0.7902, 0.7931, 0.7957, 0.7997, 0.8068, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - }; -// o18 ora 382 382 0.0826 0.0832 0.0892 0.1108 0.1248 0.1263 0.1259 0.1289 0.1319 0.1419 0.1851 0.2743 0.3536 0.3585 0.3322 0.3470 0.3680 0.3316 0.3129 0.4013 0.5454 0.6502 0.6982 0.7182 0.7269 0.7342 0.7436 0.7550 0.7640 0.7713 0.7766 0.7816 0.7863 0.7902 0.7957 0.8068 + const double ColorTemp::JDC468_OraD17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0462, 0.0442, 0.0422, 0.0401, 0.0383, 0.0390, 0.0396, 0.0396, 0.0395, 0.0388, 0.0380, 0.0378, 0.0376, 0.0381, 0.0384, 0.0391, 0.0399, 0.0421, 0.0451, 0.0561, 0.0676, 0.0934, 0.1189, 0.1432, 0.1671, 0.1650, 0.1632, 0.1512, 0.1402, 0.1456, 0.1521, 0.1613, 0.1696, 0.1552, 0.1409, 0.1342, 0.1283, 0.1689, 0.2084, 0.2845, 0.3575, 0.4183, 0.4797, 0.5090, 0.5389, 0.5498, 0.5617, 0.5667, 0.5728, 0.5788, 0.5822, 0.5889, 0.5938, 0.6011, 0.6081, 0.6145, 0.6212, 0.6267, 0.6304, 0.6331, 0.6352, 0.6361, 0.6373, 0.6372, 0.6370, 0.6376, 0.6384, 0.6413, 0.6483, 0.6523, 0.6668, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - }; -// d17 ora 95 95 0.0462 0.0422 0.0383 0.0396 0.0395 0.0380 0.0376 0.0384 0.0399 0.0451 0.0676 0.1189 0.1671 0.1632 0.1402 0.1521 0.1696 0.1409 0.1283 0.2084 0.3575 0.4797 0.5389 0.5617 0.5728 0.5822 0.5938 0.6081 0.6212 0.6304 0.6352 0.6373 0.6370 0.6384 0.6483 0.6668 - -//spectral data ColorLab : Skin 35 15 17 const double ColorTemp::ColabSkin35_15_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0211, 0.022, 0.0225, 0.0234, 0.0244, 0.0294, 0.0349, 0.038, 0.0411, 0.0425, 0.0441, 0.0455, 0.0472, 0.0473, 0.0475, 0.0463, 0.0452, 0.0435, 0.0417, 0.0397, 0.0377, @@ -1434,7 +1259,6 @@ const double ColorTemp::ColabSkin35_15_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 57 22 18 const double ColorTemp::ColabSkin57_22_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0647, 0.0677, 0.0709, 0.0754, 0.0797, 0.099, 0.1181, 0.1296, 0.1409, 0.1469, 0.1529, 0.1594, 0.1657, 0.1672, 0.1683, 0.1648, 0.1615, 0.1561, 0.1506, 0.144, 0.1375, 0.136, 0.1339, @@ -1443,7 +1267,6 @@ const double ColorTemp::ColabSkin57_22_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 40 17 17 const double ColorTemp::ColabSkin40_17_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0296, 0.0306, 0.0317, 0.0332, 0.0346, 0.042, 0.0498, 0.0543, 0.0588, 0.061, 0.0632, 0.0624, 0.0678, 0.068, 0.0682, 0.0663, 0.0649, 0.0625, 0.0598, 0.057, 0.0540, 0.0535, 0.0529, 0.057, @@ -1452,7 +1275,6 @@ const double ColorTemp::ColabSkin40_17_17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 91 4 14 const double ColorTemp::ColabSkin91_4_14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1430, 0.16, 0.1778, 0.202, 0.2303, 0.301, 0.3813, 0.4245, 0.4692, 0.499, 0.5287, 0.5635, 0.5977, 0.6175, 0.6372, 0.6394, 0.6418, 0.638, 0.6341, 0.6228, 0.6117, 0.6121, 0.6125, @@ -1461,7 +1283,6 @@ const double ColorTemp::ColabSkin91_4_14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 87 8 8 const double ColorTemp::ColabSkin87_8_8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1433, 0.161, 0.1780, 0.204, 0.2305, 0.306, 0.3828, 0.428, 0.4722, 0.502, 0.5317, 0.5645, 0.5997, 0.618, 0.6366, 0.6368, 0.6370, 0.631, 0.6251, 0.6120, 0.5994, 0.596, @@ -1470,7 +1291,6 @@ const double ColorTemp::ColabSkin87_8_8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 89 8 21 const double ColorTemp::ColabSkin89_8_21_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1394, 0.152, 0.1659, 0.1855, 0.2052, 0.266, 0.3277, 0.363, 0.3988, 0.422, 0.4450, 0.472, 0.4984, 0.512, 0.5270, 0.5274, 0.5278, 0.522, 0.5177, 0.5065, 0.4960, 0.4975, @@ -1479,7 +1299,6 @@ const double ColorTemp::ColabSkin89_8_21_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 75 8 4 const double ColorTemp::ColabSkin75_8_4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1030, 0.116, 0.1294, 0.1495, 0.1696, 0.227, 0.2847, 0.319, 0.3524, 0.375, 0.3977, 0.423, 0.4492, 0.462, 0.4770, 0.4768, 0.4767, 0.471, 0.4675, 0.458, 0.4480, 0.444, 0.4408, @@ -1488,7 +1307,6 @@ const double ColorTemp::ColabSkin75_8_4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 75 10 33 const double ColorTemp::ColabSkin75_10_33_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0873, 0.091, 0.0967, 0.103, 0.1097, 0.135, 0.1617, 0.177, 0.1913, 0.198, 0.2086, 0.218, 0.2289, 0.234, 0.2383, 0.2375, 0.2370, 0.2335, 0.2299, 0.223, 0.2180, 0.222, @@ -1497,7 +1315,6 @@ const double ColorTemp::ColabSkin75_10_33_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 65 33 11 const double ColorTemp::ColabSkin65_33_11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1067, 0.113, 0.1182, 0.126, 0.1346, 0.165, 0.2033, 0.224, 0.2448, 0.259, 0.2666, 0.277, 0.2891, 0.291, 0.2927, 0.285, 0.2783, 0.268, 0.2569, 0.244, 0.2323, 0.225, 0.2195, @@ -1506,7 +1323,6 @@ const double ColorTemp::ColabSkin65_33_11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 65 7 24 const double ColorTemp::ColabSkin65_7_24_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0619, 0.066, 0.0710, 0.077, 0.0840, 0.106, 0.1288, 0.142, 0.1546, 0.163, 0.1706, 0.179, 0.1893, 0.194, 0.1989, 0.1988, 0.1987, 0.196, 0.1941, 0.189, 0.1853, 0.188, 0.1894, @@ -1515,7 +1331,6 @@ const double ColorTemp::ColabSkin65_7_24_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 57 19 6 const double ColorTemp::ColabSkin57_19_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0662, 0.071, 0.0773, 0.085, 0.0939, 0.115, 0.1491, 0.165, 0.1821, 0.192, 0.2019, 0.214, 0.2236, 0.228, 0.2321, 0.2298, 0.2266, 0.221, 0.2161, 0.208, 0.2019, 0.199, @@ -1524,7 +1339,6 @@ const double ColorTemp::ColabSkin57_19_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 57 4 19 const double ColorTemp::ColabSkin57_4_19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0430, 0.047, 0.0505, 0.056, 0.0614, 0.077, 0.0963, 0.1063, 0.1164, 0.123, 0.1294, 0.137, 0.1448, 0.149, 0.1533, 0.154, 0.1544, 0.153, 0.1521, 0.149, 0.1463, 0.148, @@ -1533,7 +1347,6 @@ const double ColorTemp::ColabSkin57_4_19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 57 10 28 const double ColorTemp::ColabSkin57_10_28_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0463, 0.048, 0.0505, 0.053, 0.0563, 0.069, 0.0816, 0.088, 0.0961, 0.102, 0.1041, 0.1085, 0.1135, 0.1155, 0.1174, 0.1168, 0.1161, 0.114, 0.1118, 0.1085, 0.1054, 0.1074, 0.1094, 0.124, @@ -1542,7 +1355,6 @@ const double ColorTemp::ColabSkin57_10_28_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 40 7 19 const double ColorTemp::ColabSkin40_7_19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0215, 0.023, 0.0240, 0.026, 0.0275, 0.033, 0.0409, 0.044, 0.0487, 0.051, 0.0532, 0.056, 0.0585, 0.0595, 0.0608, 0.0605, 0.0602, 0.059, 0.0581, 0.057, 0.0549, 0.0555, 0.0562, @@ -1551,7 +1363,6 @@ const double ColorTemp::ColabSkin40_7_19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 40 17 6 const double ColorTemp::ColabSkin40_17_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0314, 0.033, 0.0359, 0.039, 0.0427, 0.054, 0.0668, 0.074, 0.0812, 0.085, 0.0895, 0.094, 0.0985, 0.10, 0.1015, 0.0991, 0.0984, 0.096, 0.0930, 0.089, 0.0861, 0.085, 0.0828, @@ -1560,7 +1371,6 @@ const double ColorTemp::ColabSkin40_17_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 40 4 11 const double ColorTemp::ColabSkin40_4_11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0209, 0.023, 0.0250, 0.028, 0.0310, 0.039, 0.0497, 0.056, 0.0605, 0.064, 0.0675, 0.072, 0.0758, 0.078, 0.0802, 0.0803, 0.0804, 0.0797, 0.0790, 0.078, 0.0758, 0.076, 0.0764, 0.082, @@ -1569,7 +1379,6 @@ const double ColorTemp::ColabSkin40_4_11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 33 6 15 const double ColorTemp::ColabSkin33_6_15_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0143, 0.015, 0.0162, 0.0175, 0.0189, 0.023, 0.0286, 0.031, 0.0342, 0.036, 0.0376, 0.039, 0.0415, 0.0425, 0.0434, 0.0432, 0.0431, 0.0425, 0.0418, 0.041, 0.0396, 0.04, @@ -1578,7 +1387,6 @@ const double ColorTemp::ColabSkin33_6_15_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 33 15 5 const double ColorTemp::ColabSkin33_15_5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0212, 0.023, 0.0243, 0.0265, 0.0289, 0.037, 0.0451, 0.051, 0.0549, 0.058, 0.0605, 0.063, 0.0666, 0.0675, 0.0686, 0.0672, 0.0664, 0.065, 0.0627, 0.0061, 0.0580, 0.0565, 0.0557, @@ -1586,7 +1394,7 @@ const double ColorTemp::ColabSkin33_15_5_spect[97] = { 0.0992, 0.1132, 0.1272, 0.1345, 0.1425, 0.1455, 0.1489, 0.1505, 0.1518, 0.1527, 0.1536, 0.1545, 0.1552, 0.1555, 0.1557, 0.1558, 0.1559, 0.1558, 0.1557, 0.1155, 0.1552, 0.1551, 0.1550, 0.1551, 0.1552, 0.1560, 0.1569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 33 10 15 + const double ColorTemp::ColabSkin33_10_15_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0166, 0.0175, 0.0183, 0.0194, 0.0207, 0.0260, 0.0306, 0.033, 0.0364, 0.0380, 0.0396, 0.0415, 0.0431, 0.0437, 0.0443, 0.0438, 0.0432, 0.0420, 0.0409, 0.0395, 0.0380, 0.0380, @@ -1595,7 +1403,6 @@ const double ColorTemp::ColabSkin33_10_15_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 24 5 6 const double ColorTemp::ColabSkin24_5_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0086, 0.0095, 0.0102, 0.0112, 0.0127, 0.0167, 0.0203, 0.0225, 0.0248, 0.0265, 0.0277, 0.0295, 0.0309, 0.0315, 0.0325, 0.0324, 0.0323, 0.0319, 0.0315, 0.0307, 0.0299, 0.0298, @@ -1604,7 +1411,6 @@ const double ColorTemp::ColabSkin24_5_6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 26 18 18 const double ColorTemp::ColabSkin26_18_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0135, 0.0137, 0.0138, 0.0139, 0.0140, 0.0163, 0.0187, 0.0202, 0.0215, 0.0220, 0.0224, 0.0228, 0.0231, 0.0227, 0.0222, 0.0212, 0.0202, 0.0189, 0.0174, 0.0161, 0.0146, 0.0143, @@ -1613,7 +1419,6 @@ const double ColorTemp::ColabSkin26_18_18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 24 7 5 const double ColorTemp::ColabSkin24_7_5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0093, 0.0105, 0.0111, 0.0125, 0.0137, 0.0180, 0.0221, 0.0245, 0.0270, 0.0285, 0.0301, 0.0316, 0.0336, 0.0345, 0.0353, 0.0350, 0.0349, 0.0343, 0.0338, 0.0329, 0.0320, 0.0317, 0.0315, @@ -1622,7 +1427,6 @@ const double ColorTemp::ColabSkin24_7_5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 24 4 2 const double ColorTemp::ColabSkin20_4_2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0064, 0.0074, 0.0080, 0.00903, 0.0104, 0.0139, 0.0174, 0.0189, 0.0216, 0.0222, 0.0243, 0.0258, 0.0274, 0.0282, 0.0291, 0.0290, 0.0290, 0.0288, 0.0284, 0.0278, 0.0272, 0.0270, 0.0267, 0.0276, @@ -1631,7 +1435,6 @@ const double ColorTemp::ColabSkin20_4_2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 98 -2 10 const double ColorTemp::ColabSkin98_m2_10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1627, 0.1870, 0.2115, 0.2480, 0.2860, 0.3870, 0.4878, 0.5460, 0.6050, 0.6460, 0.6874, 0.7355, 0.7836, 0.8130, 0.8424, 0.8494, 0.8543, 0.8520, 0.8508, 0.8390, 0.8267, 0.8274, 0.8280, @@ -1640,7 +1443,6 @@ const double ColorTemp::ColabSkin98_m2_10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 90 -1 20 const double ColorTemp::ColabSkin90_m1_20_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1228, 0.138, 0.1532, 0.175, 0.1987, 0.261, 0.3279, 0.365, 0.4022, 0.428, 0.4537, 0.4842, 0.5147, 0.5337, 0.5521, 0.557, 0.5611, 0.5602, 0.5593, 0.551, 0.5438, 0.548, @@ -1649,7 +1451,6 @@ const double ColorTemp::ColabSkin90_m1_20_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 95 0 4 const double ColorTemp::ColabSkin95_0_4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1614, 0.1865, 0.2118, 0.2495, 0.2889, 0.392, 0.4969, 0.557, 0.6185, 0.6605, 0.7035, 0.749, 0.8018, 0.832, 0.8605, 0.865, 0.8696, 0.866, 0.8633, 0.849, 0.8365, 0.834, @@ -1658,7 +1459,6 @@ const double ColorTemp::ColabSkin95_0_4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 81 2 14 const double ColorTemp::ColabSkin81_2_14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1029, 0.116, 0.1285, 0.148, 0.1672, 0.222, 0.2774, 0.311, 0.3412, 0.362, 0.3849, 0.410, 0.4359, 0.451, 0.4659, 0.468, 0.4706, 0.4685, 0.4664, 0.4685, 0.4512, 0.4525, 0.4536, @@ -1667,7 +1467,6 @@ const double ColorTemp::ColabSkin81_2_14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 87 3 10 const double ColorTemp::ColabSkin87_3_10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1295, 0.146, 0.1639, 0.190, 0.2160, 0.291, 0.3626, 0.405, 0.4480, 0.476, 0.5066, 0.541, 0.5743, 0.593, 0.6136, 0.616, 0.6186, 0.614, 0.6119, 0.601, 0.5911, 0.5905, @@ -1676,7 +1475,6 @@ const double ColorTemp::ColabSkin87_3_10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 77 12 21 const double ColorTemp::ColabSkin77_12_21_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1039, 0.111, 0.1205, 0.132, 0.1448, 0.185, 0.2261, 0.249, 0.2734, 0.287, 0.3028, 0.318, 0.3364, 0.345, 0.3525, 0.351, 0.3499, 0.345, 0.3397, 0.3295, 0.3224, 0.329, 0.3234, @@ -1685,7 +1483,6 @@ const double ColorTemp::ColabSkin77_12_21_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Skin 70 7 32 const double ColorTemp::ColabSkin70_7_32_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0695, 0.074, 0.0777, 0.084, 0.0890, 0.104, 0.1321, 0.144, 0.1565, 0.164, 0.1713, 0.1795, 0.1889, 0.194, 0.1978, 0.198, 0.1983, 0.196, 0.1939, 0.189, 0.1853, 0.189, @@ -1694,7 +1491,6 @@ const double ColorTemp::ColabSkin70_7_32_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Sky 60 0 -31 const double ColorTemp::ColabSky60_0_m31_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0752, 0.094, 0.1121, 0.141, 0.1699, 0.243, 0.3150, 0.357, 0.4015, 0.432, 0.4631, 0.497, 0.5325, 0.553, 0.5730, 0.574, 0.5758, 0.572, 0.5695, 0.559, 0.5503, 0.539, @@ -1703,7 +1499,6 @@ const double ColorTemp::ColabSky60_0_m31_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : Sky 42 0 -24 const double ColorTemp::ColabSky42_0_m24_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0336, 0.041, 0.0501, 0.063, 0.0761, 0.103, 0.1412, 0.151, 0.1799, 0.193, 0.2076, 0.223, 0.2387, 0.248, 0.2569, 0.2575, 0.2581, 0.256, 0.2553, 0.250, 0.2466, 0.2411, @@ -1711,7 +1506,6 @@ const double ColorTemp::ColabSky42_0_m24_spect[97] = { 0.0979, 0.112, 0.1269, 0.134, 0.1430, 0.147, 0.1497, 0.151, 0.1529, 0.1545, 0.1561, 0.158, 0.1603, 0.1616, 0.1627, 0.1625, 0.1623, 0.1614, 0.1605, 0.159, 0.1575, 0.1567, 0.1557, 0.1563, 0.1569, 0.159, 0.1627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//spectral data ColorLab : blue 77 -44 -50 const double ColorTemp::Colorblue_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1720,9 +1514,7 @@ const double ColorTemp::Colorblue_spect[97] = { 0.0601, 0.0525, 0.0455, 0.0423, 0.0386, 0.0370, 0.0358, 0.0354, 0.0351, 0.0368, 0.0382, 0.0413, 0.0449, 0.0474, 0.0492, 0.0484, 0.0477, 0.0460, 0.0437, 0.0402, 0.0371, 0.0349, 0.0329, 0.0341, 0.0356, 0.0410, 0.0462, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 - }; -//0.1571 0.2150 0.3040 0.3684 0.3952 0.3965 0.3782 0.3418 0.2995 0.2543 0.2043 0.1686 0.1420 0.1070 0.0785 0.0725 0.0755 0.0695 0.0680 0.0914 0.1379 0.1833 0.2038 0.2065 0.2079 0.2110 0.2176 0.2319 0.2518 0.2632 0.2616 0.2522 0.2380 0.2290 0.2432 0.2901 const double ColorTemp::ColorViolA1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1731,7 +1523,6 @@ const double ColorTemp::ColorViolA1_spect[97] = { 0.2065, 0.207, 0.2079, 0.209, 0.2110, 0.214, 0.2176, 0.226, 0.2319, 0.242, 0.2518, 0.258, 0.2632, 0.263, 0.2616, 0.256, 0.2522, 0.246, 0.2380, 0.233, 0.2290, 0.235, 0.2432, 0.265, 0.2901, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.2270 0.2413 0.3287 0.4079 0.4469 0.4594 0.4535 0.4268 0.3886 0.3427 0.2866 0.2433 0.2087 0.1604 0.1181 0.1069 0.1098 0.0985 0.0916 0.1130 0.1496 0.1746 0.1783 0.1742 0.1738 0.1763 0.1831 0.1975 0.2169 0.2274 0.2247 0.2140 0.1990 0.1897 0.2039 0.2508 const double ColorTemp::ColorViolA4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1741,7 +1532,6 @@ const double ColorTemp::ColorViolA4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.1426 0.2660 0.3556 0.4259 0.4459 0.4317 0.3942 0.3425 0.2917 0.2413 0.1885 0.1524 0.1267 0.0948 0.0700 0.0661 0.0708 0.0671 0.0699 0.1092 0.2099 0.3582 0.4857 0.5583 0.5950 0.6146 0.6307 0.6495 0.6720 0.6825 0.6809 0.6718 0.6593 0.6517 0.6649 0.7066 const double ColorTemp::ColorViolA6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1426, 0.203, 0.2660, 0.315, 0.3556, 0.392, 0.4259, 0.435, 0.4459, 0.437, 0.4317, 0.417, 0.3942, 0.365, 0.3425, 0.317, 0.2917, 0.266, 0.2413, 0.218, 0.1885, 0.172, 0.1524, 0.141, @@ -1750,7 +1540,6 @@ const double ColorTemp::ColorViolA6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.4939 0.3859 0.4198 0.4780 0.5328 0.5672 0.5880 0.5994 0.6029 0.5981 0.5808 0.5618 0.5369 0.4819 0.4190 0.3921 0.3815 0.3400 0.2991 0.2977 0.3090 0.3088 0.2930 0.2753 0.2660 0.2636 0.2678 0.2811 0.2995 0.3125 0.3153 0.3111 0.3006 0.2952 0.3116 0.3584 const double ColorTemp::ColorBlueSkyK3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4939, 0.435, 0.3859, 0.403, 0.4198, 0.446, 0.4780, 0.505, 0.5328, 0.552, 0.5672, 0.578, 0.5880, 0.595, 0.5994, 0.602, 0.6029, 0.600, 0.5981, 0.588, 0.5808, 0.571, 0.5618, 0.551, @@ -1759,8 +1548,6 @@ const double ColorTemp::ColorBlueSkyK3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0.4058 0.4734 0.5372 0.6051 0.6698 0.6992 0.7118 0.7135 0.7071 0.6938 0.6702 0.6511 0.6282 0.5732 0.5103 0.4913 0.4926 0.4604 0.4341 0.4648 0.5111 0.5335 0.5283 0.5154 0.5098 0.5093 0.5151 0.5309 0.5520 0.5642 0.5657 0.5598 0.5489 0.5430 0.5601 0.6067 - const double ColorTemp::ColorBlueSkyK9_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4058, 0.441, 0.4734, 0.502, 0.5372, 0.585, 0.6051, 0.643, 0.6698, 0.685, 0.6992, 0.705, 0.7118, 0.712, 0.7135, 0.711, 0.7071, 0.702, 0.6938, 0.681, 0.6702, 0.663, 0.6511, 0.642, @@ -1769,7 +1556,6 @@ const double ColorTemp::ColorBlueSkyK9_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//42 C4 0.3280 0.2611 0.3781 0.4646 0.5292 0.5732 0.6112 0.6307 0.6310 0.6181 0.5847 0.5488 0.5066 0.4358 0.3585 0.3151 0.2855 0.2309 0.1786 0.1546 0.1443 0.1359 0.1245 0.1151 0.1120 0.1127 0.1169 0.1275 0.1421 0.1504 0.1488 0.1416 0.1303 0.1241 0.1355 0.1739 const double ColorTemp::ColorBlueSkyC4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3280, 0.2950, 0.2611, 0.304, 0.3781, 0.423, 0.4646, 0.498, 0.5292, 0.555, 0.5732, 0.591, 0.6112, 0.6221, 0.6307, 0.631, 0.6310, 0.625, 0.6181, 0.607, 0.5847, 0.563, 0.5488, 0.524, @@ -1778,8 +1564,6 @@ const double ColorTemp::ColorBlueSkyC4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//52 C14 0.5697 0.4660 0.5000 0.5560 0.6072 0.6402 0.6632 0.6850 0.7069 0.7292 0.7488 0.7678 0.7786 0.7721 0.7544 0.7394 0.7232 0.6889 0.6446 0.6171 0.5966 0.5743 0.5425 0.5093 0.4884 0.4784 0.4774 0.4822 0.4944 0.5076 0.5186 0.5268 0.5303 0.5332 0.5454 0.5760 const double ColorTemp::ColorBlueSkyC14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5697, 0.511, 0.4660, 0.481, 0.5000, 0.528, 0.5560, 0.583, 0.6072, 0.622, 0.6402, 0.653, 0.6632, 0.674, 0.6850, 0.699, 0.7069, 0.717, 0.7292, 0.735, 0.7488, 0.757, 0.7678, 0.773, @@ -1788,8 +1572,6 @@ const double ColorTemp::ColorBlueSkyC14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//80 E4 0.1483 0.1756 0.2536 0.3084 0.3665 0.4189 0.4746 0.5127 0.5239 0.5193 0.4917 0.4569 0.4123 0.3422 0.2672 0.2179 0.1820 0.1356 0.0972 0.0784 0.0698 0.0646 0.0592 0.0556 0.0546 0.0551 0.0571 0.0611 0.0670 0.0701 0.0692 0.0661 0.0620 0.0606 0.0663 0.0834 const double ColorTemp::ColorBlueSkyE4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1483, 0.161, 0.1756, 0.213, 0.2536, 0.283, 0.3084, 0.331, 0.3665, 0.387, 0.4189, 0.445, 0.4746, 0.496, 0.5127, 0.519, 0.5239, 0.522, 0.5193, 0.508, 0.4917, 0.476, 0.4569, 0.431, @@ -1798,8 +1580,6 @@ const double ColorTemp::ColorBlueSkyE4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//229 M1 0.3100 0.2922 0.3514 0.4042 0.4443 0.4769 0.5002 0.5133 0.5187 0.5179 0.5057 0.4928 0.4729 0.4235 0.3643 0.3371 0.3234 0.2827 0.2418 0.2338 0.2370 0.2329 0.2184 0.2028 0.1958 0.1937 0.1973 0.2084 0.2244 0.2351 0.2372 0.2331 0.2239 0.2178 0.2319 0.2731 const double ColorTemp::ColorBlueSkyM1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3100, 0.303, 0.2922, 0.322, 0.3514, 0.376, 0.4042, 0.424, 0.4443, 0.457, 0.4769, 0.497, 0.5002, 0.507, 0.5133, 0.516, 0.5187, 0.518, 0.5179, 0.511, 0.5057, 0.497, 0.4928, 0.483, @@ -1808,8 +1588,6 @@ const double ColorTemp::ColorBlueSkyM1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//514 2B1 0.5277 0.4431 0.4972 0.5820 0.6387 0.6750 0.7001 0.7140 0.7202 0.7193 0.7053 0.6891 0.6657 0.6181 0.5614 0.5312 0.5101 0.4589 0.4045 0.3857 0.3826 0.3751 0.3574 0.3393 0.3314 0.3304 0.3368 0.3523 0.3742 0.3874 0.3883 0.3818 0.3693 0.3616 0.3800 0.4324 const double ColorTemp::ColorBlueSky2B1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5277, 0.485, 0.4431, 0.476, 0.4972, 0.539, 0.5820, 0.607, 0.6387, 0.653, 0.6750, 0.691, 0.7001, 0.707, 0.7140, 0.718, 0.7202, 0.720, 0.7193, 0.713, 0.7053, 0.695, 0.6891, 0.674, @@ -1818,8 +1596,6 @@ const double ColorTemp::ColorBlueSky2B1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//368 T7 0.1943 0.3199 0.4536 0.5443 0.6043 0.6499 0.6839 0.7125 0.7329 0.7482 0.7527 0.7514 0.7383 0.7028 0.6526 0.6034 0.5500 0.4708 0.3848 0.3268 0.2929 0.2712 0.2493 0.2316 0.2243 0.2234 0.2288 0.2436 0.2640 0.2762 0.2767 0.2693 0.2566 0.2489 0.2665 0.3165 const double ColorTemp::ColorBlueSkyT7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1943, 0.256, 0.3199, 0.376, 0.4536, 0.494, 0.5443, 0.572, 0.6043, 0.631, 0.6499, 0.664, 0.6839, 0.698, 0.7125, 0.726, 0.7329, 0.741, 0.7482, 0.751, 0.7527, 0.752, 0.7514, 0.745, @@ -1828,9 +1604,6 @@ const double ColorTemp::ColorBlueSkyT7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//399 U19 0.5829 0.4865 0.4927 0.5690 0.6221 0.6532 0.6728 0.6832 0.6889 0.6884 0.6771 0.6648 0.6465 0.6038 0.5524 0.5297 0.5194 0.4797 0.4387 0.4356 0.4455 0.4444 0.4282 0.4094 0.4009 0.3992 0.4046 0.4185 0.4385 0.4515 0.4545 0.4505 0.4411 0.4368 0.4539 0.5013 const double ColorTemp::ColorBlueSkyU19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5829, 0.534, 0.4865, 0.489, 0.4927, 0.532, 0.5690, 0.593, 0.6221, 0.641, 0.6532, 0.662, 0.6728, 0.674, 0.6832, 0.687, 0.6889, 0.688, 0.6884, 0.683, 0.6771, 0.671, 0.6648, 0.665, @@ -1839,8 +1612,6 @@ const double ColorTemp::ColorBlueSkyU19_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//382 U2 0.3594 0.3425 0.3214 0.3654 0.4097 0.4360 0.4590 0.4793 0.5002 0.5234 0.5476 0.5745 0.5940 0.5901 0.5703 0.5545 0.5384 0.5029 0.4592 0.4334 0.4149 0.3947 0.3657 0.3363 0.3177 0.3087 0.3077 0.3123 0.3231 0.3351 0.3454 0.3520 0.3545 0.3562 0.3674 0.3976 const double ColorTemp::ColorBlueSkyU2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3594, 0.345, 0.3425, 0.333, 0.3214, 0.346, 0.3654, 0.387, 0.4097, 0.424, 0.4360, 0.446, 0.4590, 0.467, 0.4793, 0.494, 0.5002, 0.517, 0.5234, 0.538, 0.5476, 0.564, 0.5745, 0.583, @@ -1849,9 +1620,6 @@ const double ColorTemp::ColorBlueSkyU2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//378 T17 0.4213 0.3332 0.4205 0.5078 0.5650 0.6025 0.6223 0.6279 0.6195 0.5981 0.5578 0.5197 0.4785 0.4074 0.3325 0.3030 0.2918 0.2511 0.2125 0.2105 0.2198 0.2199 0.2083 0.1945 0.1895 0.1898 0.1954 0.2094 0.2288 0.2406 0.2399 0.2317 0.2189 0.2108 0.2261 0.2755 const double ColorTemp::ColorBlueSkyT17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4213, 0.376, 0.3332, 0.387, 0.4205, 0.467, 0.5078, 0.532, 0.5650, 0.587, 0.6025, 0.611, 0.6223, 0.624, 0.6279, 0.623, 0.6195, 0.607, 0.5981, 0.576, 0.5578, 0.534, 0.5197, 0.499, @@ -1860,8 +1628,6 @@ const double ColorTemp::ColorBlueSkyT17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//236 M8 -0.0593 0.0128 0.0031 0.0149 0.0197 0.0221 0.0223 0.0230 0.0232 0.0237 0.0243 0.0247 0.0249 0.0249 0.0248 0.0247 0.0244 0.0240 0.0240 0.0242 0.0244 0.0247 0.0252 0.0254 0.0262 0.0269 0.0271 0.0273 0.0278 0.0280 0.0276 0.0275 0.0282 0.0288 0.0295 0.0303 const double ColorTemp::ColorBlackM8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0593, 0.040, 0.0128, 0.023, 0.0031, 0.024, 0.0149, 0.017, 0.0197, 0.021, 0.0221, 0.022, 0.0223, 0.023, 0.0230, 0.023, 0.0232, 0.023, 0.0237, 0.024, 0.0243, 0.024, 0.0247, 0.024, @@ -1870,8 +1636,6 @@ const double ColorTemp::ColorBlackM8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//240 M12 -0.0377 0.0146 0.0167 0.0222 0.0257 0.0261 0.0270 0.0271 0.0274 0.0281 0.0287 0.0299 0.0306 0.0304 0.0297 0.0285 0.0277 0.0267 0.0257 0.0257 0.0258 0.0259 0.0263 0.0276 0.0279 0.0288 0.0297 0.0302 0.0304 0.0303 0.0302 0.0303 0.0310 0.0321 0.0337 0.0356 const double ColorTemp::ColorBlackM12_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0377, 0.022, 0.0146, 0.015, 0.0167, 0.020, 0.0222, 0.023, 0.0257, 0.026, 0.0261, 0.027, 0.0270, 0.027, 0.0271, 0.027, 0.0274, 0.028, 0.0281, 0.028, 0.0287, 0.029, 0.0299, 0.030, @@ -1880,8 +1644,6 @@ const double ColorTemp::ColorBlackM12_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//241 M13 0.2961 0.0487 0.0261 0.0330 0.0296 0.0305 0.0305 0.0314 0.0320 0.0322 0.0335 0.0348 0.0352 0.0347 0.0336 0.0325 0.0314 0.0299 0.0284 0.0284 0.0286 0.0288 0.0290 0.0299 0.0306 0.0314 0.0320 0.0328 0.0332 0.0331 0.0330 0.0328 0.0337 0.0350 0.0366 0.0385 const double ColorTemp::ColorBlackM13_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2961, 0.100, 0.0487, 0.035, 0.0261, 0.030, 0.0330, 0.031, 0.0296, 0.030, 0.0305, 0.030, 0.0305, 0.031, 0.0314, 0.032, 0.0320, 0.032, 0.0322, 0.033, 0.0335, 0.034, 0.0348, 0.035, @@ -1890,7 +1652,6 @@ const double ColorTemp::ColorBlackM13_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//525 2B12 0.3848 0.4127 0.4780 0.5375 0.5917 0.6194 0.6353 0.6485 0.6625 0.6784 0.7010 0.7367 0.7706 0.7847 0.7843 0.7826 0.7799 0.7689 0.7521 0.7463 0.7401 0.7314 0.7168 0.7008 0.6904 0.6860 0.6861 0.6896 0.6986 0.7064 0.7138 0.7185 0.7233 0.7281 0.7338 0.7498 const double ColorTemp::ColorWhite2B12_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3848, 0.405, 0.4127, 0.435, 0.4780, 0.501, 0.5375, 0.572, 0.5917, 0.606, 0.6194, 0.627, 0.6353, 0.642, 0.6485, 0.653, 0.6625, 0.669, 0.6784, 0.692, 0.7010, 0.072, 0.7367, 0.0760, @@ -1899,8 +1660,6 @@ const double ColorTemp::ColorWhite2B12_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//527 2B14 0.6608 0.5900 0.6114 0.6747 0.7329 0.7599 0.7706 0.7776 0.7831 0.7890 0.7952 0.8074 0.8185 0.8214 0.8201 0.8218 0.8244 0.8229 0.8192 0.8281 0.8344 0.8388 0.8415 0.8445 0.8495 0.8521 0.8556 0.8604 0.8666 0.8687 0.8687 0.8672 0.8682 0.8703 0.8720 0.8803 const double ColorTemp::ColorWhite2B14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6608, 0.631, 0.5900, 0.605, 0.6114, 0.634, 0.6747, 0.698, 0.7329, 0.745, 0.7599, 0.765, 0.7706, 0.775, 0.7776, 0.781, 0.7831, 0.786, 0.7890, 0.792, 0.7952, 0.797, 0.8074, 0.810, @@ -1909,7 +1668,6 @@ const double ColorTemp::ColorWhite2B14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//97 97 0.0031 0.0047 0.0056 0.0064 0.0070 0.0070 0.0071 0.0066 0.0065 0.0065 0.0064 0.0063 0.0063 0.0058 0.0052 0.0052 0.0053 0.0047 0.0044 0.0052 0.0066 0.0077 0.0081 0.0082 0.0084 0.0089 0.0096 0.0106 0.0121 0.0127 0.0128 0.0124 0.0115 0.0117 0.0133 0.0169 const double ColorTemp::JDC468_Blackred97_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0031, 0.0035, 0.0047, 0.0050, 0.0056, 0.0060, 0.0064, 0.0065, 0.0070, 0.007, 0.0070, 0.007, 0.0071, 0.007, 0.0066, 0.007, 0.0065, 0.006, 0.0065, 0.006, 0.0064, 0.006, 0.0063, @@ -1918,7 +1676,6 @@ const double ColorTemp::JDC468_Blackred97_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//443 443 0.0067 0.0068 0.0067 0.0074 0.0083 0.0088 0.0092 0.0093 0.0098 0.0099 0.0101 0.0106 0.0109 0.0104 0.0094 0.0086 0.0075 0.0058 0.0044 0.0039 0.0037 0.0038 0.0036 0.0035 0.0036 0.0033 0.0033 0.0036 0.0038 0.0042 0.0041 0.0036 0.0033 0.0035 0.0042 0.0062 const double ColorTemp::JDC468_Blackredbl443_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0067, 0.0067, 0.0068, 0.0068, 0.0067, 0.0070, 0.0074, 0.008, 0.0083, 0.0085, 0.0088, 0.009, 0.0092, 0.0092, 0.0093, 0.0096, 0.0098, 0.0098, 0.0099, 0.01, 0.0101, 0.0104, 0.0106, @@ -1927,8 +1684,6 @@ const double ColorTemp::JDC468_Blackredbl443_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//27 27 0.0060 0.0064 0.0070 0.0076 0.0086 0.0086 0.0088 0.0089 0.0089 0.0083 0.0079 0.0078 0.0077 0.0067 0.0059 0.0057 0.0056 0.0046 0.0041 0.0045 0.0050 0.0056 0.0054 0.0053 0.0054 0.0055 0.0057 0.0065 0.0073 0.0079 0.0080 0.0075 0.0067 0.0068 0.0081 0.0114 const double ColorTemp::JDC468_Blackbl27_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0060, 0.0062, 0.0064, 0.0066, 0.0070, 0.0073, 0.0076, 0.008, 0.0086, 0.0086, 0.0086, 0.0087, 0.0088, 0.0088, 0.0089, 0.0089, 0.0089, 0.0085, 0.0083, 0.008, 0.0079, 0.0078, 0.0078, @@ -1937,7 +1692,6 @@ const double ColorTemp::JDC468_Blackbl27_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//28 28 0.0092 0.0118 0.0155 0.0218 0.0267 0.0296 0.0312 0.0306 0.0282 0.0244 0.0205 0.0186 0.0167 0.0126 0.0091 0.0080 0.0071 0.0050 0.0042 0.0042 0.0044 0.0045 0.0045 0.0042 0.0041 0.0039 0.0040 0.0043 0.0048 0.0050 0.0047 0.0042 0.0041 0.0042 0.0049 0.0074 const double ColorTemp::JDC468_Blackbl28_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0092, 0.01, 0.0118, 0.012, 0.0155, 0.016, 0.0218, 0.025, 0.0267, 0.028, 0.0296, 0.03, 0.0312, 0.031, 0.0306, 0.03, 0.0282, 0.026, 0.0244, 0.022, 0.0205, 0.02, 0.0186, 0.017, 0.0167, @@ -1946,7 +1700,6 @@ const double ColorTemp::JDC468_Blackbl28_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//214 214 0.0072 0.0062 0.0061 0.0064 0.0069 0.0071 0.0075 0.0081 0.0082 0.0088 0.0103 0.0126 0.0145 0.0146 0.0140 0.0133 0.0118 0.0094 0.0070 0.0059 0.0051 0.0046 0.0045 0.0043 0.0045 0.0045 0.0048 0.0056 0.0065 0.0072 0.0067 0.0065 0.0057 0.0058 0.0068 0.0103 const double ColorTemp::JDC468_Blackgr214_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0072, 0.007, 0.0062, 0.0062, 0.0061, 0.0063, 0.0064, 0.0067, 0.0069, 0.007, 0.0071, 0.0072, 0.0075, 0.008, 0.0081, 0.008, 0.0082, 0.0085, 0.0088, 0.009, 0.0103, 0.011, 0.0126, @@ -1955,9 +1708,6 @@ const double ColorTemp::JDC468_Blackgr214_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//436 436 0.0095 0.0123 0.0173 0.0242 0.0293 0.0317 0.0310 0.0283 0.0246 0.0197 0.0152 0.0129 0.0112 0.0083 0.0063 0.0059 0.0056 0.0045 0.0043 0.0050 0.0059 0.0064 0.0062 0.0060 0.0060 0.0062 0.0066 0.0075 0.0086 0.0093 0.0089 0.0082 0.0073 0.0072 0.0088 0.0139 const double ColorTemp::JDC468_Blackbl436_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0095, 0.01, 0.0123, 0.013, 0.0173, 0.02, 0.0242, 0.026, 0.0293, 0.03, 0.0317, 0.031, 0.0310, 0.03, 0.0283, 0.025, 0.0246, 0.02, 0.0197, 0.018, 0.0152, 0.014, 0.0129, 0.012, @@ -1966,9 +1716,6 @@ const double ColorTemp::JDC468_Blackbl436_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//455 455 0.1560 0.1943 0.2724 0.4469 0.5896 0.6393 0.6390 0.6239 0.6096 0.5895 0.5698 0.5662 0.5603 0.5304 0.4977 0.4975 0.4998 0.4601 0.4261 0.4520 0.4986 0.5237 0.5270 0.5260 0.5297 0.5375 0.5504 0.5711 0.5910 0.6023 0.6029 0.5977 0.5880 0.5830 0.5978 0.6345 const double ColorTemp::JDC468_Whitebl455_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1560, 0.18, 0.1943, 0.25, 0.2724, 0.40, 0.4469, 0.50, 0.5896, 0.60, 0.6393, 0.639, 0.6390, 0.625, 0.6239, 0.61, 0.6096, 0.60, 0.5895, 0.57, 0.5698, 0.567, 0.5662, 0.56, @@ -1977,8 +1724,6 @@ const double ColorTemp::JDC468_Whitebl455_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//101 101 0.0076 0.0094 0.0116 0.0139 0.0158 0.0158 0.0152 0.0142 0.0130 0.0111 0.0094 0.0090 0.0085 0.0069 0.0058 0.0057 0.0058 0.0048 0.0044 0.0060 0.0094 0.0126 0.0141 0.0141 0.0148 0.0157 0.0172 0.0197 0.0227 0.0245 0.0242 0.0233 0.0215 0.0205 0.0240 0.0321 const double ColorTemp::JDC468_Blackvio101_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0076, 0.008, 0.0094, 0.01, 0.0116, 0.012, 0.0139, 0.015, 0.0158, 0.0158, 0.0158, 0.0156, 0.0152, 0.015, 0.0142, 0.014, 0.0130, 0.012, 0.0111, 0.01, 0.0094, 0.009, 0.0090, 0.009, @@ -1987,7 +1732,6 @@ const double ColorTemp::JDC468_Blackvio101_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//92 92 0.1652 0.2036 0.2848 0.4708 0.6230 0.6758 0.6761 0.6619 0.6502 0.6343 0.6195 0.6194 0.6169 0.5939 0.5677 0.5678 0.5695 0.5373 0.5105 0.5356 0.5778 0.6020 0.6073 0.6090 0.6124 0.6187 0.6295 0.6456 0.6603 0.6693 0.6716 0.6704 0.6660 0.6640 0.6749 0.7003 const double ColorTemp::JDC468_Whitebl92_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1652, 0.19, 0.2036, 0.24, 0.2848, 0.35, 0.4708, 0.55, 0.6230, 0.65, 0.6758, 0.6759, 0.6761, 0.665, 0.6619, 0.655, 0.6502, 0.64, 0.6343, 0.62, 0.6195, 0.6194, 0.6194, 0.618, @@ -1996,7 +1740,6 @@ const double ColorTemp::JDC468_Whitebl92_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//94 94 0.0506 0.0569 0.0678 0.0906 0.1088 0.1160 0.1184 0.1195 0.1203 0.1215 0.1293 0.1474 0.1609 0.1538 0.1415 0.1466 0.1535 0.1364 0.1248 0.1494 0.1871 0.2098 0.2163 0.2179 0.2217 0.2282 0.2372 0.2500 0.2631 0.2713 0.2739 0.2725 0.2678 0.2660 0.2770 0.3025 const double ColorTemp::JDC468_Greyredbl94_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0506, 0.053, 0.0569, 0.06, 0.0678, 0.08, 0.0906, 0.1, 0.1088, 0.11, 0.1160, 0.117, 0.1184, 0.119, 0.1195, 0.12, 0.1203, 0.1205, 0.1215, 0.125, 0.1293, 0.133, 0.1474, 0.15, @@ -2005,10 +1748,6 @@ const double ColorTemp::JDC468_Greyredbl94_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - - -//32 32 0.0933 0.1333 0.1967 0.3132 0.4096 0.4556 0.4763 0.4845 0.4870 0.4852 0.4868 0.4959 0.4971 0.4755 0.4407 0.4085 0.3643 0.2922 0.2161 0.1658 0.1370 0.1190 0.1040 0.0947 0.0949 0.1001 0.1106 0.1306 0.1536 0.1652 0.1609 0.1480 0.1291 0.1188 0.1370 0.1933 const double ColorTemp::JDC468_Blue32_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0933, 0.11, 0.1333, 0.17, 0.1967, 0.265, 0.3132, 0.35, 0.4096, 0.43, 0.4556, 0.465, 0.4763, 0.48, 0.4845, 0.486, .4870, 0.486, 0.4852, 0.486, 0.4868, 0.49, 0.4959, 0.496, @@ -2017,9 +1756,6 @@ const double ColorTemp::JDC468_Blue32_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - - -//236 236 0.0165 0.0259 0.0432 0.0684 0.0858 0.0895 0.0828 0.0683 0.0527 0.0365 0.0235 0.0177 0.0143 0.0096 0.0067 0.0063 0.0060 0.0052 0.0053 0.0061 0.0074 0.0083 0.0085 0.0080 0.0078 0.0076 0.0081 0.0095 0.0112 0.0121 0.0114 0.0100 0.0086 0.0083 0.0102 0.0180 const double ColorTemp::JDC468_Blue236_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0165, 0.021, 0.0259, 0.035, 0.0432, 0.05, 0.0684, 0.075, 0.0858, 0.087, 0.0895, 0.085, 0.0828, 0.075, 0.0683, 0.058, 0.0527, 0.045, 0.0365, 0.031, 0.0235, 0.021, 0.0177, 0.016, @@ -2028,8 +1764,6 @@ const double ColorTemp::JDC468_Blue236_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//300 300 0.0079 0.0085 0.0087 0.0092 0.0094 0.0093 0.0093 0.0095 0.0097 0.0110 0.0158 0.0544 0.1907 0.3753 0.4883 0.5181 0.5044 0.4631 0.4070 0.3594 0.3262 0.3054 0.2873 0.2772 0.2790 0.2875 0.3029 0.3292 0.3571 0.3719 0.3693 0.3573 0.3371 0.3253 0.3471 0.4087 const double ColorTemp::JDC468_Gre300_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0079, 0.008, 0.0085, 0.0086, 0.0087, 0.009, 0.0092, 0.0093, 0.0094, 0.0094, 0.0093, 0.0093, 0.0093, 0.0094, 0.0095, 0.0096, 0.0097, 0.01, 0.0110, 0.012, 0.0158, 0.045, @@ -2038,7 +1772,6 @@ const double ColorTemp::JDC468_Gre300_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//340 340 0.0175 0.0320 0.0587 0.0989 0.1267 0.1322 0.1210 0.0978 0.0732 0.0487 0.0297 0.0212 0.0167 0.0106 0.0069 0.0064 0.0062 0.0051 0.0052 0.0061 0.0073 0.0081 0.0080 0.0076 0.0075 0.0072 0.0077 0.0088 0.0105 0.0112 0.0104 0.0092 0.0079 0.0075 0.0092 0.0167 const double ColorTemp::JDC468_Blue340_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0175, 0.02, 0.0320, 0.04, 0.0587, 0.08, 0.0989, 0.11, 0.1267, 0.13, 0.1322, 0.125, 0.1210, 0.111, 0.0978, 0.08, 0.0732, 0.06, 0.0487, 0.04, 0.0297, 0.025, 0.0212, 0.02, @@ -2048,8 +1781,6 @@ const double ColorTemp::JDC468_Blue340_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//110 110 0.0954 0.1234 0.1702 0.2631 0.3363 0.3664 0.3799 0.3905 0.4002 0.4160 0.4582 0.5262 0.5798 0.5915 0.5742 0.5465 0.5035 0.4364 0.3581 0.2977 0.2589 0.2349 0.2152 0.2030 0.2032 0.2106 0.2249 0.2511 0.2799 0.2951 0.2915 0.2776 0.2552 0.2419 0.2638 0.3287 const double ColorTemp::JDC468_Gree110_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0954, 0.11, 0.1234, 0.15, 0.1702, 0.22, 0.2631, 0.312, 0.3363, 0.352, 0.3664, 0.372, 0.3799, 0.385, 0.3905, 0.395, 0.4002, 0.41, 0.4160, 0.43, 0.4582, 0.511, 0.5262, 0.544, @@ -2058,7 +1789,6 @@ const double ColorTemp::JDC468_Gree110_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//457 457 0.0127 0.0126 0.0112 0.0110 0.0109 0.0106 0.0105 0.0104 0.0110 0.0136 0.0318 0.1246 0.3262 0.5051 0.5566 0.5181 0.4406 0.3429 0.2411 0.1647 0.1202 0.0968 0.0804 0.0709 0.0703 0.0747 0.0840 0.1023 0.1243 0.1355 0.1311 0.1179 0.0993 0.0884 0.1043 0.1590 const double ColorTemp::JDC468_Gree457_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0127, 0.0126, 0.0126, 0.012, 0.0112, 0.011, 0.0110, 0.011, 0.0109, 0.0107, 0.0106, 0.0105, 0.0105, 0.0105, 0.0104, 0.0107, 0.0110, 0.0124, 0.0136, 0.0234, 0.0318, 0.09, @@ -2067,7 +1797,6 @@ const double ColorTemp::JDC468_Gree457_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//241 241 0.0134 0.0106 0.0110 0.0108 0.0111 0.0114 0.0114 0.0115 0.0114 0.0122 0.0192 0.0731 0.2455 0.4689 0.6183 0.6852 0.7107 0.7112 0.7059 0.7177 0.7335 0.7445 0.7487 0.7523 0.7555 0.7606 0.7683 0.7779 0.7855 0.7915 0.7964 0.8011 0.8056 0.8097 0.8144 0.8239 const double ColorTemp::JDC468_Yel241_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0134, 0.012, 0.0106, 0.011, 0.0110, 0.011, 0.0108, 0.011, 0.0111, 0.0112, 0.0114, 0.0114, 0.0114, 0.0114, 0.0115, 0.0114, 0.0114, 0.012, 0.0122, 0.017, 0.0192, 0.05, 0.0731, 0.12, @@ -2076,8 +1805,6 @@ const double ColorTemp::JDC468_Yel241_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//321 321 0.0247 0.0203 0.0182 0.0183 0.0182 0.0179 0.0182 0.0188 0.0199 0.0249 0.0529 0.1519 0.3116 0.4138 0.4410 0.4679 0.4906 0.4655 0.4517 0.5203 0.6238 0.6952 0.7270 0.7406 0.7469 0.7527 0.7607 0.7708 0.7786 0.7849 0.7897 0.7940 0.7984 0.8025 0.8069 0.8160 const double ColorTemp::JDC468_Ora321_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0247, 0.022, 0.0203, 0.019, 0.0182, 0.0182, 0.0183, 0.0182, 0.0182, 0.018, 0.0179, 0.018, 0.0182, 0.0185, 0.0188, 0.019, 0.0199, 0.022, 0.0249, 0.035, 0.0529, 0.112, @@ -2085,7 +1812,7 @@ const double ColorTemp::JDC468_Ora321_spect[97] = { 0.7406, 0.743, 0.7469, .751, 0.7527, 0.756, 0.7607, 0.765, 0.7708, 0.774, 0.7786, 0.782, 0.7849, 0.786, 0.7897, 0.79, 0.7940, 0.794, 0.7984, 0.799, 0.8025, 0.805, 0.8069, 0.811, 0.8160, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//353 353 0.0260 0.0294 0.0331 0.0420 0.0490 0.0517 0.0541 0.0572 0.0608 0.0664 0.0813 0.1070 0.1291 0.1344 0.1317 0.1356 0.1390 0.1289 0.1195 0.1278 0.1420 0.1493 0.1500 0.1500 0.1527 0.1576 0.1651 0.1759 0.1870 0.1942 0.1963 0.1952 0.1910 0.1898 0.1995 0.2209 + const double ColorTemp::JDC468_Yellow353_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0260, 0.027, 0.0294, 0.031, 0.0331, 0.037, 0.0420, 0.045, 0.0490, 0.051, 0.0517, 0.053, 0.0541, 0.056, 0.0572, 0.059, 0.0608, 0.063, 0.0664, 0.072, 0.0813, 0.096, 0.1070, 0.112, @@ -2094,8 +1821,6 @@ const double ColorTemp::JDC468_Yellow353_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//465 465 0.0388 0.0654 0.1020 0.1557 0.1880 0.1783 0.1434 0.1013 0.0684 0.0410 0.0219 0.0149 0.0117 0.0080 0.0062 0.0062 0.0062 0.0056 0.0063 0.0098 0.0230 0.0440 0.0577 0.0617 0.0645 0.0690 0.0766 0.0903 0.1064 0.1144 0.1113 0.1022 0.0898 0.0833 0.0962 0.1377 const double ColorTemp::JDC468_Mag465_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0388, 0.05, 0.0654, 0.09, 0.1020, 0.12, 0.1557, 0.17, 0.1880, 0.182, 0.1783, 0.162, 0.1434, 0.12, 0.1013, 0.09, 0.0684, 0.05, 0.0410, 0.03, 0.0219, 0.02, 0.0149, 0.012, @@ -2104,8 +1829,6 @@ const double ColorTemp::JDC468_Mag465_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//333 333 0.1030 0.1508 0.2133 0.3191 0.3910 0.3895 0.3424 0.2770 0.2184 0.1593 0.1074 0.0825 0.0669 0.0430 0.0265 0.0278 0.0315 0.0212 0.0163 0.0355 0.0861 0.1365 0.1565 0.1589 0.1629 0.1713 0.1852 0.2099 0.2378 0.2517 0.2469 0.2322 0.2102 0.1973 0.2191 0.2855 const double ColorTemp::JDC468_Mag333_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1030, 0.12, 0.1508, 0.18, 0.2133, 0.26, 0.3191, 0.364, 0.3910, 0.39, 0.3895, 0.375, 0.3424, 0.312, 0.2770, 0.251, 0.2184, 0.183, 0.1593, 0.122, 0.1074, 0.1, 0.0825, 0.07, @@ -2114,8 +1837,6 @@ const double ColorTemp::JDC468_Mag333_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -//203 203 0.0833 0.1329 0.2005 0.3099 0.3855 0.3916 0.3530 0.2926 0.2346 0.1741 0.1201 0.0934 0.0759 0.0495 0.0306 0.0308 0.0330 0.0214 0.0150 0.0256 0.0510 0.0723 0.0769 0.0748 0.0761 0.0813 0.0911 0.1087 0.1295 0.1399 0.1353 0.1232 0.1064 0.0971 0.1137 0.1677 const double ColorTemp::JDC468_Mag203_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0833, 0.11, 0.1329, 0.16, 0.2005, 0.25, 0.3099, 0.342, 0.3855, 0.39, 0.3916, 0.374, 0.3530, 0.321, 0.2926, 0.267, 0.2346, 0.21, 0.1741, 0.153, 0.1201, 0.1, 0.0934, 0.08, @@ -2123,7 +1844,7 @@ const double ColorTemp::JDC468_Mag203_spect[97] = { 0.0761, 0.08, 0.0813, 0.09, 0.0911, 0.1, 0.1087, 0.115, 0.1295, 0.134, 0.1399, 0.136, 0.1353, 0.131, 0.1232, 0.114, 0.1064, 0.1, 0.0971, 0.105, 0.1137, 0.123, 0.1677, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//blue cyan + const double ColorTemp::J570_BlueB6_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1611, 0.18, 0.1947, 0.23, 0.2639, 0.31, 0.3488, 0.37, 0.4022, 0.43, 0.4517, 0.49, 0.501, 0.52, 0.5317, 0.534, 0.5367, 0.53, 0.5246, 0.51, 0.4905, 0.47, 0.4510, 0.43, 0.4059, @@ -2322,7 +2043,6 @@ const double ColorTemp::J570_BlueU8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//N8 const double ColorTemp::J570_NeuN8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0632, -0.04, -0.0244, 0.01, 0.0125, 0.02, 0.0294, 0.03, 0.0326, 0.033, 0.0352, 0.036, 0.0361, 0.037, 0.0374, 0.0374, 0.0373, 0.038, 0.0378, 0.039, 0.0397, 0.04, @@ -2331,6 +2051,16 @@ const double ColorTemp::J570_NeuN8_spect[97] = { 0.0395, 0.04, 0.0415, 0.043, 0.0448, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuN8_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0632, -0.04, -0.0244, 0.01, 0.0135, 0.02, 0.0294, 0.03, 0.0326, 0.033, 0.0352, 0.036, 0.0361, 0.037, 0.0374, 0.0374, 0.0373, 0.038, 0.0378, 0.039, 0.0397, 0.04, + 0.0421, 0.043, 0.0431, 0.042, 0.0417, 0.04, 0.0391, 0.038, 0.0378, 0.037, 0.0368, 0.035, 0.0347, 0.034, 0.0335, 0.034, 0.0341, 0.035, 0.0350, 0.035, 0.0355, 0.036, + 0.0357, 0.0357, 0.0358, 0.036, 0.0369, 0.037, 0.0372, 0.0376, 0.0378, 0.038, 0.0388, 0.039, 0.0397, 0.04, 0.0400, 0.0395, 0.0394, 0.039, 0.0386, 0.0385, 0.0384, 0.039, + 0.0395, 0.04, 0.0415, 0.043, 0.0448, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuN9_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0573, 0.054, 0.0516, 0.053, 0.0548, 0.05, 0.0401, 0.041, 0.0424, 0.043, 0.0449, 0.046, 0.0467, 0.047, 0.0473, 0.0473, 0.0474, 0.048, 0.0483, 0.05, 0.0508, 0.053, @@ -2339,6 +2069,16 @@ const double ColorTemp::J570_NeuN9_spect[97] = { 0.0515, 0.053, 0.0538, 0.056, 0.0597, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuN9_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0573, 0.054, 0.0516, 0.053, 0.0548, 0.05, 0.0401, 0.041, 0.0424, 0.043, 0.0459, 0.046, 0.0467, 0.047, 0.0473, 0.0473, 0.0474, 0.048, 0.0483, 0.05, 0.0508, 0.053, + 0.0558, 0.057, 0.0584, 0.058, 0.0550, 0.05, 0.0495, 0.048, 0.0468, 0.0465, 0.0460, 0.044, 0.0430, 0.042, 0.0411, 0.042, 0.0425, 0.044, 0.0457, 0.046, 0.0473, 0.0474, + 0.0475, 0.0475, 0.0474, 0.0475, 0.0476, 0.048, 0.0487, 0.049, 0.0499, 0.05, 0.0515, 0.052, 0.0533, 0.054, 0.0544, 0.054, 0.0539, 0.053, 0.0526, 0.052, 0.0512, 0.0515, + 0.0515, 0.053, 0.0538, 0.056, 0.0597, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuO8_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0014, 0.02, 0.0806, 0.07, 0.0673, 0.07, 0.0854, 0.09, 0.0901, 0.095, 0.0960, 0.098, 0.0992, 0.1, 0.1017, 0.102, 0.1030, 0.104, 0.1052, 0.107, 0.1098, 0.11, @@ -2347,6 +2087,16 @@ const double ColorTemp::J570_NeuO8_spect[97] = { 0.1132, 0.115, 0.1185, 0.12, 0.1345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuO8_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0014, 0.02, 0.0806, 0.07, 0.0673, 0.07, 0.0854, 0.09, 0.0901, 0.095, 0.0960, 0.098, 0.0992, 0.1, 0.1017, 0.102, 0.1030, 0.104, 0.1052, 0.107, 0.1098, 0.11, + 0.1176, 0.12, 0.1230, 0.12, 0.1276, 0.11, 0.1071, 0.105, 0.1032, 0.103, 0.1032, 0.1, 0.0963, 0.09, 0.0899, 0.09, 0.0939, 0.095, 0.1007, 0.102, 0.1037, 0.104, + 0.1029, 0.102, 0.1014, 0.102, 0.1220, 0.103, 0.1039, 0.105, 0.1072, 0.11, 0.1134, 0.12, 0.1207, 0.122, 0.1245, 0.123, 0.1236, 0.121, 0.1205, 0.12, 0.1158, 0.115, + 0.1132, 0.115, 0.1185, 0.12, 0.1345, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuO11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2926, 0.2, 0.1863, 0.16, 0.1428, 0.14, 0.1322, 0.134, 0.1396, 0.14, 0.1450, 0.146, 0.1498, 0.15, 0.1527, 0.155, 0.1554, 0.157, 0.1583, 0.16, 0.1631, 0.17, @@ -2355,6 +2105,16 @@ const double ColorTemp::J570_NeuO11_spect[97] = { 0.1716, 0.175, 0.1800, 0.2, 0.2039, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuO11_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2926, 0.2, 0.1863, 0.16, 0.1428, 0.14, 0.1322, 0.134, 0.1396, 0.14, 0.1450, 0.146, 0.1498, 0.15, 0.1527, 0.155, 0.1554, 0.157, 0.1583, 0.16, 0.1631, 0.17, + 0.1754, 0.18, 0.1841, 0.18, 0.1861, 0.17, 0.1600, 0.155, 0.1549, 0.155, 0.1555, 0.15, 0.1449, 0.14, 0.1352, 0.14, 0.1414, 0.15, 0.1519, 0.153, 0.1568, 0.156, + 0.1556, 0.154, 0.1534, 0.154, 0.1647, 0.156, 0.1573, 0.16, 0.1622, 0.17, 0.1713, 0.18, 0.1823, 0.185, 0.1886, 0.188, 0.1873, 0.183, 0.1829, 0.18, 0.1753, 0.174, + 0.1716, 0.175, 0.1800, 0.2, 0.2039, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuD5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0840, 0.1, 0.1627, 0.18, 0.1934, 0.2, 0.2234, 0.23, 0.2430, 0.25, 0.2547, 0.26, 0.2618, 0.264, 0.2651, 0.265, 0.2655, 0.2655, 0.2659, 0.266, 0.2674, 0.27, @@ -2364,6 +2124,15 @@ const double ColorTemp::J570_NeuD5_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::J570_NeuD5_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0840, 0.1, 0.1627, 0.18, 0.1934, 0.2, 0.2234, 0.23, 0.2430, 0.25, 0.2547, 0.26, 0.2618, 0.264, 0.2651, 0.265, 0.2655, 0.2655, 0.2659, 0.266, 0.2674, 0.27, + 0.2776, 0.28, 0.2841, 0.27, 0.2854, 0.25, 0.2351, 0.23, 0.2246, 0.225, 0.2247, 0.22, 0.2074, 0.20, 0.1913, 0.20, 0.2029, 0.21, 0.2231, 0.23, 0.2337, 0.233, + 0.2327, 0.23, 0.2291, 0.23, 0.2405, 0.232, 0.2344, 0.24, 0.2417, 0.25, 0.2553, 0.26, 0.2724, 0.28, 0.2816, 0.28, 0.2797, 0.276, 0.2720, 0.27, + 0.2603, 0.26, 0.2536, 0.26, 0.2660, 0.28, 0.3027, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuE11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1699, 0.18, 0.1971, 0.21, 0.2276, 0.23, 0.2483, 0.25, 0.2690, 0.28, 0.2820, 0.29, 0.2916, 0.295, 0.2992, 0.3, 0.3064, 0.31, 0.3151, 0.32, 0.3301, 0.34, 0.3593, 0.37, @@ -2371,6 +2140,13 @@ const double ColorTemp::J570_NeuE11_spect[97] = { 0.3086, 0.31, 0.3105, 0.312, 0.3148, 0.313, 0.3222, 0.33, 0.3364, 0.34, 0.3535, 0.36, 0.3629, 0.362, 0.3621, 0.36, 0.3549, 0.35, 0.3444, 0.34, 0.3394, 0.35, 0.3511, 0.36, 0.3862, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::J570_NeuE11_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1699, 0.18, 0.1971, 0.21, 0.2276, 0.23, 0.2483, 0.25, 0.2690, 0.28, 0.2820, 0.29, 0.2916, 0.295, 0.2992, 0.3, 0.3064, 0.31, 0.3151, 0.32, 0.3301, 0.34, 0.3593, 0.37, + 0.3873, 0.39, 0.3913, 0.38, 0.3993, 0.375, 0.3723, 0.37, 0.3678, 0.35, 0.3482, 0.33, 0.3249, 0.32, 0.3188, 0.319, 0.3188, 0.318, 0.3179, 0.315, 0.3128, 0.31, + 0.3086, 0.31, 0.3105, 0.312, 0.3248, 0.313, 0.3222, 0.33, 0.3364, 0.34, 0.3535, 0.36, 0.3629, 0.362, 0.3621, 0.36, 0.3549, 0.35, 0.3444, 0.34, 0.3394, 0.35, 0.3511, 0.36, 0.3862, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; const double ColorTemp::J570_NeuK16_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -2379,6 +2155,15 @@ const double ColorTemp::J570_NeuK16_spect[97] = { 0.5406, 0.542, 0.5418, 0.543, 0.5452, 0.55, 0.5529, 0.56, 0.5654, 0.57, 0.5806, 0.584, 0.5888, 0.589, 0.5898, 0.586, 0.5858, 0.58, 0.5796, 0.577, 0.5770, 0.58, 0.5883, 0.59, 0.6190, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuK16_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5837, 0.45, 0.4117, 0.43, 0.4427, 0.47, 0.5098, 0.52, 0.5451, 0.55, 0.5698, 0.57, 0.5828, 0.59, 0.5939, 0.6, 0.6045, 0.607, 0.6140, 0.62, 0.6219, 0.63, 0.6330, 0.64, + 0.6419, 0.643, 0.6440, 0.642, 0.6617, 0.64, 0.6379, 0.631, 0.6309, 0.62, 0.6154, 0.6, 0.5911, 0.58, 0.5736, 0.57, 0.5612, 0.56, 0.5539, 0.55, 0.5462, 0.543, + 0.5406, 0.542, 0.5418, 0.543, 0.5652, 0.55, 0.5529, 0.56, 0.5654, 0.57, 0.5806, 0.584, 0.5888, 0.589, 0.5898, 0.586, 0.5858, 0.58, 0.5796, 0.577, 0.5770, 0.58, 0.5883, 0.59, 0.6190, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuM3_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2659, 0.255, 0.2526, 0.26, 0.2616, 0.27, 0.2854, 0.29, 0.3088, 0.31, 0.3231, 0.33, 0.3336, 0.34, 0.3421, 0.345, 0.347, 0.35, 0.3542, 0.36, 0.3647, 0.37, @@ -2386,6 +2171,15 @@ const double ColorTemp::J570_NeuM3_spect[97] = { 0.3240, 0.322, 0.3202, 0.321, 0.3220, 0.323, 0.3267, 0.33, 0.3342, 0.34, 0.3487, 0.35, 0.3667, 0.37, 0.3761, 0.375, 0.3746, 0.37, 0.3670, 0.36, 0.3559, 0.35, 0.3498, 0.35, 0.3630, 0.37, 0.3998, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuM3_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2659, 0.255, 0.2526, 0.26, 0.2616, 0.27, 0.2854, 0.29, 0.3088, 0.31, 0.3231, 0.33, 0.3336, 0.34, 0.3421, 0.345, 0.347, 0.35, 0.3542, 0.36, 0.3647, 0.37, + 0.3854, 0.4, 0.4041, 0.452, 0.4012, 0.39, 0.3856, 0.38, 0.3769, 0.375, 0.3725, 0.36, 0.3525, 0.34, 0.3286, 0.325, 0.3247, 0.326, 0.3279, 0.328, 0.3285, 0.325, + 0.3240, 0.322, 0.3202, 0.341, 0.3220, 0.323, 0.3267, 0.33, 0.3342, 0.34, 0.3487, 0.35, 0.3667, 0.37, 0.3761, 0.375, 0.3746, 0.37, 0.3670, 0.36, 0.3559, 0.35, 0.3498, 0.35, 0.3630, 0.37, 0.3998, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuN18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1284, 0.11, 0.1090, 0.13, 0.1573, 0.17, 0.1837, 0.19, 0.1971, 0.2, 0.2059, 0.21, 0.2143, 0.22, 0.2213, 0.225, 0.2271, 0.23, 0.2341, 0.24, 0.2487, 0.26, 0.2764, 0.29, @@ -2393,6 +2187,15 @@ const double ColorTemp::J570_NeuN18_spect[97] = { 0.2235, 0.224, 0.2246, 0.226, 0.2282, 0.23, 0.2349, 0.24, 0.2477, 0.25, 0.2632, 0.27, 0.2714, 0.271, 0.2702, 0.27, 0.2637, 0.26, 0.2538, 0.25, 0.2479, 0.25, 0.2589, 0.26, 0.2918, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuN18_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1284, 0.11, 0.1090, 0.13, 0.1573, 0.17, 0.1837, 0.19, 0.1971, 0.2, 0.2059, 0.21, 0.2143, 0.22, 0.2213, 0.225, 0.2271, 0.23, 0.2341, 0.24, 0.2487, 0.26, 0.2764, 0.29, + 0.3025, 0.303, 0.3052, 0.3, 0.2819, 0.29, 0.2843, 0.283, 0.2800, 0.27, 0.2612, 0.24, 0.2394, 0.235, 0.2339, 0.234, 0.2340, 0.233, 0.2326, 0.23, 0.2277, 0.225, + 0.2235, 0.224, 0.2246, 0.226, 0.2382, 0.23, 0.2349, 0.24, 0.2477, 0.25, 0.2632, 0.27, 0.2714, 0.271, 0.2702, 0.27, 0.2637, 0.26, 0.2538, 0.25, 0.2479, 0.25, 0.2589, 0.26, 0.2918, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuQ1_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0610, 0.06, 0.0592, 0.04, 0.0339, 0.04, 0.0338, 0.034, 0.0350, 0.036, 0.0363, 0.037, 0.0380, 0.038, 0.0383, 0.0383, 0.0385, 0.04, 0.0408, 0.042, 0.0451, 0.05, @@ -2401,6 +2204,16 @@ const double ColorTemp::J570_NeuQ1_spect[97] = { 0.0351, 0.036, 0.0373, 0.038, 0.0411, 0.042, 0.0446, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuQ1_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0610, 0.06, 0.0592, 0.04, 0.0359, 0.04, 0.0338, 0.034, 0.0350, 0.036, 0.0363, 0.037, 0.0380, 0.038, 0.0383, 0.0383, 0.0385, 0.04, 0.0408, 0.042, 0.0451, 0.05, + 0.0524, 0.055, 0.0589, 0.058, 0.0595, 0.055, 0.0529, 0.05, 0.0456, 0.04, 0.0390, 0.035, 0.0330, 0.03, 0.0286, 0.028, 0.0275, 0.0276, 0.0275, 0.0278, 0.0279, 0.028, + 0.0289, 0.03, 0.0304, 0.031, 0.0340, 0.032, 0.0328, 0.033, 0.0341, 0.0345, 0.0346, 0.0346, 0.0347, 0.034, 0.0341, 0.034, 0.0336, 0.034, 0.0340, 0.035, + 0.0351, 0.036, 0.0373, 0.038, 0.0411, 0.042, 0.0446, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuS7_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1447, 0.06, 0.0448, 0.042, 0.0411, 0.03, 0.0282, 0.028, 0.0270, 0.029, 0.0298, 0.03, 0.0319, 0.032, 0.0331, 0.0333, 0.0335, 0.036, 0.0361, 0.038, 0.0403, 0.045, @@ -2409,6 +2222,17 @@ const double ColorTemp::J570_NeuS7_spect[97] = { 0.0361, 0.0362, 0.0363, 0.037, 0.0376, 0.04, 0.0412, 0.042, 0.0450, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuS7_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1447, 0.06, 0.0448, 0.042, 0.0511, 0.03, 0.0282, 0.028, 0.0270, 0.029, 0.0298, 0.03, 0.0319, 0.032, 0.0331, 0.0333, 0.0335, 0.036, 0.0361, 0.038, 0.0403, 0.045, + 0.0493, 0.05, 0.0599, 0.06, 0.0666, 0.062, 0.0606, 0.06, 0.0547, 0.05, 0.0488, 0.045, 0.0421, 0.04, 0.0366, 0.035, 0.0335, 0.033, 0.0323, 0.032, 0.0320, 0.032, + 0.0321, 0.0322, 0.0324, 0.033, 0.0333, 0.034, 0.0345, 0.035, 0.0356, 0.036, 0.0364, 0.037, 0.0372, 0.037, 0.0367, 0.0365, 0.0363, 0.0364, + 0.0361, 0.0362, 0.0363, 0.037, 0.0376, 0.04, 0.0412, 0.042, 0.0450, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + const double ColorTemp::J570_NeuV10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1439, 0.07, 0.0583, 0.04, 0.0372, 0.037, 0.0362, 0.035, 0.0344, 0.034, 0.0340, 0.035, 0.0351, 0.036, 0.0361, 0.0361, 0.0361, 0.037, 0.0377, 0.039, 0.0404, 0.042, @@ -2417,6 +2241,17 @@ const double ColorTemp::J570_NeuV10_spect[97] = { 0.0341, 0.035, 0.0371, 0.038, 0.0399, 0.041, 0.0432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuV10_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1439, 0.07, 0.0583, 0.04, 0.0392, 0.037, 0.0362, 0.035, 0.0344, 0.034, 0.0340, 0.035, 0.0351, 0.036, 0.0361, 0.0361, 0.0361, 0.037, 0.0377, 0.039, 0.0404, 0.042, + 0.0450, 0.047, 0.0483, 0.048, 0.0495, 0.045, 0.0436, 0.04, 0.0387, 0.036, 0.0343, 0.03, 0.0299, 0.028, 0.0271, 0.027, 0.0262, 0.0262, 0.0262, 0.0267, 0.0269, 0.027, + 0.0283, 0.029, 0.0299, 0.03, 0.0328, 0.031, 0.0319, 0.032, 0.0331, 0.0333, 0.0337, 0.0337, 0.0337, 0.0333, 0.0332, 0.0332, 0.0331, 0.0331, 0.0331, 0.034, + 0.0341, 0.035, 0.0371, 0.038, 0.0399, 0.041, 0.0432, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + const double ColorTemp::J570_NeuW18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4685, 0.45, 0.4262, 0.5, 0.5061, 0.55, 0.5898, 0.6, 0.6487, 0.66, 0.6781, 0.68, 0.6947, 0.7, 0.7070, 0.71, 0.7185, 0.72, 0.7294, 0.73, 0.7383, 0.74, 0.7499, 0.75, @@ -2424,6 +2259,15 @@ const double ColorTemp::J570_NeuW18_spect[97] = { 0.6512, 0.65, 0.6462, 0.645, 0.6448, 0.645, 0.6485, 0.65, 0.6569, 0.66, 0.6698, 0.67, 0.6781, 0.68, 0.6822, 0.682, 0.6820, 0.682, 0.6815, 0.682, 0.6820, 0.69, 0.6907, 0.7, 0.7152, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuW18_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4685, 0.45, 0.4262, 0.5, 0.5061, 0.55, 0.5998, 0.6, 0.6487, 0.66, 0.6781, 0.68, 0.6947, 0.7, 0.7070, 0.71, 0.7185, 0.72, 0.7294, 0.73, 0.7383, 0.74, 0.7499, 0.75, + 0.7582, 0.758, 0.7582, 0.755, 0.7531, 0.75, 0.7584, 0.745, 0.7422, 0.73, 0.7263, 0.72, 0.7033, 0.7, 0.6913, 0.69, 0.6820, 0.68, 0.6738, 0.67, 0.6628, 0.66, + 0.6512, 0.65, 0.6462, 0.645, 0.6448, 0.645, 0.6485, 0.65, 0.6569, 0.66, 0.6698, 0.67, 0.6781, 0.68, 0.6822, 0.682, 0.6820, 0.682, 0.6815, 0.682, 0.6820, 0.69, 0.6907, 0.7, 0.7152, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuZ14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2765, 0.2, 0.1352, 0.13, 0.1222, 0.121, 0.1206, 0.13, 0.1300, 0.134, 0.1357, 0.14, 0.1407, 0.142, 0.1455, 0.147, 0.1485, 0.15, 0.1539, 0.16, 0.1648, 0.17, @@ -2433,6 +2277,15 @@ const double ColorTemp::J570_NeuZ14_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::J570_NeuZ14_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2765, 0.2, 0.1352, 0.13, 0.1222, 0.121, 0.1206, 0.13, 0.1300, 0.134, 0.1357, 0.14, 0.1407, 0.142, 0.1455, 0.147, 0.1485, 0.15, 0.1539, 0.16, 0.1648, 0.17, + 0.1844, 0.2, 0.2015, 0.202, 0.2024, 0.2, 0.2022, 0.19, 0.1868, 0.185, 0.1841, 0.18, 0.1715, 0.16, 0.1566, 0.155, 0.1536, 0.154, 0.1545, 0.154, 0.1536, 0.151, + 0.1500, 0.148, 0.1471, 0.1472, 0.1478, 0.15, 0.1605, 0.153, 0.1552, 0.16, 0.1641, 0.17, 0.1751, 0.18, 0.1813, 0.181, 0.1801, 0.18, + 0.1757, 0.17, 0.1683, 0.165, 0.1642, 0.17, 0.1728, 0.18, 0.1970, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuC18_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0555, 0.055, 0.0545, 0.055, 0.0585, 0.058, 0.0577, 0.056, 0.0554, 0.056, 0.0564, 0.058, 0.0590, 0.06, 0.0611, 0.062, 0.0638, 0.065, 0.0685, 0.07, 0.0797, 0.09, @@ -2441,6 +2294,16 @@ const double ColorTemp::J570_NeuC18_spect[97] = { 0.0858, 0.09, 0.0903, 0.1, 0.1037, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuC18_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0555, 0.055, 0.0545, 0.055, 0.0585, 0.058, 0.0577, 0.056, 0.0554, 0.056, 0.0564, 0.058, 0.0590, 0.06, 0.0611, 0.062, 0.0638, 0.065, 0.0685, 0.07, 0.0797, 0.09, + 0.1009, 0.11, 0.1222, 0.124, 0.1398, 0.127, 0.1257, 0.123, 0.1208, 0.12, 0.1164, 0.11, 0.1067, 0.1, 0.0954, 0.09, 0.0895, 0.088, 0.0862, 0.085, 0.0834, 0.082, + 0.0806, 0.08, 0.0782, 0.078, 0.0880, 0.078, 0.0789, 0.08, 0.0813, 0.084, 0.0858, 0.09, 0.0911, 0.092, 0.0944, 0.093, 0.0938, 0.092, 0.0914, 0.09, 0.0878, 0.086, + 0.0858, 0.09, 0.0903, 0.1, 0.1037, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::J570_NeuD17_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1980, 0.1, 0.0793, 0.06, 0.0578, 0.05, 0.0476, 0.046, 0.0454, 0.046, 0.0471, 0.048, 0.0499, 0.05, 0.0518, 0.052, 0.0533, 0.055, 0.0574, 0.06, 0.0676, 0.07, @@ -2449,6 +2312,17 @@ const double ColorTemp::J570_NeuD17_spect[97] = { 0.0360, 0.037, 0.0376, 0.039, 0.0406, 0.042, 0.0448, 0.046, 0.0499, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::J570_NeuD17_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1980, 0.1, 0.0793, 0.06, 0.0578, 0.05, 0.0476, 0.046, 0.0454, 0.046, 0.0471, 0.048, 0.0499, 0.05, 0.0518, 0.052, 0.0533, 0.055, 0.0574, 0.06, 0.0676, 0.07, + 0.0897, 0.1, 0.1129, 0.113, 0.1240, 0.1, 0.0958, 0.08, 0.0743, 0.06, 0.0566, 0.05, 0.0422, 0.04, 0.0332, 0.03, 0.0297, 0.0295, 0.0292, 0.0293, 0.0294, 0.03, + 0.0306, 0.031, 0.0319, 0.032, 0.0439, 0.034, 0.0353, 0.036, 0.0363, 0.037, 0.0370, 0.037, 0.0372, 0.037, 0.0368, 0.0365, 0.0363, 0.036, + 0.0360, 0.037, 0.0376, 0.039, 0.0406, 0.042, 0.0448, 0.046, 0.0499, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + const double ColorTemp::J570_NeuJ11_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1274, 0.1, 0.0916, 0.08, 0.0656, 0.061, 0.0604, 0.06, 0.0570, 0.06, 0.0604, 0.062, 0.0644, 0.065, 0.0668, 0.069, 0.0700, 0.072, 0.0754, 0.08, 0.0874, 0.1, @@ -2457,6 +2331,16 @@ const double ColorTemp::J570_NeuJ11_spect[97] = { 0.0424, 0.043, 0.0458, 0.048, 0.0522, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::J570_NeuJ11_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1274, 0.1, 0.0916, 0.08, 0.0756, 0.061, 0.0604, 0.06, 0.0570, 0.06, 0.0604, 0.062, 0.0644, 0.065, 0.0668, 0.069, 0.0700, 0.072, 0.0754, 0.08, 0.0874, 0.1, + 0.1111, 0.12, 0.1327, 0.132, 0.1413, 0.12, 0.1127, 0.1, 0.0931, 0.08, 0.0758, 0.06, 0.0580, 0.05, 0.0449, 0.04, 0.0385, 0.037, 0.0360, 0.036, 0.0351, 0.035, + 0.0351, 0.0354, 0.0355, 0.036, 0.0371, 0.0375, 0.0379, 0.038, 0.0388, 0.04, 0.0406, 0.041, 0.0414, 0.0415, 0.0416, 0.041, 0.0409, 0.04, 0.0398, 0.0397, 0.0397, 0.04, + 0.0424, 0.043, 0.0458, 0.048, 0.0522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + const double ColorTemp::J570_NeuL4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0348, 0.05, 0.0700, 0.09, 0.1043, 0.11, 0.1320, 0.14, 0.1505, 0.16, 0.1622, 0.17, 0.1721, 0.18, 0.1805, 0.185, 0.1877, 0.19, 0.1955, 0.2, 0.2068, 0.21, @@ -2466,6 +2350,15 @@ const double ColorTemp::J570_NeuL4_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::J570_NeuL4_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0348, 0.05, 0.0700, 0.09, 0.1043, 0.11, 0.1320, 0.14, 0.1505, 0.16, 0.1622, 0.17, 0.1721, 0.18, 0.1805, 0.185, 0.1877, 0.19, 0.1955, 0.2, 0.2068, 0.21, + 0.2226, 0.23, 0.2350, 0.235, 0.2452, 0.23, 0.2251, 0.22, 0.2128, 0.2, 0.1990, 0.18, 0.1761, 0.16, 0.1494, 0.13, 0.1296, 0.12, 0.1171, 0.11, 0.1089, 0.105, + 0.1010, 0.1, 0.0949, 0.093, 0.0826, 0.093, 0.0937, 0.095, 0.0961, 0.1, 0.1020, 0.11, 0.1104, 0.112, 0.1150, 0.115, 0.1155, 0.113, 0.1123, 0.11, + 0.1070, 0.105, 0.1040, 0.11, 0.1110, 0.12, 0.1323, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::Colorlab_n72_n2_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0116, 0.01, 0.0171, 0.05, 0.0625, 0.08, 0.1486, 0.16, 0.1963, 0.2, 0.2409, 0.26, 0.2974, 0.31, 0.3468, 0.36, 0.3790, 0.39, 0.4075, 0.41, 0.4216, 0.43, @@ -2482,6 +2375,34 @@ const double ColorTemp::Colorlab_10_n70_spect[97] = { 0.3187, 0.31, 0.3082, 0.305, 0.3014, 0.304, 0.3059, 0.31, 0.3253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + +const double ColorTemp::Colorlab_10_n70_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0964, 0.1, 0.1534, 0.2, 0.2437, 0.33, 0.4663, 0.5, 0.6005, 0.65, 0.6958, 0.75, 0.8010, 0.83, 0.8598, 0.858, 0.8579, 0.85, 0.8432, 0.83, 0.8102, 0.79, + 0.7607, 0.7, 0.6760, 0.65, 0.5530, 0.55, 0.4212, 0.3, 0.2974, 0.25, 0.1839, 0.12, 0.0743, 0.03, -0.0208, -0.05, -0.0747, -0.08, -0.0913, -0.05, -0.0458, 0.03, + 0.0806, 0.1, 0.1936, 0.2, 0.2556, 0.27, 0.2816, 0.29, 0.2925, 0.3, 0.3033, 0.31, 0.3175, 0.32, 0.3257, 0.325, 0.3246, 0.32, + 0.3187, 0.31, 0.3082, 0.305, 0.3014, 0.304, 0.3059, 0.34, 0.3353, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_10_n70_spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0964, 0.1, 0.1534, 0.2, 0.2437, 0.33, 0.4663, 0.5, 0.6005, 0.65, 0.6958, 0.75, 0.8010, 0.83, 0.8598, 0.858, 0.8579, 0.85, 0.8432, 0.83, 0.8102, 0.79, + 0.7607, 0.7, 0.6760, 0.65, 0.5530, 0.55, 0.4212, 0.3, 0.2974, 0.25, 0.1839, 0.12, 0.0743, 0.03, -0.0208, -0.05, -0.0747, -0.08, -0.0913, -0.05, -0.0458, 0.03, + 0.0806, 0.1, 0.1936, 0.22, 0.2556, 0.27, 0.2816, 0.29, 0.2925, 0.33, 0.3033, 0.33, 0.3175, 0.32, 0.3257, 0.325, 0.3246, 0.32, + 0.3187, 0.32, 0.3082, 0.305, 0.3014, 0.304, 0.3059, 0.36, 0.3353, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_10_n70_spect4[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0964, 0.1, 0.1534, 0.2, 0.2437, 0.34, 0.4663, 0.55, 0.6005, 0.65, 0.6958, 0.75, 0.8010, 0.83, 0.8598, 0.858, 0.8579, 0.86, 0.8432, 0.82, 0.8102, 0.79, + 0.7607, 0.7, 0.6760, 0.6, 0.5530, 0.5, 0.4212, 0.3, 0.2974, 0.20, 0.1839, 0.12, 0.0743, 0.03, -0.0208, -0.05, -0.0747, -0.08, -0.0913, -0.05, -0.0458, 0.03, + 0.0806, 0.1, 0.1936, 0.22, 0.2556, 0.27, 0.2816, 0.29, 0.2925, 0.33, 0.3033, 0.33, 0.3175, 0.32, 0.3257, 0.325, 0.3246, 0.32, + 0.3187, 0.32, 0.3082, 0.305, 0.3014, 0.304, 0.3059, 0.36, 0.3353, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + const double ColorTemp::Colorlab_n33_n70_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0615, 0.1, 0.1219, 0.2, 0.2179, 0.3, 0.4397, 0.5, 0.5722, 0.6, 0.6714, 0.7, 0.7834, 0.8, 0.8535, 0.86, 0.8647, 0.864, 0.8642, 0.864, 0.8429, 0.82, @@ -2522,11 +2443,8 @@ const double ColorTemp::Colorlab_n80_26_spect[97] = { -0.2047, -0.205, -0.2069, -0.208, -0.2099, -0.21, -0.2115, -0.21, -0.2106, -0.209, -0.2086, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -/* -//0,1767000 0,2207000 0,3142000 0,5269000 0,7018000 0,7605000 0,7580000 0,7366000 0,7182000 0,6929000 0,6661000 0,6542000 -//0,6420000 0,6085000 0,5752000 0,5728000 0,5723000 0,5318000 0,4982000 0,5226000 0,5670000 0,5929000 0,5977000 0,5975000 -//0,6002000 0,6065000 0,6177000 0,6352000 0,6526000 0,6623000 0,6633000 0,6593000 0,6517000 0,6479000 0,6607000 0,6908000 +/* const double ColorTemp::JDC468_greyc14_66_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767, 0.19, 0.2207, 0.25, 0.3142, 0.40, 0.5269, 0.63, 0.7018, 0.73, 0.7605, 0.76, 0.7580, 0.74, 0.7366, 0.725, 0.7182, 0.705, 0.6929, 0.68, 0.6661, 0.66, 0.6542, 0.65, @@ -2534,9 +2452,6 @@ const double ColorTemp::JDC468_greyc14_66_spect[97] = { 0.6002, 0.602, 0.6065, 0.61, 0.6177, 0.62, 0.6352, 0.64, 0.6526, 0.66, 0.6623, 0.662, 0.6633, 0.66, 0.6593, 0.653, 0.6517, 0.65, 0.6479, 0.65, 0.6607, 0.69, 0.6908, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0,1325000 0,1637000 0,2222000 0,3492000 0,4523000 0,4897000 0,4918000 0,4840000 0,4761000 0,4638000 0,4538000 0,4582000 -// 0,4588000 0,4360000 0,4091000 0,4101000 0,4128000 0,3785000 0,3494000 0,3720000 0,4122000 0,4339000 0,4362000 0,4355000 -// 0,4395000 0,4475000 0,4606000 0,4807000 0,5006000 0,5125000 0,5145000 0,5112000 0,5029000 0,4992000 0,5150000 0,5526000 const double ColorTemp::JDC468_greym13_325_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -2546,10 +2461,6 @@ const double ColorTemp::JDC468_greym13_325_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; -//0,0823000 0,1036000 0,1337000 0,1966000 0,2468000 0,2679000 0,2728000 0,2726000 0,2724000 0,2698000 0,2705000 0,2810000 -// 0,2879000 0,2756000 0,2586000 0,2601000 0,2617000 0,2357000 0,2124000 0,2241000 0,2471000 0,2581000 0,2569000 0,2548000 -// 0,2579000 0,2653000 0,2765000 0,2941000 0,3126000 0,3230000 0,3238000 0,3189000 0,3091000 0,3043000 0,3200000 0,3579000 - const double ColorTemp::JDC468_greyf26_156_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0823, 0.1, 0.1036, 0.11, 0.1337, 0.16, 0.1966, 0.22, 0.2468, 0.255, 0.2679, 0.27, 0.2728, 0.273, 0.2726, 0.273, 0.2724, 0.271, 0.2698, 0.27, 0.2705, 0.275, 0.2810, 0.285, @@ -2558,10 +2469,6 @@ const double ColorTemp::JDC468_greyf26_156_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; */ -//A1 0.0912 0.1228 0.1712 0.2978 0.3713 0.4241 0.4861 0.5255 0.5355 0.5363 0.5237 0.5251 -// 0.5722 0.6554 0.6936 0.6675 0.6203 0.5651 0.5116 0.4825 0.4714 0.4866 0.5320 0.5729 -// 0.5968 0.6069 0.6131 0.6198 0.6285 0.6325 0.6316 0.6282 0.6227 0.6196 0.6215 0.6337 - const double ColorTemp::Colorlab_n80_5_9_5_9spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0912, 0.1, 0.1228, 0.15, 0.1712, 0.2, 0.2978, 0.32, 0.3713, 0.41, 0.4241, 0.44, 0.4861, 0.51, 0.5255, 0.53, 0.5355, 0.534, 0.5363, 0.53, 0.5237, 0.524, 0.5251, 0.56, @@ -2570,10 +2477,6 @@ const double ColorTemp::Colorlab_n80_5_9_5_9spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* -//A2 0.0385 0.0514 0.0711 0.1229 0.1528 0.1744 0.1999 0.2163 0.2209 0.2216 0.2167 0.2185 -//0.2414 0.2813 0.3012 0.2922 0.2734 0.2511 0.2292 0.2173 0.2127 0.2183 0.2354 0.2508 -//0.2599 0.2637 0.2662 0.2689 0.2725 0.2742 0.2738 0.2724 0.2701 0.2689 0.2697 0.2747 - const double ColorTemp::Colorlab_n57_5_6_9spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0385, 0.04, 0.0514, 0.06, 0.0711, 0.1, 0.1229, 0.14, 0.1528, 0.16, 0.1744, 0.18, 0.1999, 0.2, 0.2163, 0.22, 0.2209, 0.221, 0.2216, 0.22, 0.2167, 0.216, 0.2185, 0.23, @@ -2582,6 +2485,1720 @@ const double ColorTemp::Colorlab_n57_5_6_9spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; */ +const double ColorTemp::Colorlab_L61_110_110Rec2020spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2118, 0.2100, 0.1920, 0.1800, 0.1574, 0.1575, 0.1578, 0.1600, 0.1631, 0.1500, 0.1392, 0.1200, 0.1018, 0.650, 0.0430, 0.1000, -0.0212, 0.0543, -0.0929, -0.1111, -0.1519, -0.1600, -0.1876, -0.1923, -0.1950, -0.1850, -0.1775, -0.1600, -0.1448, -0.1000, -0.0914, -0.0100, -0.0271, 0.0120, 0.0300, 0.0550, 0.0732, 0.0900, 0.1017, 0.1234, 0.1425,//41 + 0.1468, 0.3619, 0.5434, 0.8773, 1.1111, 1.3269, 1.4355, 1.5694, 1.6100, 1.6707, 1.7100, 1.7137, 1.7235, 1.7332, 1.7410, 1.7420, 1.7420, 1.7422, 1.7450, 1.7475, 1.7510, 1.7519, 1.7550, 1.7584, 1.7610, 1.7627, 1.7600, 1.7601, 1.7620, 1.7630,//30 + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L63_120_m56Rec2020spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3223, 0.3500, 0.3687, 0.4000, 0.4394, 0.5100, 0.7018, 0.7500, 0.8667, 0.9000, 0.9539, 1.000, 1.0370, 1.040, 1.0410, 0.9800, 0.9653, 0.9200, 0.8675, 0.8100, 0.7631, 0.7100, + 0.6533, 0.5500, 0.5024, 0.4000, 0.3065, 0.2100, 0.1347, 0.1000, 0.0257, 0.0100, -0.0474, -0.0600, -0.1188, -0.1500, -0.1851, -0.2000, -0.2188, -0.2000, -0.1941, -0.0100, + 0.0977, 0.5000, 0.8071, 1.100, 1.4292, 1.5500, 1.7653, 1.8500, 1.9058, 1.9300, 1.9644, 1.9800, 1.9977, 2.010, 2.0234, 2.0300, 2.0337, 2.0250, 2.0381, 2.0360, 2.0358, 2.3010, 2.0302, 2.0280, 2.0265, 2.0227, 2.0292, 2.0290, 2.0547, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L63_m50_m60Rec2020spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0605, 0.1000, 0.1336, 0.2000, 0.2496, 0.4500, 0.5113, 0.6000, 0.6662, 0.7500, 0.7853, 0.9000, 0.9221, 0.9650, 1.0126, 1.0200, 1.0357, 1.0400, 1.0454, 1.0300, 1.0283, 1.0000, + 0.9940, 0.9500, 0.9371, 0.8800, 0.8515, 0.7900, 0.7337, 0.6500, 0.5897, 0.5300, 0.4428, 0.3200, 0.2986, 0.2100, 0.1731, 0.1300, 0.1012, 0.0800, 0.0678, 0.0500, 0.0461, 0.0300, 0.0176, 0.0100, + -0.0042, -0.0100, -0.0143, -0.0150, -0.0183, -0.0190, -0.0194, -0.0150, -0.0127, -0.0100, 0.0014, 0.0050, 0.0108, 0.0090, 0.0076, 0.0001, -0.0007, -0.0050, -0.0150, -0.0200, -0.0240, -0.0200, -0.0182, 0.0010, 0.0042, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L63_m120_80Rec2020spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0708, -0.0700, -0.0651, -0.0600, -0.0562, -0.0600, 0.0685, -0.0700, -0.0813, -0.0750, -0.0762, -0.0700, -0.0617, -0.0400, -0.0305, 0.0100, 0.0120, 0.0300, 0.0568, 0.0800, 0.0933, 0.1000, 0.1433, 0.2000, 0.2482, 0.31000, 0.4019, 0.4500, 0.5081, 0.5200, 0.5339, 0.5300, 0.5266, 0.5200, 0.5121, 0.5000, 0.4971, 0.4900, + 0.4877, 0.4700, 0.4672, 0.4000, 0.3479, 0.2000, 0.0648, -0.0100, -0.1825, -0.0250, -0.3147, -0.3500, -0.3697, -0.3800, -0.3911, -0.4000, -0.4007, -0.4020, -0.4050, + -0.4050, -0.4063, -0.4080, -0.4090, -0.4100, -0.4109, -0.4120, -0.4130, -0.4135, -0.4140, -0.4138, -0.4135, -0.4140, -0.4149, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L42_110_m100Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2174, 0.2500, 0.2847, 0.3300, 0.3905, 0.5500, 0.6912, 0.7500, 0.8768, 0.9100, 0.9938, 1.0500, 1.1155, 1.1300, 1.1613, 1.1300, 1.1194, 1.0800, 1.0576, 1.0100, 0.9793, 0.9200, + 0.8769, 0.7700, 0.7035, 0.6000, 0.4573, 0.3400, 0.2303, 0.1100, 0.0648, 0.0100, -0.0656, -0.1100, -0.1884, -0.2300, -0.2951, -0.3200, -0.3541, -0.3542, -0.3546, -0.2300, + -0.1748, 0.1000, 0.2751, 0.4100, 0.6713, 0.7500, 0.8857, 0.9200, 0.9753, 1.000, 1.0120, 1.0200, 1.0363, 1.0400, 1.0595, 1.0600, 1.0712, 1.0720, 1.0726, 1.0700, 1.0669, 1.0600, 1.0558, 1.0500, 1.0484, 1.0501, 1.0534, 1.0700, 1.0805, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L42_m70_m100Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0736, 0.1000, 0.1529, 0.2200, 0.2791, 0.4200, 0.5702, 0.6600, 0.7447, 0.8200, 0.8749, 0.9500, 1.0210, 1.0600, 1.1109, 1.1200, 1.1222, 1.1200, 1.1187, 1.0900, 1.0887, 1.0500, 1.0294, 0.9500, 0.9114, 0.8600, 0.7320, 0.6600, 0.5414, + 0.4500, 0.3630, 0.2500, 0.1980, 0.1100, 0.0409, 0.0100, -0.0935, -0.01200, -0.1707, -0.1900, -0.2017, -0.2000, -0.1920, -0.1700, -0.1434, -0.1200, -0.0975, -0.0800, -0.0714, + -0.7000, -0.0605, -0.0600, -0.0562, -0.0500, -0.0466, -0.0350, -0.0302, -0.0200, -0.0194, -0.0200, -0.0220, -0.0250, -0.0308, -0.0350, -0.0460, -0.0500, -0.0559, -0.0500, -0.0495, -0.0300, -0.0248, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L56_m120_90Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0592, -0.0560, -0.0555, -0.0550, -0.0497, -0.0600, -0.0630, -0.0700, -0.0753, -0.0740, -0.0727, -0.0700, -0.0627, -0.0500, -0.0387, -0.0040, -0.0049, 0.0100, 0.0311, 0.0500, + 0.0607, 0.0800, 0.1009, 0.1500, 0.1840, 0.2500, 0.3055, 0.3400, 0.3899, 0.4000, 0.4115, 0.40800, 0.4069, 0.4000, 0.3968, 0.3900, 0.3862, 0.3800, 0.3795, 0.3700, 0.3633, 0.3200, 0.2672, 0.1300, 0.0388, + 0.0100, -0.1609, -0.2000, -0.2676, -0.3000, -0.3121, -0.3200, -0.3294, -0.3300, -0.3373, -0.3400, -0.3410, -0.3420, -0.3421, -0.3430, -0.3443, -0.3450, -0.3456, -0.3460, -0.3472, -0.3475, -0.3479, -0.3476, -0.3476, -0.3480, -0.3490, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L25_60_m120Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1084, 0.1500, 0.1725, 0.2200, 0.2744, 0.4000, 0.5281, 0.6000, 0.6825, 0.7500, 0.7901, 0.8500, 0.9069, 0.9300, 0.9679, 0.9600, 0.9574, 0.9400, 0.9326, 0.9100, 0.8890, 0.8500, 0.8185, 0.7500, + 0.6837, 0.5400, 0.4837, 0.3500, 0.2905, 0.2000, 0.1352, 0.1000, 0.0028, -0.050, -0.1213, -0.2000, -0.2273, -0.2500, -0.2875, -0.2950, -0.3033, -0.2600, -0.2338, -0.1000, -0.0476, 0.0500, + 0.1181, 0.1500, 0.2081, 0.2200, 0.2458, 0.2550, 0.2608, 0.2650, 0.2741, 0.2800, 0.2906, 0.2950, 0.3003, 0.3000, 0.2994, 0.2950, 0.2930, 0.2850, 0.2813, 0.2800, 0.2735, 0.2750, 0.2786, 0.2900, 0.3006, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L75_50_120Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1451, 0.1350, 0.1304, 0.1200, 0.1040, 0.1000, 0.0943, 0.0900, 0.0894, 0.8500, 0.0702, 0.0500, 0.0450, 0.0200, 0.0120, 0.0000, -0.0180, -0.0200, -0.0531, -0.0600, -0.0820, -0.0800, -0.0803, -0.0400, -0.0149, 0.0200, 0.1067, 0.1500, + 0.2101, 0.2500, 0.2775, 0.3000, 0.3323, 0.3500, 0.3756, 0.3900, 0.4057, 0.4100, 0.4259, 0.4300, 0.4494, 0.5000, 0.5688, 0.7500, 0.8473, 0.9500, 1.0899, 1.1500, 1.2215, 1.2500, + 1.2766, 1.2900, 1.3014, 1.305, 1.3127, 1.3150, 1.3176, 1.3170, 1.3169, 1.3180, 1.3199, 1.3200, 1.3227, 1.3250, 1.3272, 1.3300, 1.3306, 1.3300, 1.3285, 1.3295, 1.3301, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L75_m120_0Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0548, -0.0200, -0.0126, 0.0100, 0.0544, 0.1100, 0.1678, 0.1900, 0.2289, 0.2500, 0.2929, 0.3300, 0.3761, 0.4100, 0.4556, 0.4800, 0.5149, 0.5400, 0.5703, 0.5900, 0.6035, 0.6300, 0.6419, 0.6800, 0.7270, 0.8000, 0.8497, 0.8700, + 0.9053, 0.8800, 0.8613, 0.8200, 0.7798, 0.7300, 0.6924, 0.6600, 0.6138, 0.5900, 0.5679, 0.5500, 0.5282, 0.4500, 0.3813, 0.2000, 0.0440, 0.0100, -0.2491, -0.3000, -0.4050, -0.4300, -0.4699, -0.4800, -0.4951, -0.5000, + -0.5029, -0.5020, -0.5010, -0.5000, -0.4978, -0.5000, -0.5025, -0.5050, -0.5087, -0.5100, -0.5181, -0.5200, -0.5237, -0.5220, -0.5203, -0.5200, -0.5111, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_2_1_3Prospect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0074, 0.008, 0.0095, 0.01, 0.0127, 0.02, 0.0215, 0.025, 0.0267, 0.03, 0.0302, 0.033, 0.0343, 0.035, 0.0366, 0.036, 0.0367, 0.037, 0.0362, 0.035, 0.0349, 0.035, 0.0344, 0.036, 0.0367, 0.040, 0.0411, 0.042, 0.0428, 0.041, + 0.0409, 0.038, 0.0379, 0.035, 0.0343, 0.032, 0.0309, 0.030, 0.0290, 0.029, 0.0286, 0.03, 0.0312, 0.035, 0.0381, 0.040, 0.0443, 0.045, 0.0477, 0.048, 0.0491, 0.0490, 0.0498, 0.050, + 0.0504, 0.051, 0.0511, 0.0512, 0.0514, 0.0514, 0.0514, 0.0512, 0.0511, 0.0510, 0.0508, 0.0507, 0.0506, 0.0506, 0.0507, 0.0510, 0.0516, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp:: Colorlab_L44_2_8_3_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0277, 0.030, 0.0351, 0.040, 0.0464, 0.060, 0.0782, 0.085, 0.0969, 0.010, 0.1096, 0.11, 0.1240, 0.130, 0.1321, 0.132, 0.1325, 0.131, 0.1305, 0.130, 0.1255, 0.125, + 0.1240, 0.130, 0.1328, 0.140, 0.1497, 0.150, 0.1569, 0.153, 0.1505, 0.140, 0.1399, 0.130, 0.1274, 0.120, 0.1152, 0.110, 0.1086, 0.108, 0.1070, 0.117, 0.1172, 0.130, + 0.1438, 0.150, 0.1672, 0.170, 0.1803, 0.181, 0.1858, 0.186, 0.1885, 0.190, 0.1907, 0.192, 0.1932, 0.194, 0.1942, 0.1942, 0.1941, 0.193, 0.1934, 0.193, 0.1922, 0.192, 0.1915, 0.191, 0.1919, 0.194, 0.1950, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L44_2_8_3_9spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0277, 0.030, 0.0351, 0.040, 0.0564, 0.060, 0.0782, 0.085, 0.0969, 0.010, 0.1096, 0.11, 0.1240, 0.130, 0.1321, 0.132, 0.1325, 0.131, 0.1305, 0.130, 0.1255, 0.125, + 0.1240, 0.130, 0.1328, 0.140, 0.1597, 0.150, 0.1569, 0.153, 0.1505, 0.140, 0.1399, 0.130, 0.1274, 0.120, 0.1152, 0.110, 0.1086, 0.108, 0.1070, 0.117, 0.1172, 0.130, + 0.1438, 0.150, 0.1672, 0.170, 0.1903, 0.181, 0.1858, 0.186, 0.1885, 0.190, 0.1907, 0.192, 0.1932, 0.194, 0.1942, 0.1942, 0.1941, 0.193, 0.1934, 0.193, 0.1922, 0.192, 0.1915, 0.191, 0.1919, 0.194, 0.1950, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L95_2_3_15_6spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1546, 0.18, 0.1934, 0.22, 0.2519, 0.35, 0.4184, 0.45, 0.5150, 0.55, 0.5811, 0.625, 0.6582, 0.689, 0.7035, 0.71, 0.7106, 0.705, 0.7042, 0.70, 0.6812, 0.682, 0.6845, 0.715, + 0.7647, 0.82, 0.9074, 0.95, 0.9847, 0.97, 0.9662, 0.94, 0.9160, 0.888, 0.8522, 0.81, 0.7878, 0.77, 0.7534, 0.75, 0.7438, 0.76, 0.900, 0.905, 0.9109, 0.95, 1.0180, 1.03, + 1.0784, 1.1, 1.1039, 1.11, 1.1176, 1.12, 1.1290, 1.13, 1.1417, 1.145, 1.1469, 1.146, 1.1463, 1.143, 1.1425, 1.30, 1.1360, 1.20, 1.1327, 1.133, 1.1348, 1.14, 1.1514, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L95_2_3_15_6spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1546, 0.18, 0.1934, 0.22, 0.2519, 0.35, 0.4284, 0.45, 0.5150, 0.55, 0.5811, 0.625, 0.6582, 0.689, 0.7035, 0.71, 0.7106, 0.705, 0.7042, 0.70, 0.6812, 0.682, 0.6845, 0.715, + 0.7647, 0.82, 0.9074, 0.95, 0.9847, 0.97, 0.9362, 0.91, 0.9160, 0.888, 0.8522, 0.81, 0.7878, 0.77, 0.7534, 0.75, 0.7438, 0.76, 0.900, 0.905, 0.9109, 0.95, 1.0180, 1.03, + 1.0784, 1.1, 1.1039, 1.11, 1.1176, 1.12, 1.1090, 1.13, 1.1417, 1.145, 1.1469, 1.146, 1.1463, 1.143, 1.1425, 1.30, 1.1360, 1.20, 1.1327, 1.133, 1.1348, 1.14, 1.1514, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_3_5_10_7spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0207, 0.022, 0.0249, 0.03, 0.0312, 0.04, 0.0503, 0.055, 0.0614, 0.065, 0.0687, 0.077, 0.0772, 0.08, 0.0819, 0.082, 0.0823, 0.085, 0.0810, 0.08, 0.0778, 0.078, 0.0784, 0.08, + 0.0893, 0.1, 0.1088, 0.11, 0.1202, 0.12, 0.1195, 0.115, 0.1147, 0.11, 0.1082, 0.105, 0.1012, 0.1, 0.0976, 0.97, 0.0969, 0.1, 0.1043, 0.11, 0.1231, 0.13, 0.1397, 0.145, + 0.1490, 0.15, 0.1529, 0.153, 0.1549, 0.155, 0.1564, 0.157, 0.1580, 0.1585, 0.1586, 0.1585, 0.1585, 0.1584, 0.1582, 0.158, 0.1575, 0.1573, 0.1572, 0.1573, 0.1574, 0.158, 0.1593, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_3_5_10_7spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0207, 0.022, 0.0249, 0.03, 0.0312, 0.04, 0.0603, 0.055, 0.0614, 0.065, 0.0687, 0.077, 0.0772, 0.08, 0.0819, 0.082, 0.0823, 0.085, 0.0810, 0.08, 0.0778, 0.078, 0.0784, 0.08, + 0.0893, 0.1, 0.1088, 0.11, 0.1202, 0.12, 0.1295, 0.115, 0.1147, 0.11, 0.1082, 0.105, 0.1012, 0.1, 0.0976, 0.97, 0.0969, 0.1, 0.1043, 0.11, 0.1231, 0.13, 0.1397, 0.145, + 0.1490, 0.15, 0.1529, 0.153, 0.1549, 0.155, 0.1664, 0.157, 0.1580, 0.1585, 0.1586, 0.1585, 0.1585, 0.1584, 0.1582, 0.158, 0.1575, 0.1573, 0.1572, 0.1573, 0.1574, 0.158, 0.1593, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_3_5_10_7spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0207, 0.022, 0.0249, 0.03, 0.0212, 0.04, 0.0503, 0.055, 0.0614, 0.065, 0.0687, 0.077, 0.0772, 0.08, 0.0819, 0.082, 0.0823, 0.085, 0.0810, 0.08, 0.0778, 0.078, 0.0784, 0.08, + 0.0893, 0.1, 0.1088, 0.11, 0.1102, 0.12, 0.1195, 0.115, 0.1147, 0.11, 0.1082, 0.105, 0.1012, 0.1, 0.0976, 0.97, 0.0969, 0.1, 0.1043, 0.11, 0.1231, 0.13, 0.1397, 0.145, + 0.1490, 0.15, 0.1529, 0.153, 0.1449, 0.155, 0.1564, 0.157, 0.1580, 0.1585, 0.1486, 0.1585, 0.1585, 0.1584, 0.1582, 0.158, 0.1575, 0.1573, 0.1572, 0.1573, 0.1574, 0.158, 0.1593, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L34_1_8_1_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0154, 0.018, 0.0199, 0.021, 0.0267, 0.03, 0.0454, 0.05, 0.0564, 0.06, 0.0639, 0.07, 0.0726, 0.075, 0.0776, 0.078, 0.0781, 0.078, 0.0771, 0.075, 0.0744, 0.074, 0.0737, 0.075, + 0.0788, 0.08, 0.0886, 0.09, 0.0926, 0.09, 0.0886, 0.085, 0.0821, 0.08, 0.0745, 0.07, 0.0672, 0.065, 0.0632, 0.063, 0.0621, 0.066, 0.0672, 0.08, 0.0807, 0.09, 0.0927, 0.095, + 0.0995, 0.1, 0.1023, 0.102, 0.1037, 0.104, 0.1049, 0.105, 0.1063, 0.1065, 0.1069, 0.1069, 0.1069, 0.1065, 0.1064, 0.106, 0.1057, 0.1055, 0.1053, 0.1054, 0.1055, 0.107, 0.1073, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L34_1_8_1_9spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0154, 0.018, 0.0199, 0.021, 0.0297, 0.03, 0.0454, 0.05, 0.0564, 0.06, 0.0639, 0.07, 0.0726, 0.075, 0.0776, 0.078, 0.0781, 0.078, 0.0771, 0.075, 0.0744, 0.074, 0.0737, 0.075, + 0.0788, 0.08, 0.0886, 0.09, 0.0826, 0.09, 0.0886, 0.085, 0.0821, 0.08, 0.0745, 0.07, 0.0672, 0.065, 0.0632, 0.063, 0.0621, 0.066, 0.0672, 0.08, 0.0807, 0.09, 0.0927, 0.095, + 0.0995, 0.1, 0.1023, 0.102, 0.1137, 0.104, 0.1049, 0.105, 0.1063, 0.1065, 0.1069, 0.1069, 0.1069, 0.1065, 0.1064, 0.106, 0.1057, 0.1055, 0.1053, 0.1054, 0.1055, 0.107, 0.1073, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L64_1_8_m1_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0652, 0.08, 0.0864, 0.1, 0.1189, 0.15, 0.2063, 0.22, 0.2577, 0.28, 0.2935, 0.31, 0.3344, 0.34, 0.3582, 0.36, 0.3608, 0.36, 0.3569, 0.35, 0.3449, 0.34, 0.3395, 0.34, + 0.3558, 0.37, 0.3884, 0.39, 0.3971, 0.38, 0.3738, 0.35, 0.3408, 0.32, 0.3038, 0.28, 0.2686, 0.25, 0.2493, 0.245, 0.2435, 0.26, 0.2645, 0.3, 0.3207, 0.33, 0.3706, 0.38, + 0.398, 0.4, 0.4103, 0.415, 0.4163, 0.42, 0.4216, 0.425, 0.4278, 0.43, 0.4307, 0.4305, 0.4304, 0.43, 0.4282, 0.425, 0.4246, 0.424, 0.4225, 0.425, 0.4238, 0.43, 0.4321, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L84_0_8_m1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1232, 0.15, 0.1635, 0.2, 0.2255, 0.3, 0.3913, 0.4, 0.4886, 0.5, 0.5567, 0.6, 0.6349, 0.65, 0.6810, 0.682, 0.6871, 0.685, 0.6811, 0.67, 0.6591, 0.655, 0.6507, 0.67, 0.6864, 0.70, 0.7553, 0.76, 0.7770, 0.75, + 0.7343, 0.7, 0.6719, 0.65, 0.6014, 0.55, 0.5340, 0.5, 0.4973, 0.49, 0.4858, 0.5, 0.5227, 0.55, 0.6222, 0.65, 0.7108, 0.75, 0.7606, 0.77, 0.7817, 0.79, 0.7925, 0.8, + 0.8023, 0.81, 0.8141, 0.815, 0.8196, 0.818, 0.8188, 0.817, 0.8147, 0.81, 0.8077, 0.805, 0.8037, 0.804, 0.8063, 0.81, 0.8221, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L63_1_3_m2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0646, 0.07, 0.0858, 0.1, 0.1184, 0.15, 0.2058, 0.22, 0.2571, 0.27, 0.2929, 0.31, 0.3340, 0.34, 0.3580, 0.36, 0.3608, 0.355, 0.3572, 0.35, 0.3454, 0.345, 0.3402, 0.35, + 0.3568, 0.37, 0.3896, 0.39, 0.3985, 0.38, 0.3752, 0.36, 0.3420, 0.32, 0.3049, 0.29, 0.2695, 0.255, 0.2501, 0.245, 0.2442, 0.25, 0.2644, 0.3, 0.3188, 0.35, 0.3671, 0.38, + 0.3942, 0.4, 0.4056, 0.41, 0.4115, 0.415, 0.4167, 0.42, 0.4229, 0.425, 0.4258, 0.4255, 0.4254, 0.424, 0.4232, 0.42, 0.4196, 0.417, 0.4174, 0.418, 0.4188, 0.42, 0.4271, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L44_2_3_m3spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0287, 0.03, 0.0380, 0.04, 0.0523, 0.08, 0.0910, 0.1, 0.1137, 0.12, 0.1295, 0.13, 0.1475, 0.15, 0.1578, 0.158, 0.1586, 0.157, 0.1566, 0.155, 0.1510, 0.15, 0.1481, 0.15, + 0.1538, 0.16, 0.1657, 0.167, 0.1678, 0.16, 0.1569, 0.15, 0.1421, 0.13, 0.1258, 0.12, 0.1103, 0.11, 0.1018, 0.1, 0.0994, 0.1, 0.1093, 0.12, 0.1356, 0.14, 0.1590, 0.16, + 0.1720, 0.173, 0.1775, 0.18, 0.1802, 0.181, 0.1826, 0.184, 0.1854, 0.186, 0.1867, 0.1865, 0.1865, 0.186, 0.1856, 0.185, 0.1840, 0.184, 0.1830, 0.1835, 0.1836, 0.186, 0.1873, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L65_96_45spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2103, 0.2, 0.1996, 0.19, 0.1795, 0.19, 0.2091, 0.22, 0.2312, 0.23, 0.2217, 0.22, 0.2014, 0.18, 0.1560, 0.1, 0.0981, 0.05, 0.0316, 0.0, -0.0261, -0.05, -0.0622, -0.07, + -0.0700, -0.06, -0.0540, -0.04, -0.0294, -0.01, 0.0079, 0.03, 0.0536, 0.08, 0.0922, 0.1, 0.1193, 0.12, 0.1385, 0.16, 0.1735, 0.25, 0.3791, 0.5, 0.8646, 1.0, 1.2884, 1.35, + 1.5172, 1.6, 1.6128, 1.63, 1.6537, 1.66, 1.6730, 1.68, 1.682, 1.684, 1.6842, 1.685, 1.6888, 1.69, 1.6921, 1.695, 1.6967, 1.698, 1.6998, 1.699, 1.6979, 1.70, 1.7033, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L52_47_57spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0746, 0.7, 0.0693, 0.06, 0.0597, 0.06, 0.0637, 0.065, 0.0670, 0.063, 0.0611, 0.055, 0.0521, 0.04, 0.0367, 0.03, 0.0198, 0.0, -0.0001, -0.01, -0.0171, -0.02, -0.0218, -0.022, + -0.0029, 0.0, 0.0366, 0.05, 0.0710, 0.08, 0.0956, 0.1, 0.1172, 0.12, 0.1343, 0.14, 0.1459, 0.15, 0.1539, 0.16, 0.1656, 0.20, 0.2305, 0.3, 0.3828, 0.45, 0.5156, 0.55, + 0.5875, 0.6, 0.6176, 0.62, 0.6309, 0.632, 0.6371, 0.64, 0.6401, 0.6401, 0.6402, 0.6415, 0.6417, 0.642, 0.6430, 0.644, 0.6448, 0.645, 0.6462, 0.646, 0.6454, 0.646, 0.6469, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L31_62_27spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0456, 0.045, 0.0430, 0.04, 0.0383, 0.04, 0.0441, 0.045, 0.0486, 0.047, 0.0462, 0.045, 0.0413, 0.04, 0.0310, 0.02, 0.0180, 0.01, 0.0031, 0.0, -0.0096, -0.01, -0.0179, -0.02, + -0.0211, -0.02, -0.0198, -0.019, -0.0159, -0.01, -0.0081, 0.0, 0.0021, 0.02, 0.0109, 0.0105, 0.0172, 0.02, 0.0216, 0.025, 0.0294, 0.05, 0.0749, 0.1, 0.1824, 0.2, 0.2761, 0.3, + 0.3267, 0.33, 0.3479, 0.35, 0.3569, 0.36, 0.3611, 0.362, 0.3632, 0.363, 0.3635, 0.364, 0.3645, 0.365, 0.3653, 0.366, 0.3663, 0.367, 0.3670, 0.367, 0.3666, 0.367, 0.3677, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L79_m9_m28spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1188, 0.15, 0.1814, 0.2, 0.2793, 0.4, 0.5204, 0.6, 0.6631, 0.7, 0.7669, 0.8, 0.8855, 0.9, 0.9584, 0.96, 0.9703, 0.97, 0.9673, 0.96, 0.9410, 0.94, 0.9144, 0.91, 0.9020, 0.9, + 0.8941, 0.86, 0.8425, 0.8, 0.7410, 0.7, 0.6276, 0.6, 0.5106, 0.45, 0.4049, 0.35, 0.3456, 0.33, 0.3233, 0.33, 0.3475, 0.4, 0.4243, 0.45, 0.4941, 0.5, 0.5339, 0.54, 0.5507, 0.555, + 0.5593, 0.56, 0.5700, 0.575, 0.5852, 0.59, 0.5936, 0.592, 0.5918, 0.59, 0.5850, 0.58, 0.5735, 0.57, 0.5665, 0.57, 0.5710, 0.58, 0.5928, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L58_50_31spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1011, 0.11, 0.1006, 0.1, 0.0980, 0.11, 0.1257, 0.13, 0.1434, 0.145, 0.1459, 0.145, 0.1455, 0.14, 0.1325, 0.12, 0.1113, 0.1, 0.0852, 0.07, 0.0607, 0.05, 0.0494, 0.06, + 0.0625, 0.08, 0.0961, 0.1, 0.1233, 0.13, 0.1401, 0.15, 0.1549, 0.16, 0.1647, 0.165, 0.1692, 0.17, 0.1736, 0.18, 0.1864, 0.22, 0.2711, 0.35, 0.4721, 0.55, 0.6477, 0.7, 0.7428, 0.76, 0.7826, 0.79, + 0.8000, 0.804, 0.8088, 0.81, 0.8140, 0.815, 0.8150, 0.816, 0.8167, 0.817, 0.8176, 0.818, 0.8188, 0.819, 0.8198, 0.8195, 0.8192, 0.82, 0.8231, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L31_m52_27spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0093, -0.008, -0.0073, -0.005, -0.0042, -0.003, -0.0021, -0.002, -0.0018, 0.0, 0.0008, 0.004, 0.0053, 0.01, 0.0117, 0.015, 0.0191, 0.02, 0.0265, 0.03, 0.0321, 0.035, 0.0402, 0.05, 0.0582, 0.07, 0.0849, 0.1, + 0.1027, 0.103, 0.1056, 0.104, 0.1027, 0.1, 0.0984, 0.095, 0.0941, 0.093, 0.0915, 0.09, 0.0877, 0.08, 0.0684, 0.05, 0.0228, 0.0, -0.0170, -0.02, -0.0383, -0.04, -0.0471, -0.05, + -0.0505, -0.051, -0.0519, -0.052, -0.0523, -0.0523, -0.0524, -0.0528, -0.0529, -0.053, -0.0533, -0.0538, -0.0538, -0.54, -0.0541, -0.054, -0.0540, -0.054, -0.0538, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L44_2_2_m7_35spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0303, 0.04, 0.0412, 0.05, 0.0579, 0.08, 0.1021, 0.11, 0.1283, 0.135, 0.1465, 0.16, 0.1672, 0.17, 0.1790, 0.179, 0.1798, 0.178, 0.1775, 0.173, 0.1712, 0.17, 0.1668, 0.168, 0.1695, 0.18, 0.1769, 0.175, 0.1746, 0.17, 0.1600, 0.15, + 0.1422, 0.13, 0.1229, 0.11, 0.1049, 0.1, 0.0950, 0.093, 0.0921, 0.1, 0.1027, 0.12, 0.1314, 0.14, 0.1569, 0.16, 0.1711, 0.175, 0.1771, 0.18, 0.1800, 0.181, 0.1826, 0.184, 0.1857, 0.187, 0.1872, 0.1871, + 0.1871, 0.186, 0.1860, 0.185, 0.1841, 0.184, 0.1830, 0.183, 0.1837, 0.186, 0.1878, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L47_m10_8_0_41spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0213, 0.03, 0.0316, 0.04, 0.0475, 0.06, 0.0864, 0.09, 0.1088, 0.11, 0.1258, 0.13, 0.1458, 0.15, 0.1595, 0.16, 0.1641, 0.165, 0.1662, 0.164, 0.1639, 0.164, 0.1647, 0.17, 0.1775, 0.18, 0.1995, 0.2, 0.2080, 0.2, 0.1975, 0.19, 0.1809, 0.17, + 0.1621, 0.15, 0.1445, 0.14, 0.1347, 0.131, 0.1302, 0.13, 0.1289, 0.129, 0.1288, 0.129, 0.1291, 0.1295, 0.1298, 0.13, 0.1301, 0.1305, 0.1308, 0.131, 0.1323, 0.133, 0.1347, 0.135, + 0.1360, 0.136, 0.1355, 0.135, 0.1344, 0.133, 0.1325, 0.132, 0.1314, 0.132, 0.1321, 0.134, 0.1357, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L32_4_8_m3_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0163, 0.02, 0.0211, 0.025, 0.0285, 0.03, 0.0490, 0.05, 0.0611, 0.065, 0.0694, 0.07, 0.0786, 0.08, 0.0837, 0.083, 0.0835, 0.082, 0.0819, 0.08, 0.0785, 0.077, 0.0764, 0.077, 0.0784, 0.08, 0.0833, 0.083, 0.0835, 0.08, 0.0776, 0.075, + 0.0701, 0.065, 0.0617, 0.06, 0.0538, 0.05, 0.0494, 0.045, 0.0484, 0.05, 0.0552, 0.06, 0.0729, 0.08, 0.0885, 0.09, 0.0972, 0.1, 0.1008, 0.102, 0.1026, 0.0103, 0.1039, 0.0104, + 0.1055, 0.0106, 0.1062, 0.0161, 0.1061, 0.0106, 0.1056, 0.0105, 0.1048, 0.0104, 0.1044, 0.01045, 0.1047, 0.0105, 0.1066, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L57_m6_9_2_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0379, 0.04, 0.0525, 0.06, 0.0750, 0.1, 0.1325, 0.14, 0.1658, 0.18, 0.1901, 0.2, 0.2187, 0.22, 0.2373, 0.24, 0.2425, 0.243, 0.2437, 0.24, 0.2387, 0.236, 0.2394, 0.24, 0.2594, 0.28, 0.2945, 0.3, 0.3096, 0.3, + 0.2963, 0.28, 0.2737, 0.26, 0.2478, 0.23, 0.2230, 0.21, 0.2093, 0.205, 0.2038, 0.206, 0.2078, 0.21, 0.2218, 0.225, 0.2346, 0.24, 0.2423, 0.244, 0.2456, 0.246, 0.2478, 0.25, + 0.2505, 0.252, 0.2543, 0.255, 0.2562, 0.257, 0.2557, 0.255, 0.2541, 0.253, 0.2515, 0.252, 0.2500, 0.25, 0.2509, 0.252, 0.2564, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L33_2_4_m4_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0167, 0.02, 0.0223, 0.03, 0.0310, 0.04, 0.054, 0.06, 0.0679, 0.07, 0.0774, 0.08, 0.0881, 0.09, 0.0943, 0.095, 0.0946, 0.094, 0.0933, 0.09, 0.0899, 0.088, 0.0877, 0.088, + 0.0898, 0.09, 0.0949, 0.095, 0.0947, 0.09, 0.0875, 0.08, 0.0785, 0.07, 0.0685, 0.06, 0.0592, 0.055, 0.0541, 0.053, 0.0527, 0.055, 0.0587, 0.06, 0.0748, 0.08, 0.0891, 0.09, + 0.0971, 0.1, 0.1005, 0.102, 0.1021, 0.103, 0.1035, 0.104, 0.1052, 0.1055, 0.1060, 0.106, 0.1059, 0.106, 0.1053, 0.105, 0.1043, 0.104, 0.1038, 0.104, 0.1041, 0.105, 0.1063, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L35_11_65_m1_1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0226, 0.025, 0.0276, 0.03, 0.0351, 0.04, 0.0579, 0.06, 0.0715, 0.075, 0.0802, 0.085, 0.0897, 0.09, 0.0940, 0.093, 0.0925, 0.09, 0.0891, 0.085, 0.0841, 0.082, 0.0810, 0.082, + 0.0830, 0.085, 0.0888, 0.089, 0.0897, 0.085, 0.0842, 0.08, 0.0772, 0.07, 0.0691, 0.065, 0.0612, 0.055, 0.0570, 0.057, 0.0568, 0.06, 0.0691, 0.08, 0.0998, 0.1, 0.1269, 0.13, + 0.1417, 0.145, 0.1479, 0.15, 0.1508, 0.151, 0.1527, 0.153, 0.1546, 0.155, 0.1554, 0.1554, 0.1555, 0.155, 0.1550, 0.155, 0.1543, 0.153, 0.1538, 0.154, 0.1541, 0.155, 0.1564, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L52_m2_7_8_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0316, 0.04, 0.0411, 0.05, 0.0556, 0.08, 0.0946, 0.1, 0.1172, 0.12, 0.1332, 0.14, 0.1521, 0.16, 0.1640, 0.165, 0.1670, 0.167, 0.1670, 0.165, 0.1628, 0.164, 0.1643, 0.17, 0.1829, 0.2, 0.2154, 0.22, 0.2324, 0.23, + 0.2267, 0.22, 0.2135, 0.2, 0.1973, 0.19, 0.1812, 0.18, 0.1725, 0.17, 0.1694, 0.17, 0.1756, 0.18, 0.1930, 0.2, 0.2085, 0.21, 0.2175, 0.22, 0.2213, 0.222, 0.2236, 0.224, 0.2259, 0.227, + 0.2287, 0.229, 0.2299, 0.2298, 0.2296, 0.229, 0.2286, 0.227, 0.2270, 0.227, 0.2261, 0.2265, 0.2267, 0.23, 0.2305, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L32_7_m2_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0170, 0.02, 0.0216, 0.025, 0.0285, 0.04, 0.0483, 0.05, 0.0600, 0.065, 0.0678, 0.07, 0.0765, 0.08, 0.0809, 0.0802, 0.0804, 0.079, 0.0783, 0.075, 0.0747, 0.074, 0.0724, 0.073, 0.0742, 0.077, 0.0789, 0.079, 0.0792, 0.075, + 0.0738, 0.07, 0.0670, 0.06, 0.0593, 0.055, 0.0519, 0.05, 0.0479, 0.0476, 0.0472, 0.05, 0.0552, 0.06, 0.0756, 0.09, 0.0937, 0.1, 0.1036, 0.104, 0.1078, 0.108, 0.1097, 0.11, + 0.1112, 0.112, 0.1127, 0.113, 0.1134, 0.1134, 0.1134, 0.113, 0.1130, 0.113, 0.1122, 0.112, 0.1118, 0.112, 0.1121, 0.113, 0.1140, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L32_3_4_m3_8spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0156, 0.02, 0.0205, 0.025, 0.0281, 0.03, 0.0488, 0.06, 0.0611, 0.065, 0.0694, 0.07, 0.0789, 0.08, 0.0842, 0.0843, 0.0843, 0.084, 0.0830, 0.08, 0.0798, 0.078, 0.0777, 0.078, 0.0797, 0.08, + 0.0844, 0.0844, 0.0843, 0.08, 0.0781, 0.075, 0.0702, 0.065, 0.0615, 0.06, 0.0534, 0.05, 0.0489, 0.048, 0.0477, 0.05, 0.0538, 0.06, 0.0697, 0.07, 0.0838, 0.09, 0.0916, 0.093, + 0.0949, 0.095, 0.0965, 0.097, 0.0978, 0.098, 0.0993, 0.1, 0.1000, 0.1, 0.0999, 0.0996, 0.0994, 0.099, 0.0986, 0.0985, 0.0981, 0.0985, 0.0984, 0.1, 0.1004, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L50_m5_3_6_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0275, 0.03, 0.0370, 0.04, 0.0515, 0.06, 0.0893, 0.1, 0.1111, 0.12, 0.1269, 0.13, 0.1456, 0.15, 0.1578, 0.16, 0.1614, 0.162, 0.1622, 0.16, 0.1589, 0.16, 0.1604, 0.17, 0.1776, 0.19, 0.2074, 0.21, + 0.2223, 0.22, 0.2158, 0.21, 0.2020, 0.19, 0.1855, 0.18, 0.1695, 0.165, 0.1607, 0.16, 0.1572, 0.16, 0.1605, 0.17, 0.1711, 0.18, 0.1807, 0.185, 0.1864, 0.188, 0.1889, 0.19, + 0.1906, 0.191, 0.1925, 0.194, 0.1951, 0.196, 0.1963, 0.196, 0.1960, 0.195, 0.1949, 0.194, 0.1933, 0.193, 0.1923, 0.1925, 0.1929, 0.195, 0.1966, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L44_3_96_m8_8spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0320, 0.04, 0.0431, 0.05, 0.0604, 0.09, 0.1063, 0.12, 0.1336, 0.14, 0.1524, 0.16, 0.1737, 0.18, 0.1856, 0.186, 0.1860, 0.185, 0.1831, 0.18, 0.1761, 0.175, 0.1709, 0.172, 0.1721, 0.175, 0.1773, 0.175, + 0.1732, 0.16, 0.1576, 0.15, 0.1391, 0.13, 0.1192, 0.11, 0.1007, 0.1, 0.0905, 0.09, 0.0877, 0.1, 0.1001, 0.12, 0.1329, 0.15, 0.1620, 0.17, 0.1782, 0.1850, 0.188, 0.1882, 0.19, + 0.1910, 0.193, 0.1942, 0.195, 0.1958, 0.1956, 0.195, 0.195, 0.1945, 0.193, 0.1926, 0.192, 0.1915, 0.192, 0.1922, 0.195, 0.1965, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L34_3_6_m5_4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0184, 0.02, 0.0245, 0.03, 0.0339, 0.04, 0.0591, 0.06, 0.0741, 0.08, 0.0844, 0.09, 0.0960, 0.1, 0.1025, 0.105, 0.1026, 0.101, 0.1009, 0.1, 0.0970, 0.095, 0.0944, 0.095, + 0.0959, 0.1, 0.1004, 0.1, 0.0993, 0.095, 0.0913, 0.09, 0.0815, 0.08, 0.0707, 0.065, 0.0607, 0.06, 0.0552, 0.055, 0.0537, 0.06, 0.0609, 0.07, 0.0799, 0.08, 0.0968, 0.1, 0.1061, 0.11, 0.1101, 0.111, 0.1119, 0.112, 0.1135, 0.114, + 0.1153, 0.116, 0.1162, 0.1161, 0.1161, 0.116, 0.1155, 0.115, 0.1145, 0.114, 0.1139, 0.114, 0.1143, 0.115, 0.1166, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L31_5_9_m4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0166, 0.02, 0.0214, 0.025, 0.0288, 0.04, 0.0495, 0.05, 0.0618, 0.065, 0.0700, 0.07, 0.0793, 0.08, 0.0842, 0.084, 0.0839, 0.083, 0.0820, 0.08, 0.0784, 0.077, 0.0761, 0.077, 0.0774, 0.08, 0.0813, 0.081, + 0.0808, 0.08, 0.0747, 0.07, 0.0671, 0.06, 0.0587, 0.055, 0.0508, 0.05, 0.0465, 0.046, 0.0456, 0.05, 0.0530, 0.06, 0.0720, 0.08, 0.0888, 0.09, 0.0981, 0.1, 0.1020, 0.102, + 0.1039, 0.104, 0.1053, 0.106, 0.1068, 0.107, 0.1076, 0.1075, 0.1075, 0.1074, 0.1071, 0.107, 0.1062, 0.106, 0.1058, 0.106, 0.1061, 0.107, 0.1080, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L35_3_4_m11spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0211, 0.025, 0.0291, 0.03, 0.0414, 0.05, 0.0739, 0.08, 0.0932, 0.1, 0.1066, 0.12, 0.1217, 0.13, 0.1302, 0.1302, 0.1303, 0.129, 0.1283, 0.125, 0.1235, 0.12, 0.1193, 0.118, 0.1180, 0.118, 0.1183, 0.115, 0.1129, 0.105, 0.1007, 0.9, + 0.0871, 0.08, 0.0727, 0.065, 0.0595, 0.053, 0.0521, 0.503, 0.0501, 0.055, 0.0583, 0.07, 0.0804, 0.09, 0.1000, 0.11, 0.1109, 0.115, 0.1154, 0.116, 0.1176, 0.118, 0.1195, 0.12, + 0.1217, 0.122, 0.1229, 0.122, 0.1227, 0.122, 0.1219, 0.121, 0.1205, 0.12, 0.1197, 0.12, 0.1202, 0.121, 0.1233, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L31_4_5_m4_7spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0163, 0.02, 0.0214, 0.025, 0.0292, 0.04, 0.0507, 0.06, 0.0634, 0.07, 0.0720, 0.08, 0.0818, 0.082, 0.0871, 0.087, 0.0870, 0.086, 0.0854, 0.084, 0.0820, 0.08, 0.0796, 0.08, + 0.0810, 0.082, 0.0849, 0.084, 0.0842, 0.08, 0.0776, 0.07, 0.0694, 0.065, 0.0605, 0.055, 0.0520, 0.05, 0.047, 0.046, 0.0463, 0.05, 0.0531, 0.06, 0.0706, 0.08, + 0.0862, 0.09, 0.0948, 0.0948, 0.0984, 0.1, 0.1001, 0.101, 0.1015, 0.102, 0.1031, 0.1032, 0.1038, 0.1038, 0.1038, 0.1035, 0.1033, 0.103, 0.1024, 0.102, 0.1019, 0.102, 0.1022, 0.103, 0.1043, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L35_4_8_m6_4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0202, 0.025, 0.0268, 0.03, 0.0369, 0.05, 0.0643, 0.07, 0.0805, 0.09, 0.0917, 0.095, 0.1042, 0.11, 0.1110, 0.1105, 0.1109, 0.11, 0.1089, 0.105, 0.1045, 0.102, + 0.1013, 0.102, 0.1023, 0.105, 0.1060, 0.105, 0.1040, 0.1, 0.0951, 0.09, 0.0845, 0.08, 0.0729, 0.07, 0.0621, 0.06, 0.0562, 0.055, 0.0547, 0.06, 0.0631, 0.07, + 0.0851, 0.09, 0.1045, 0.11, 0.1153, 0.116, 0.1198, 0.12, 0.1220, 0.123, 0.1237, 0.124, 0.1257, 0.126, 0.1267, 0.1266, 0.1266, 0.126, 0.1259, 0.125, 0.1248, 0.1245, 0.1242, 0.1242, 0.1246, 0.126, 0.1272, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L95_10_7_m14_3spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2133, 0.25, 0.2824, 0.32, 0.3890, 0.5, 0.6783, 0.8, 0.8501, 0.9, 0.9674, 1.05, 1.0994, 1.11, 1.1716, 1.1705, 1.1704, 1.15, 1.1487, 1.12, 1.1019, 1.09, 1.0679, 1.07, 1.0770, 1.1, 1.1145, 1.1, 1.0929, 1.0, 0.9987, 0.9, + 0.8859, 0.8, 0.7633, 0.7, 0.6498, 0.6, 0.5873, 0.57, 0.5718, 0.6, 0.6609, 0.7, 0.8939, 1.0, 1.1003, 1.1, 1.2145, 1.25, 1.2625, 1.27, 1.2851, 1.3, 1.3037, 1.31, 1.3246, 1.33, + 1.3346, 1.334, 1.3339, 1.33, 1.3270, 1.32, 1.3152, 1.31, 1.3082, 1.31, 1.3127, 1.33, 1.340, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_34_m7_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0401, 0.045, 0.0459, 0.05, 0.0545, 0.07, 0.0861, 0.1, 0.1055, 0.11, 0.1162, 0.12, 0.1270, 0.128, 0.1290, 0.125, 0.1221, 0.12, 0.1125, 0.11, 0.1015, 0.1, 0.0924, 0.09, 0.0859, 0.085, 0.0806, 0.08, 0.0731, 0.07, 0.0646, 0.06, + 0.0570, 0.05, 0.0484, 0.04, 0.0399, 0.036, 0.0356, 0.037, 0.0378, 0.05, 0.0685, 0.1, 0.1433, 0.15, 0.2088, 0.22, 0.2444, 0.25, 0.2593, 0.26, 0.2658, 0.266, 0.2695, 0.27, + 0.2726, 0.273, 0.2738, 0.274, 0.2742, 0.274, 0.2738, 0.2733, 0.2731, 0.273, 0.2727, 0.273, 0.2730, 0.275, 0.2762, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L37_59_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0604, 0.061, 0.0622, 0.063, 0.0644, 0.07, 0.0898, 0.1, 0.1061, 0.11, 0.1114, 0.113, 0.1147, 0.11, 0.1079, 0.1, 0.0930, 0.08, 0.0749, 0.06, 0.0576, 0.05, 0.0442, 0.04, 0.0342, 0.03, 0.0265, 0.021, 0.0208, 0.02, 0.0197, 0.02, + 0.0219, 0.022, 0.0228, 0.022, 0.0220, 0.0225, 0.0225, 0.025, 0.0300, 0.05, 0.0857, 0.2, 0.2187, 0.3, 0.3350, 0.35, 0.3978, 0.4, 0.4241, 0.43, 0.4353, 0.44, 0.4410, 0.445, + 0.4447, 0.445, 0.4457, 0.446, 0.4467, 0.447, 0.4471, 0.4472, 0.4474, 0.4475, 0.4476, 0.4475, 0.4475, 0.45, 0.4504, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L69_14_m9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1024, 0.12, 0.1316, 0.15, 0.1764, 0.2, 0.3024, 0.35, 0.3775, 0.4, 0.4274, 0.45, 0.4832, 0.5, 0.5118, 0.51, 0.5082, 0.5, 0.4953, 0.48, 0.4721, 0.46, 0.4554, 0.455, 0.4581, 0.46, 0.4737, 0.47, 0.4648, 0.44, 0.4258, 0.4, + 0.3795, 0.35, 0.3290, 0.3, 0.2813, 0.27, 0.2554, 0.253, 0.2506, 0.28, 0.2997, 0.33, 0.4254, 0.4, 0.5364, 0.55, 0.5976, 0.6, 0.6232, 0.63, 0.6351, 0.64, 0.6441, 0.65, + 0.6536, 0.655, 0.6580, 0.658, 0.6579, 0.656, 0.6551, 0.652, 0.6503, 0.65, 0.6474, 0.648, 0.6493, 0.67, 0.6613, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L92_13_m16spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2033, 0.23, 0.2685, 0.32, 0.3690, 0.5, 0.6430, 0.7, 0.8059, 0.85, 0.9166, 1.0, 1.0407, 1.1, 1.1075, 1.105, 1.1043, 1.09, 1.0816, 1.05, 1.0357, 1.02, 1.0006, 1.0, 1.0019, 1.02, 1.0261, 1.0, 0.9978, 0.95, 0.9063, 0.8, 0.7994, 0.75, 0.6845, 0.6, + 0.5772, 0.55, 0.5185, 0.52, 0.5047, 0.57, 0.5942, 0.7, 0.8269, 0.9, 1.0329, 1.1, 1.1466, 1.15, 1.1944, 1.2, 1.2167, 1.22, 1.2346, 1.24, 1.2546, 1.26, 1.2641, 1.264, + 1.2635, 1.26, 1.2571, 1.25, 1.2460, 1.24, 1.2394, 1.24, 1.2437, 1.25, 1.2695, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L49_21_m12spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0571, 0.06, 0.0711, 0.08, 0.0928, 0.11, 0.1566, 0.17, 0.1950, 0.2, 0.2195, 0.23, 0.2461, 0.25, 0.2579, 0.255, 0.2527, 0.25, 0.2427, 0.23, 0.2282, 0.22, 0.2160, 0.21, 0.2094, 0.206, 0.2057, 0.2, 0.1934, 0.18, 0.1722, 0.16, 0.1498, 0.13, 0.1258, 0.11, + 0.1033, 0.1, 0.0911, 0.0905, 0.0904, 0.1, 0.1245, 0.18, 0.2101, 0.25, 0.2855, 0.3, 0.3266, 0.33, 0.3439, 0.35, 0.3516, 0.355, 0.3568, 0.36, 0.3619, 0.363, 0.3642, 0.3644, + 0.3644, 0.364, 0.3631, 0.361, 0.3609, 0.36, 0.3596, 0.36, 0.3605, 0.365, 0.3665, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L56_20_m15spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0778, 0.08, 0.0988, 0.11, 0.1312, 0.19, 0.2241, 0.25, 0.2800, 0.3, 0.3163, 0.34, 0.3559, 0.36, 0.3744, 0.37, 0.3683, 0.36, 0.3553, 0.34, 0.3356, 0.32, 0.3184, 0.31, 0.3083, 0.305, 0.3014, 0.3, 0.2817, 0.26, 0.2492, 0.23, + 0.2150, 0.2, 0.1787, 0.15, 0.1448, 0.13, 0.1264, 0.125, 0.1244, 0.15, 0.1690, 0.22, 0.2816, 0.32, 0.3810, 0.4, 0.4353, 0.44, 0.4580, 0.46, 0.4682, 0.47, 0.4754, 0.48, + 0.4826, 0.483, 0.4859, 0.486, 0.4861, 0.485, 0.4842, 0.483, 0.4807, 0.48, 0.4787, 0.48, 0.4800, 0.485, 0.4888, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L68_21_m19spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1192, 0.13, 0.1536, 0.18, 0.2066, 0.3, 0.3562, 0.4, 0.4460, 0.45, 0.5051, 0.55, 0.5700, 0.6, 0.6015, 0.6, 0.5935, 0.58, 0.5748, 0.56, 0.5447, 0.53, 0.5182, 0.51, 0.5024, 0.5, 0.4912, 0.48, 0.4591, 0.42, 0.4053, 0.37, + 0.3484, 0.3, 0.2883, 0.25, 0.2325, 0.22, 0.2021, 0.2, 0.1976, 0.23, 0.2631, 0.33, 0.4293, 0.5, 0.5760, 0.6564, 0.6, 0.6901, 0.7, 0.7051, 0.71, 0.7161, 0.72, 0.7275, 0.73, + 0.7328, 0.733, 0.7329, 0.73, 0.7297, 0.725, 0.7241, 0.721, 0.7206, 0.722, 0.7229, 0.73, 0.7370, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L98_m2_m32spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2248, 0.3, 0.3270, 0.4, 0.4865, 0.6, 0.8902, 1.0, 1.1296, 1.13, 1.3004, 1.4, 1.4939, 1.5, 1.6083, 1.61, 1.6196, 1.61, 1.6050, 1.6, 1.5533, 1.54, 1.5033, 1.5, 1.4786, 1.47, 1.4628, 1.4, 1.3770, 1.3, 1.2127, 1.1, 1.0306, 0.9, 0.8418, 0.7, + 0.6705, 0.6, 0.574, 0.55, 0.5427, 0.6, 0.6117, 0.7, 0.8072, 0.9, 0.9823, 1.0, 1.0802, 1.1, 1.1215, 1.13, 1.1414, 1.15, 1.1617, 1.17, 1.1884, 1.2, 1.2025, 1.2, 1.2001, 1.19, + 1.1894, 1.18, 1.1710, 1.16, 1.1597, 1.16, 1.1670, 1.2, 1.2037, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L98_m2_m32spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2248, 0.3, 0.3370, 0.4, 0.4865, 0.6, 0.8902, 1.0, 1.1296, 1.13, 1.3004, 1.4, 1.4939, 1.5, 1.6083, 1.61, 1.6196, 1.61, 1.6050, 1.6, 1.5533, 1.54, 1.5033, 1.5, 1.4786, 1.47, 1.4628, 1.4, 1.3770, 1.3, 1.2127, 1.1, 1.0306, 0.9, 0.8418, 0.7, + 0.6705, 0.6, 0.584, 0.55, 0.5427, 0.6, 0.6117, 0.7, 0.8072, 0.9, 0.9823, 1.0, 1.0802, 1.1, 1.1215, 1.13, 1.1414, 1.15, 1.1617, 1.17, 1.1884, 1.2, 1.2025, 1.2, 1.2001, 1.19, + 1.1894, 1.18, 1.1810, 1.16, 1.1597, 1.16, 1.1670, 1.2, 1.2037, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_m27_m16spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0125, 0.02, 0.0262, 0.03, 0.0479, 0.06, 0.0964, 0.1, 0.1246, 0.13, 0.1469, 0.16, 0.1731, 0.18, 0.1917, 0.195, 0.1986, 0.2, 0.2028, 0.201, 0.2015, 0.2, 0.1997, 0.2, 0.2021, 0.203, 0.2066, 0.2, 0.1994, 0.18, 0.1778, 0.16, 0.1518, 0.13, + 0.1251, 0.11, 0.1012, 0.1, 0.0876, 0.085, 0.0805, 0.08, 0.0713, 0.06, 0.0537, 0.04, 0.0389, 0.035, 0.0313, 0.03, 0.0282, 0.025, 0.0273, 0.028, 0.0283, 0.03, 0.0308, 0.031, + 0.0325, 0.032, 0.0318, 0.031, 0.0301, 0.03, 0.0274, 0.028, 0.0258, 0.026, 0.0268, 0.03, 0.0311, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L41_m27_m16spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0125, 0.02, 0.0262, 0.03, 0.0489, 0.06, 0.0964, 0.1, 0.1246, 0.13, 0.1469, 0.16, 0.1731, 0.18, 0.1917, 0.195, 0.1986, 0.2, 0.2028, 0.201, 0.2015, 0.2, 0.1997, 0.2, 0.2021, 0.203, 0.2066, 0.2, 0.1994, 0.18, 0.1778, 0.16, 0.1518, 0.13, + 0.1251, 0.11, 0.1012, 0.1, 0.0886, 0.085, 0.0805, 0.08, 0.0713, 0.06, 0.0537, 0.04, 0.0389, 0.035, 0.0313, 0.03, 0.0282, 0.025, 0.0273, 0.028, 0.0283, 0.03, 0.0308, 0.031, + 0.0325, 0.032, 0.0318, 0.031, 0.0311, 0.03, 0.0274, 0.028, 0.0258, 0.026, 0.0268, 0.03, 0.0311, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_m9_4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0016, 0.002, 0.0027, 0.003, 0.0043, 0.006, 0.0081, 0.009, 0.0102, 0.011, 0.0119, 0.012, 0.0140, 0.014, 0.0156, 0.016, 0.0164, 0.017, 0.0170, 0.017, 0.0171, 0.0175, 0.0177, 0.02, 0.0201, 0.022, 0.0241, 0.025, 0.0261, 0.026, 0.0254, 0.025, 0.0238, 0.23, + 0.0218, 0.02, 0.0200, 0.019, 0.0189, 0.0185, 0.0183, 0.018, 0.0172, 0.016, 0.0148, 0.013, 0.0127, 0.012, 0.0116, 0.0115, 0.0112, 0.0112, 0.0111, 0.0111, 0.0111, 0.0112, 0.0113, 0.0114, 0.0115, 0.0115, + 0.0114, 0.0114, 0.0113, 0.0112, 0.0111, 0.011, 0.0109, 0.0110, 0.011, 0.0114, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_m9_4spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0016, 0.002, 0.0027, 0.003, 0.0043, 0.006, 0.0081, 0.009, 0.0102, 0.011, 0.0119, 0.012, 0.0140, 0.014, 0.0156, 0.016, 0.0164, 0.017, 0.0170, 0.017, 0.0171, 0.0175, 0.0177, 0.02, 0.0201, 0.022, 0.0241, 0.025, 0.0261, 0.026, 0.0254, 0.025, 0.0238, 0.23, + 0.0218, 0.02, 0.0220, 0.019, 0.0199, 0.0188, 0.0183, 0.018, 0.0172, 0.016, 0.0148, 0.013, 0.0127, 0.012, 0.0116, 0.0115, 0.0112, 0.0112, 0.0111, 0.0111, 0.0111, 0.0112, 0.0113, 0.0114, 0.0115, 0.0115, + 0.0114, 0.0114, 0.0113, 0.0112, 0.0111, 0.011, 0.0109, 0.0110, 0.011, 0.0114, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L11_m11_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0008, 0.001, 0.0015, 0.002, 0.0027, 0.004, 0.0053, 0.006, 0.0067, 0.007, 0.0080, 0.009, 0.0095, 0.01, 0.0107, 0.0105, 0.0113, 0.011, 0.0118, 0.012, 0.0120, 0.012, 0.0124, 0.013, 0.0140, 0.015, 0.0165, 0.017, 0.0178, 0.0175, 0.0172, 0.017, + 0.0160, 0.015, 0.0145, 0.014, 0.0132, 0.013, 0.0124, 0.012, 0.0119, 0.011, 0.0108, 0.09, 0.0085, 0.007, 0.0064, 0.006, 0.0053, 0.005, 0.0048, + 0.0049, 0.0048, 0.0047, 0.0048, 0.0048, 0.0049, 0.005, 0.0050, 0.005, 0.0049, 0.0049, 0.0048, 0.0047, 0.0047, 0.0047, 0.0046, 0.0046, 0.0046, 0.0048, 0.0049, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L14_m4_3spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0024, 0.003, 0.0034, 0.004, 0.0049, 0.007, 0.0086, 0.01, 0.0108, 0.011, 0.0124, 0.013, 0.0144, 0.015, 0.0157, 0.016, 0.0162, 0.0163, 0.0164, 0.0163, 0.0162, 0.0164, 0.0165, 0.017, 0.0183, 0.02, 0.0213, 0.022, 0.0228, 0.0225, 0.0221, 0.021, + 0.0206, 0.02, 0.0188, 0.018, 0.0172, 0.017, 0.0162, 0.016, 0.0158, 0.0158, 0.0157, 0.0158, 0.0158, 0.0159, 0.0159, 0.016, 0.0160, 0.016, 0.0160, 0.0161, 0.0161, 0.0162, + 0.0163, 0.0164, 0.0165, 0.0165, 0.0166, 0.0166, 0.0166, 0.0166, 0.0165, 0.0164, 0.0163, 0.0163, 0.0162, 0.0162, 0.0162, 0.0165, 0.0166, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_38_24spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0455, 0.0455, 0.0453, 0.045, 0.0443, 0.05, 0.0570, 0.06, 0.0651, 0.065, 0.0664, 0.066, 0.0664, 0.065, 0.0607, 0.06, 0.0513, 0.04, 0.0397, 0.03, 0.0288, 0.025, 0.0239, 0.03, 0.0302, 0.04, 0.0460, 0.05, 0.0586, 0.06, 0.0662, 0.07, + 0.0727, 0.075, 0.0769, 0.077, 0.0788, 0.08, 0.0807, 0.085, 0.0863, 0.11, 0.1241, 0.18, 0.2137, 0.24, 0.2920, 0.3, 0.3344, 0.34, 0.3522, 0.354, 0.3599, 0.36, 0.3639, 0.365, + 0.3662, 0.366, 0.3667, 0.367, 0.3674, 0.3675, 0.3678, 0.368, 0.3684, 0.3688, 0.3688, 0.3685, 0.3686, 0.37, 0.3703, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_38_24spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0455, 0.0455, 0.0453, 0.045, 0.0443, 0.05, 0.0580, 0.06, 0.0651, 0.065, 0.0664, 0.066, 0.0664, 0.065, 0.0607, 0.06, 0.0513, 0.04, 0.0397, 0.03, 0.0288, 0.025, 0.0239, 0.03, 0.0302, 0.04, 0.0460, 0.05, 0.0586, 0.06, 0.0662, 0.07, + 0.0727, 0.075, 0.0769, 0.077, 0.0798, 0.08, 0.0807, 0.085, 0.0863, 0.11, 0.1241, 0.18, 0.2137, 0.24, 0.2920, 0.3, 0.3344, 0.34, 0.3522, 0.354, 0.3599, 0.36, 0.3639, 0.365, + 0.3662, 0.366, 0.3667, 0.367, 0.3684, 0.3675, 0.3678, 0.368, 0.3684, 0.3688, 0.3688, 0.3685, 0.3686, 0.37, 0.3703, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L53_48_58spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0768, 0.075, 0.0714, 0.07, 0.0615, 0.064, 0.0656, 0.067, 0.0689, 0.065, 0.0628, 0.06, 0.0534, 0.04, 0.0375, 0.03, 0.0201, 0.0, -0.0004, -0.01, -0.0180, -0.02, -0.0228, -0.03, -0.0035, 0.0, 0.0370, 0.05, 0.0724, 0.08, 0.0977, 0.1, 0.1200, 0.13, + 0.1376, 0.14, 0.1497, 0.15, 0.1580, 0.16, 0.1701, 0.2, 0.2370, 0.3, 0.3941, 0.45, 0.5311, 0.55, 0.6053, 0.62, 0.6364, 0.64, 0.6500, 0.65, 0.6564, 0.656, 0.6596, 0.6597, + 0.6597, 0.66, 0.6612, 0.662, 0.6625, 0.663, 0.6644, 0.665, 0.6658, 0.6652, 0.6650, 0.666, 0.6665, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L53_48_58spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0768, 0.075, 0.0714, 0.07, 0.0615, 0.064, 0.0656, 0.067, 0.0689, 0.065, 0.0628, 0.06, 0.0534, 0.04, 0.0375, 0.03, 0.0201, 0.0, -0.0004, -0.01, -0.0180, -0.02, -0.0228, -0.03, -0.0035, 0.0, 0.0370, 0.05, 0.0724, 0.08, 0.0977, 0.1, 0.1200, 0.13, + 0.1376, 0.14, 0.1497, 0.15, 0.1580, 0.165, 0.1801, 0.2, 0.2370, 0.3, 0.3941, 0.45, 0.5311, 0.55, 0.6053, 0.62, 0.6364, 0.64, 0.6500, 0.65, 0.6564, 0.656, 0.6596, 0.6597, + 0.6597, 0.66, 0.6612, 0.662, 0.6625, 0.683, 0.6644, 0.675, 0.6658, 0.6652, 0.6650, 0.666, 0.6665, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L70_44_86spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1186, 0.11, 0.1086, 0.1, 0.0903, 0.09, 0.0888, 0.088, 0.0885, 0.08, 0.0760, 0.06, 0.0594, 0.04, 0.0356, 0.02, 0.0128, 0.0, -0.0144, -0.02, -0.0376, -0.035, -0.0356, 0.0, 0.0195, 0.15, 0.1214, 0.2, 0.2062, 0.24, 0.2585, 0.26, 0.2993, 0.3, 0.3307, 0.34, 0.3516, 0.36, + 0.3660, 0.37, 0.3838, 0.41, 0.4778, 0.55, 0.6974, 0.8, 0.8888, 0.95, 0.9927, 1.0, 1.0362, 1.04, 1.0559, 1.06, 1.0651, 1.066, 1.0694, 1.069, 1.0690, 1.07, 1.0713, 1.072, + 1.0733, 1.074, 1.0766, 1.076, 1.0791, 1.078, 1.0775, 1.079, 1.0794, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L70_44_86spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1186, 0.11, 0.1086, 0.1, 0.103, 0.09, 0.0888, 0.088, 0.0885, 0.08, 0.0760, 0.06, 0.0594, 0.04, 0.0356, 0.02, 0.0128, 0.0, -0.0144, -0.02, -0.0376, -0.035, -0.0356, 0.0, 0.0195, 0.15, 0.1214, 0.2, 0.2062, 0.24, 0.2585, 0.26, 0.2993, 0.3, 0.3307, 0.34, 0.3516, 0.36, + 0.3660, 0.37, 0.3838, 0.41, 0.4878, 0.55, 0.6974, 0.8, 0.8888, 0.95, 0.9927, 1.0, 1.0362, 1.04, 1.0559, 1.06, 1.0651, 1.066, 1.0694, 1.069, 1.0690, 1.07, 1.0713, 1.072, + 1.0733, 1.074, 1.0866, 1.076, 1.0891, 1.078, 1.0775, 1.079, 1.0794, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L38_42_19spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0438, 0.044, 0.0438, 0.0435, 0.0431, 0.05, 0.0562, 0.06, 0.0646, 0.065, 0.0661, 0.0662, 0.0662, 0.061, 0.0604, 0.055, 0.0506, 0.04, 0.0387, 0.03, 0.0275, 0.025, 0.0213, 0.022, 0.0233, 0.03, 0.0322, 0.035, 0.0397, 0.04, 0.0451, 0.05, + 0.0506, 0.052, 0.0543, 0.055, 0.0560, 0.0565, 0.0577, 0.06, 0.0633, 0.09, 0.1014, 0.15, 0.1919, 0.22, 0.2710, 0.3, 0.3138, 0.32, 0.3317, 0.335, 0.3394, 0.34, 0.3433, 0.345, + 0.3457, 0.346, 0.3461, 0.3465, 0.3469, 0.347, 0.3473, 0.3475, 0.3478, 0.348, 0.3482, 0.348, 0.3480, 0.349, 0.3497, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L38_42_19spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0438, 0.044, 0.0438, 0.0435, 0.0441, 0.05, 0.0562, 0.06, 0.0646, 0.065, 0.0661, 0.0662, 0.0662, 0.061, 0.0604, 0.055, 0.0506, 0.04, 0.0387, 0.03, 0.0275, 0.025, 0.0213, 0.022, 0.0233, 0.03, 0.0322, 0.035, 0.0397, 0.04, 0.0451, 0.05, + 0.0506, 0.052, 0.0543, 0.055, 0.0570, 0.0565, 0.0577, 0.06, 0.0633, 0.09, 0.1014, 0.15, 0.1919, 0.22, 0.2710, 0.3, 0.3138, 0.32, 0.3317, 0.335, 0.3394, 0.34, 0.3433, 0.345, + 0.3457, 0.346, 0.3461, 0.3465, 0.3569, 0.348, 0.3473, 0.3475, 0.3478, 0.348, 0.3482, 0.348, 0.3480, 0.349, 0.3497, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L60_63_85spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1186, 0.11, 0.1079, 0.1, 0.0890, 0.089, 0.0882, 0.089, 0.0895, 0.08, 0.0764, 0.06, 0.0573, 0.04, 0.0286, 0.0, -0.0013, -0.02, -0.0355, -0.05, -0.0640, -0.07, + -0.0738, -0.06, -0.0504, 0.0, 0.0021, 0.03, 0.0514, 0.08, 0.0918, 0.1, 0.1301, 0.14, 0.1619, 0.17, 0.1847, 0.19, 0.2000, 0.21, 0.2206, 0.28, 0.3301, 0.4, 0.5869, 0.7, + 0.8108, 0.9, 0.9318, 0.94, 0.9824, 1.0, 1.0045, 1.01, 1.0146, 1.015, 1.0192, 1.093, 1.0192, 1.02, 1.0218, 1.022, 1.0241, 1.024, 1.0275, 1.03, 1.0300, 1.029, 1.0285, 1.03, 1.0302, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L60_63_85spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1186, 0.11, 0.1079, 0.1, 0.0900, 0.089, 0.0882, 0.089, 0.0895, 0.08, 0.0764, 0.06, 0.0573, 0.04, 0.0286, 0.0, -0.0013, -0.02, -0.0355, -0.05, -0.0640, -0.07, + -0.0738, -0.06, -0.0504, 0.0, 0.0021, 0.03, 0.0514, 0.08, 0.0918, 0.1, 0.1301, 0.14, 0.1619, 0.17, 0.1847, 0.19, 0.2000, 0.21, 0.2206, 0.28, 0.3301, 0.4, 0.5869, 0.7, + 0.8108, 0.9, 0.9418, 0.94, 0.9924, 1.0, 1.0045, 1.01, 1.0146, 1.015, 1.0192, 1.093, 1.0192, 1.05, 1.0218, 1.022, 1.0241, 1.024, 1.0275, 1.03, 1.0300, 1.029, 1.0285, 1.03, 1.0302, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L80_75_30spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2541, 0.255, 0.2557, 0.255, 0.2543, 0.3, 0.3359, 0.35, 0.3885, 0.39, 0.3999, 0.4, 0.4038, 0.4, 0.3722, 0.35, 0.3159, 0.3, 0.2468, 0.2, 0.1816, 0.15, 0.1439, 0.15, 0.1522, 0.18, 0.1981, 0.21, 0.2359, 0.25, 0.2630, 0.28, 0.2910, 0.3, + 0.3087, 0.31, 0.3154, 0.32, 0.3236, 0.34, 0.3555, 0.4, 0.5755, 0.8, 1.0987, 1.4, 1.5560, 1.7, 1.8035, 1.9, 1.9070, 1.92, 1.9519, 1.96, 1.9747, 1.98, 1.9884, 1.99, + 1.9914, 1.994, 1.9958, 1.996, 1.9979, 2.0, 2.0004, 2.01, 2.0024, 2.02, 2.0013, 2.012, 2.0117, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L80_75_30spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2541, 0.255, 0.2557, 0.255, 0.2543, 0.3, 0.3359, 0.35, 0.3885, 0.39, 0.3999, 0.4, 0.4038, 0.4, 0.3722, 0.35, 0.3159, 0.3, 0.2468, 0.2, 0.1816, 0.15, 0.1439, 0.15, 0.1522, 0.18, 0.1981, 0.21, 0.2359, 0.25, 0.2630, 0.28, 0.2910, 0.3, + 0.3087, 0.31, 0.3154, 0.32, 0.3236, 0.36, 0.3555, 0.4, 0.5755, 0.8, 1.0987, 1.4, 1.5560, 1.7, 1.8035, 1.9, 1.9070, 1.92, 1.9519, 1.96, 1.9747, 1.98, 1.9884, 1.99, + 1.9984, 1.994, 1.9958, 1.986, 1.9979, 2.06, 2.0004, 2.01, 2.0024, 2.02, 2.0013, 2.012, 2.0117, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L28_m21_24spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0003, 0.0, 0.0008, 0.002, 0.0025, 0.003, 0.0049, 0.005, 0.0059, 0.006, 0.0075, 0.01, 0.0101, 0.012, 0.0133, 0.015, 0.0167, 0.018, 0.0199, 0.02, 0.0221, 0.023, 0.0266, 0.03, 0.0388, 0.05, 0.0577, 0.07, 0.0706, 0.073, 0.0736, 0.073, + 0.0728, 0.071, 0.0708, 0.07, 0.0686, 0.069, 0.0673, 0.068, 0.0657, 0.06, 0.0582, 0.05, 0.0407, 0.03, 0.0255, 0.02, 0.0174, 0.015, 0.0141, 0.013, 0.0129, 0.0126, + 0.0125, 0.0125, 0.0125, 0.0125, 0.0125, 0.0124, 0.0123, 0.0122, 0.0121, 0.012, 0.0118, 0.0117, 0.0117, 0.0118, 0.0118, 0.012, 0.0121, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L28_m21_24spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0003, 0.0, 0.0008, 0.002, 0.0025, 0.003, 0.0049, 0.005, 0.0059, 0.006, 0.0075, 0.01, 0.0101, 0.012, 0.0133, 0.015, 0.0167, 0.018, 0.0199, 0.02, 0.0221, 0.023, 0.0266, 0.03, 0.0388, 0.05, 0.0577, 0.07, 0.0706, 0.073, 0.0736, 0.073, + 0.0728, 0.071, 0.0728, 0.07, 0.0686, 0.069, 0.0653, 0.068, 0.0657, 0.06, 0.0582, 0.05, 0.0407, 0.03, 0.0255, 0.02, 0.0174, 0.015, 0.0141, 0.013, 0.0129, 0.0126, + 0.0125, 0.0125, 0.0135, 0.0125, 0.0125, 0.0124, 0.0123, 0.0122, 0.0121, 0.012, 0.0118, 0.0117, 0.0117, 0.0118, 0.0118, 0.012, 0.0121, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L45_m33_47spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0048, -0.004, -0.0032, -0.002, -0.0011, -0.001, -0.0007, -0.001, -0.0021, -0.001, 0.0003, 0.003, 0.0040, 0.009, 0.0115, 0.02, 0.0213, 0.03, 0.0311, 0.032, 0.0385, 0.04, 0.0527, 0.08, 0.0890, 0.1, 0.1449, 0.15, 0.1843, 0.19, 0.1961, 0.1967, + 0.1967, 0.195, 0.1942, 0.193, 0.1905, 0.19, 0.1884, 0.185, 0.1842, 0.17, 0.1610, 0.13, 0.1059, 0.09, 0.0578, 0.04, 0.0323, 0.03, 0.0217, 0.02, + 0.0179, 0.018, 0.0164, 0.016, 0.0159, 0.0158, 0.0157, 0.0154, 0.0151, 0.015, 0.0147, 0.0143, 0.0142, 0.0142, 0.0141, 0.0142, 0.0142, 0.0143, 0.0143, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L45_m33_47spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0048, -0.004, -0.0032, -0.002, -0.0011, -0.001, -0.0007, -0.001, -0.0021, -0.001, 0.0003, 0.003, 0.0040, 0.009, 0.0115, 0.02, 0.0213, 0.03, 0.0311, 0.032, 0.0385, 0.04, 0.0527, 0.08, 0.0890, 0.1, 0.1449, 0.15, 0.1843, 0.19, 0.1961, 0.1967, + 0.1967, 0.195, 0.1942, 0.193, 0.2005, 0.19, 0.1884, 0.185, 0.1842, 0.19, 0.1610, 0.13, 0.1059, 0.09, 0.0578, 0.04, 0.0323, 0.03, 0.0217, 0.02, + 0.0179, 0.018, 0.0164, 0.016, 0.0159, 0.0158, 0.0157, 0.0154, 0.0151, 0.015, 0.0157, 0.0143, 0.0142, 0.0142, 0.0141, 0.0142, 0.0142, 0.0143, 0.0143, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L26_m7_404spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0064, 0.008, 0.0094, 0.01, 0.0142, 0.02, 0.0258, 0.03, 0.0324, 0.033, 0.0375, 0.04, 0.0435, 0.044, 0.0475, 0.048, 0.0489, 0.049, 0.0495, 0.049, 0.0489, 0.049, 0.0491, 0.05, 0.0529, 0.053, 0.0595, 0.06, 0.0621, 0.055, 0.0590, 0.058, 0.0541, 0.05, + 0.0485, 0.045, 0.0432, 0.042, 0.0403, 0.04, 0.0390, 0.038, 0.0386, 0.0386, 0.0386, 0.0387, 0.0387, 0.0388, 0.0389, 0.039, 0.0390, 0.0391, 0.0392, 0.0395, 0.0396, 0.04, + 0.0403, 0.0402, 0.0407, 0.0406, 0.0406, 0.0404, 0.0402, 0.04, 0.0397, 0.0395, 0.0394, 0.0395, 0.0396, 0.04, 0.0406, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L34_m61_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0084, -0.004, -0.0019, 0.0, 0.0084, 0.01, 0.0259, 0.03, 0.0352, 0.04, 0.0451, 0.05, 0.0580, 0.06, 0.0705, 0.075, 0.0800, 0.085, 0.0888, 0.09, 0.0942, 0.1, 0.1007, 0.11, + 0.1154, 0.12, 0.1367, 0.14, 0.1471, 0.142, 0.1409, 0.13, 0.1285, 0.12, 0.1150, 0.11, 0.1028, 0.1, 0.0957, 0.09, 0.0894, 0.07, 0.0660, 0.04, 0.0123, 0.0, -0.0345, -0.04, + -0.0593, -0.06, -0.0697, -0.07, -0.0737, -0.074, -0.0749, -0.0745, -0.0746, -0.0744, -0.0742, -0.0748, -0.0749, -0.075, -0.0759, -0.077, -0.0773, -0.078, -0.0782, -0.078, -0.0777, -0.077, -0.0762, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L32_m16_17spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0034, 0.004, 0.0056, 0.007, 0.0089, 0.01, 0.0160, 0.014, 0.0197, 0.02, 0.0232, 0.025, 0.0279, 0.03, 0.0322, 0.033, 0.0355, 0.037, 0.0383, 0.039, 0.0397, 0.04, 0.0436, 0.05, 0.0560, 0.07, 0.0757, 0.08, 0.0884, 0.09, + 0.0900, 0.089, 0.0875, 0.085, 0.0837, 0.08, 0.0796, 0.078, 0.0774, 0.076, 0.0756, 0.07, 0.0698, 0.06, 0.0566, 0.05, 0.0452, 0.04, 0.0392, 0.036, 0.0367, + 0.0360, 0.036, 0.0359, 0.036, 0.0363, 0.0364, 0.0364, 0.0363, 0.0362, 0.036, 0.0359, 0.0356, 0.0355, 0.0353, 0.0352, 0.0353, 0.0354, 0.036, 0.0361, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_m19_15spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0020, 0.003, 0.0043, 0.006, 0.0078, 0.01, 0.0149, 0.016, 0.0187, 0.02, 0.0223, 0.025, 0.0270, 0.03, 0.0315, 0.032, 0.0349, 0.036, 0.0379, 0.038, 0.0394, 0.04, 0.0431, 0.05, + 0.0542, 0.06, 0.0715, 0.08, 0.0824, 0.083, 0.0832, 0.081, 0.0801, 0.078, 0.0759, 0.074, 0.0717, 0.07, 0.0693, 0.068, 0.0673, 0.064, 0.0608, 0.05, 0.0458, 0.04, + 0.0328, 0.03, 0.0260, 0.025, 0.0232, 0.023, 0.0223, 0.0221, 0.0221, 0.0223, 0.0224, 0.0225, 0.0226, 0.0224, 0.0224, 0.0221, 0.0220, 0.022, 0.0216, 0.0215, 0.0213, 0.0214, 0.0215, 0.02, 0.0222, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_m17_16spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0027, 0.003, 0.0048, 0.006, 0.0080, 0.01, 0.0148, 0.015, 0.0183, 0.02, 0.0216, 0.025, 0.0261, 0.03, 0.0303, 0.032, 0.0334, 0.035, 0.0361, 0.037, 0.0375, 0.04, 0.0411, 0.05, 0.0524, 0.06, 0.0700, 0.08, 0.0813, 0.082, 0.0825, 0.08, 0.0799, 0.077, + 0.0761, 0.075, 0.0722, 0.07, 0.0700, 0.069, 0.0682, 0.067, 0.0624, 0.055, 0.0493, 0.04, 0.0378, 0.035, 0.0318, 0.03, 0.0294, 0.029, 0.0286, 0.0285, 0.0285, 0.0287, + 0.0288, 0.029, 0.0290, 0.029, 0.0287, 0.0285, 0.0284, 0.0282, 0.0280, 0.028, 0.0278, 0.0279, 0.0279, 0.028, 0.0286, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L35_m8_4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0109, 0.014, 0.0158, 0.02, 0.0233, 0.03, 0.0419, 0.05, 0.0525, 0.06, 0.0606, 0.07, 0.0702, 0.075, 0.0768, 0.078, 0.0793, 0.08, 0.0805, 0.08, 0.0795, 0.08, 0.0806, 0.085, 0.0889, 0.1, 0.1028, 0.105, 0.1094, 0.106, 0.1054, 0.1, 0.0979, 0.09, + 0.0891, 0.085, 0.0807, 0.08, 0.0761, 0.075, 0.0739, 0.073, 0.0730, 0.073, 0.0722, 0.072, 0.0718, 0.0716, 0.0718, 0.0718, 0.0719, 0.072, 0.0722, 0.0725, 0.0729, 0.073, + 0.0741, 0.0745, 0.0746, 0.0744, 0.0744, 0.074, 0.0739, 0.073, 0.0730, 0.073, 0.0725, 0.0727, 0.0728, 0.073, 0.0745, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L37_m7_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0126, 0.015, 0.0178, 0.02, 0.0258, 0.03, 0.0457, 0.05, 0.0572, 0.06, 0.0658, 0.07, 0.0760, 0.08, 0.0830, 0.084, 0.0856, 0.086, 0.0867, 0.086, 0.0856, 0.086, 0.0868, 0.09, 0.0961, 0.1, 0.1120, 0.113, 0.1199, 0.118, 0.1160, 0.11, 0.1081, 0.1, + 0.0989, 0.09, 0.0900, 0.088, 0.0851, 0.084, 0.0828, 0.0825, 0.0825, 0.083, 0.0831, 0.0835, 0.0839, 0.084, 0.0846, 0.0845, 0.0849, 0.085, 0.0854, 0.086, 0.0862, 0.087, + 0.0875, 0.088, 0.0881, 0.088, 0.0879, 0.0875, 0.0873, 0.087, 0.0864, 0.086, 0.0858, 0.086, 0.0862, 0.087, 0.0881, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L45_m7_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0213, 0.03, 0.0302, 0.04, 0.0438, 0.06, 0.0780, 0.09, 0.0979, 0.1, 0.1125, 0.12, 0.1297, 0.13, 0.1411, 0.143, 0.1445, 0.1454, 0.1456, 0.143, 0.1428, 0.143, 0.1433, 0.15, 0.1548, 0.16, 0.1750, 0.18, 0.1833, 0.18, 0.1749, 0.17, 0.1610, 0.15, + 0.1452, 0.14, 0.1301, 0.13, 0.1219, 0.12, 0.1183, 0.119, 0.1197, 0.12, 0.1254, 0.13, 0.1308, 0.133, 0.1342, 0.135, 0.1356, 0.136, 0.1367, 0.137, 0.1383, 0.14, 0.1405, 0.141, + 0.1416, 0.1415, 0.1413, 0.141, 0.1403, 0.14, 0.1387, 0.138, 0.1378, 0.138, 0.1384, 0.14, 0.1416, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_m6_5spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0164, 0.02, 0.0226, 0.03, 0.0320, 0.04, 0.0562, 0.06, 0.0701, 0.08, 0.0804, 0.09, 0.0925, 0.1, 0.1006, 0.103, 0.1031, 0.1035, 0.1039, 0.103, 0.1021, 0.103, 0.1030, 0.11, 0.1135, 0.12, 0.1316, 0.13, 0.1403, 0.14, 0.1356, 0.13, 0.1264, 0.12, 0.1155, 0.11, 0.1050, 0.1, + 0.0992, 0.097, 0.0968, 0.097, 0.0979, 0.1, 0.1024, 0.103, 0.1065, 0.108, 0.1091, 0.11, 0.1102, 0.111, 0.1110, 0.111, 0.1122, 0.113, 0.1138, 0.114, 0.1145, 0.1145, 0.1143, 0.114, + 0.1136, 0.113, 0.1125, 0.112, 0.1119, 0.112, 0.1123, 0.113, 0.1146, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L46_m6_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0233, 0.03, 0.0322, 0.04, 0.0460, 0.06, 0.0811, 0.1, 0.1015, 0.11, 0.1163, 0.12, 0.1338, 0.14, 0.1451, 0.148, 0.1483, 0.145, 0.1489, 0.146, 0.1458, 0.146, 0.1461, 0.15, 0.1582, 0.17, 0.1795, 0.18, 0.1886, 0.181, 0.1804, 0.17, 0.1666, 0.16, + 0.1508, 0.14, 0.1356, 0.13, 0.1273, 0.125, 0.1239, 0.124, 0.1266, 0.13, 0.1356, 0.14, 0.1438, 0.145, 0.1488, 0.15, 0.1509, 0.152, 0.1523, 0.153, 0.1540, 0.155, 0.1563, 0.157, + 0.1574, 0.156, 0.1571, 0.157, 0.1562, 0.56, 0.1546, 0.154, 0.1537, 0.154, 0.1542, 0.156, 0.1576, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L48_m69_16spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0181, -0.01, -0.0091, 0.0, 0.0052, 0.01, 0.0259, 0.03, 0.0360, 0.04, 0.0492, 0.06, 0.0677, 0.08, 0.0879, 0.1, 0.1059, 0.11, 0.1233, 0.13, 0.1351, 0.14, 0.1511, 0.17, 0.1875, 0.2, 0.2413, 0.26, 0.2732, 0.271, 0.2706, 0.26, 0.2546, 0.24, + 0.2358, 0.22, 0.2184, 0.21, 0.2082, 0.2, 0.1975, 0.17, 0.1520, 0.06, 0.0462, 0.0, -0.0459, -0.06, -0.0950, -0.1, -0.1154, -0.12, -0.1232, -0.124, -0.1260, -0.126, + -0.1261, -0.126, -0.1257, -0.126, -0.1270, -0.128, -0.1285, -0.13, -0.1306, -0.132, -0.1318, -0.1312, -0.1311, -0.13, -0.1294, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L51_89_53spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1314, 0.13, 0.1218, 0.11, 0.1046, 0.11, 0.1137, 0.12, 0.1221, 0.12, 0.1115, 0.1, 0.0933, 0.08, 0.0607, 0.04, 0.0225, 0.0, -0.0208, -0.04, -0.0572, -0.06, -0.0798, -0.08, -0.0852, -0.08, -0.0759, -0.06, -0.0588, -0.04, -0.0307, 0.0, 0.0037, 0.0036, 0.0336, 0.04, + 0.0557, 0.06, 0.0706, 0.08, 0.0944, 0.15, 0.2271, 0.4, 0.5396, 0.7, 0.8124, 0.9, 0.9595, 1.0, 1.0210, 1.03, 1.0472, 1.05, 1.0593, 1.06, 1.0651, 1.0656, 1.0656, 1.067, + 1.0686, 1.07, 1.0711, 1.073, 1.0745, 1.075, 1.0768, 1.076, 1.0754, 1.077, 1.0780, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L49_84_33spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1189, 0.115, 0.1130, 0.11, 0.1020, 0.11, 0.1198, 0.125, 0.1331, 0.13, 0.1281, 0.12, 0.1169, 0.1, 0.0909, 0.07, 0.0573, 0.04, 0.0189, 0.0, -0.0145, -0.02, -0.0366, -0.04, + -0.0456, -0.044, -0.0438, -0.04, -0.0353, -0.02, -0.0165, 0.0, 0.0084, 0.01, 0.0297, 0.03, 0.0447, 0.05, 0.0554, 0.06, 0.0754, 0.1, 0.1935, 0.3, 0.4724, 0.6, 0.7159, 0.75, + 0.8473, 0.9, 0.9022, 0.91, 0.9255, 0.92, 0.9366, 0.94, 0.9423, 0.943, 0.9431, 0.944, 0.9457, 0.946, 0.9476, 0.95, 0.9501, 0.951, 0.9518, 0.951, 0.9508, 0.952, 0.9539, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L59_m51_31spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0123, -0.002, -0.0032, 0.0, 0.0108, 0.02, 0.0316, 0.04, 0.0410, 0.05, 0.0543, 0.06, 0.0737, 0.08, 0.0961, 0.1, 0.1175, 0.12, 0.1380, 0.14, 0.1519, 0.16, 0.1752, 0.2, 0.2340, 0.3, 0.3232, 0.35, 0.3810, 0.385, + 0.3880, 0.38, 0.3752, 0.36, 0.3573, 0.34, 0.3395, 0.33, 0.3292, 0.32, 0.3176, 0.3, 0.2669, 0.2, 0.1484, 0.1, 0.0451, 0.0, -0.0097, -0.02, -0.0324, -0.04, -0.0408, -0.042, + -0.0437, -0.0436, -0.0438, -0.0436, -0.0436, -0.045, -0.0450, -0.046, -0.0465, -0.047, -0.0486, -0.049, -0.0497, -0.0493, -0.0491, -0.048, -0.0472, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L48_m69_16spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0181, -0.02, -0.0090, 0.004, 0.0052, 0.01, 0.0259, 0.03, 0.0361, 0.04, 0.0493, 0.05, 0.0678, 0.07, 0.0880, 0.1, 0.1060, 0.11, 0.1235, 0.13, 0.1353, 0.14, 0.1513, 0.17, 0.1879, 0.21, 0.2419, 0.25, 0.2739, 0.273, 0.2713, 0.26, 0.2553, 0.24, 0.2366, 0.22, + 0.2191, 0.21, 0.2089, 0.2, 0.1982, 0.17, 0.1527, 0.08, 0.0468, 0.0, -0.0455, -0.05, -0.0946, -0.1, -0.1150, -0.12, -0.1228, -0.123, -0.1256, -0.125, -0.1258, -0.1255, + -0.1254, -0.125, -0.1267, -0.127, -0.1281, -0.13, -0.1303, -0.131, -0.1315, -0.131, -0.1308, -0.13, -0.1291, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L53_m71_6spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0168, -0.015, -0.0015, 0.01, 0.0226, 0.05, 0.0640, 0.07, 0.0860, 0.1, 0.1093, 0.12, 0.1397, 0.15, 0.1692, 0.18, 0.1916, 0.2, 0.2125, 0.22, 0.2250, 0.23, 0.2414, 0.27, 0.2802, 0.3, 0.3375, 0.35, 0.3670, 0.35, 0.3546, 0.33, + 0.3264, 0.3, 0.2951, 0.27, 0.2665, 0.25, 0.2499, 0.24, 0.2353, 0.2, 0.1811, 0.1, 0.0565, 0.0, -0.0519, -0.08, -0.1095, -0.1, -0.1334, -0.14, -0.1425, -0.143, + -0.1453, -0.145, -0.1446, -0.144, -0.1435, -0.144, -0.1452, -0.146, -0.1475, -0.15, -0.1509, -0.151, -0.1528, -0.153, -0.1516, -0.15, -0.1482, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L51_m89_53spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1331, 0.13, 0.1233, 0.11, 0.1059, 0.11, 0.1151, 0.12, 0.1236, 0.12, 0.1129, 0.1, 0.0946, 0.07, 0.0615, 0.05, 0.0228, 0.0, -0.0210, -0.04, -0.0579, -0.07, -0.0808, -0.08, -0.0863, -0.08, -0.0769, -0.06, -0.0595, -0.04, -0.0311, 0.001, 0.0037, 0.035, + 0.0341, 0.04, 0.0564, 0.06, 0.0716, 0.08, 0.0956, 0.15, 0.2300, 0.4, 0.5466, 0.7, 0.8229, 0.9, 0.9720, 1.0, 1.0342, 1.05, 1.0608, 1.07, 1.0730, 1.075, 1.0789, 1.079, + 1.0794, 1.08, 1.0825, 1.083, 1.0850, 1.088, 1.0884, 1.09, 1.0908, 1.09, 1.0894, 1.09, 1.0920, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L49_84_33spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1189, 0.125, 0.1130, 0.11, 0.1020, 0.11, 0.1198, 0.125, 0.1331, 0.13, 0.1281, 0.12, 0.1369, 0.1, 0.0909, 0.07, 0.0573, 0.04, 0.0189, 0.0, -0.0145, -0.02, -0.0366, -0.04, + -0.0456, -0.044, -0.0438, -0.04, -0.0353, -0.02, -0.0165, 0.0, 0.0084, 0.01, 0.0297, 0.03, 0.0447, 0.05, 0.0554, 0.06, 0.0754, 0.1, 0.1935, 0.3, 0.4724, 0.6, 0.7159, 0.75, + 0.8473, 0.9, 0.9122, 0.91, 0.9255, 0.92, 0.9366, 0.94, 0.9423, 0.943, 0.9431, 0.944, 0.9457, 0.946, 0.9476, 0.95, 0.9501, 0.951, 0.9518, 0.951, 0.9508, 0.952, 0.9539, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_m27_28spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0012, 0.0, 0.0007, 0.004, 0.0036, 0.007, 0.0079, 0.009, 0.0095, 0.01, 0.0123, 0.012, 0.0168, 0.02, 0.0223, 0.025, 0.0280, 0.03, 0.0335, 0.035, 0.0373, 0.04, 0.0447, 0.06, 0.0645, 0.08, 0.0949, 0.1, 0.1156, 0.12, 0.1202, 0.12, + 0.1185, 0.115, 0.1149, 0.113, 0.1110, 0.11, 0.1088, 0.107, 0.1060, 0.1, 0.0931, 0.08, 0.0628, 0.05, 0.0363, 0.03, 0.0224, 0.02, 0.0166, 0.015, 0.0145, 0.014, 0.0138, 0.0138, + 0.0138, 0.0138, 0.0138, 0.0135, 0.0134, 0.0132, 0.0131, 0.013, 0.0126, 0.0125, 0.0124, 0.0125, 0.0125, 0.013, 0.0130, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_m27_28spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0012, 0.0, 0.0007, 0.004, 0.0036, 0.007, 0.0079, 0.009, 0.0095, 0.01, 0.0153, 0.012, 0.0168, 0.02, 0.0223, 0.025, 0.0280, 0.03, 0.0335, 0.035, 0.0373, 0.04, 0.0447, 0.06, 0.0645, 0.08, 0.0949, 0.1, 0.1156, 0.12, 0.1202, 0.12, + 0.1185, 0.115, 0.1249, 0.113, 0.1110, 0.11, 0.1088, 0.107, 0.1060, 0.1, 0.0931, 0.08, 0.0628, 0.05, 0.0363, 0.03, 0.0224, 0.02, 0.0166, 0.015, 0.0145, 0.014, 0.0138, 0.0138, + 0.0138, 0.0138, 0.0138, 0.0135, 0.0134, 0.0132, 0.0131, 0.013, 0.0136, 0.0125, 0.0124, 0.0125, 0.0125, 0.013, 0.0130, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_m27_28spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0012, 0.0, 0.0007, 0.004, 0.0036, 0.007, 0.0079, 0.009, 0.0095, 0.01, 0.0153, 0.012, 0.0168, 0.02, 0.0223, 0.025, 0.0280, 0.03, 0.0335, 0.035, 0.0373, 0.04, 0.0447, 0.06, 0.0645, 0.08, 0.0949, 0.1, 0.1156, 0.12, 0.1202, 0.12, + 0.1185, 0.115, 0.1049, 0.113, 0.1110, 0.11, 0.1088, 0.107, 0.1060, 0.1, 0.0931, 0.08, 0.0628, 0.05, 0.0363, 0.03, 0.0224, 0.02, 0.0166, 0.015, 0.0145, 0.014, 0.0138, 0.0138, + 0.0138, 0.0138, 0.0138, 0.0135, 0.0134, 0.0132, 0.0131, 0.012, 0.0136, 0.0115, 0.0124, 0.0125, 0.0125, 0.013, 0.0130, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L63_16_71spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0572, 0.055, 0.0533, 0.05, 0.0456, 0.0455, 0.0455, 0.045, 0.0446, 0.04, 0.0397, 0.035, 0.0344, 0.03, 0.0278, 0.025, 0.0233, 0.02, 0.0164, 0.01, 0.0099, 0.02, 0.0210, 0.05, 0.0751, 0.1, 0.1672, 0.2, 0.2386, 0.25, 0.2735, 0.28, + 0.2946, 0.3, 0.308, 0.31, 0.3164, 0.32, 0.3222, 0.325, 0.3282, 0.35, 0.3595, 0.4, 0.4319, 0.45, 0.4950, 0.5, 0.5297, 0.53, 0.5443, 0.55, 0.5516, 0.553, 0.5552, 0.556, + 0.5571, 0.557, 0.5568, 0.557, 0.5575, 0.558, 0.5582, 0.559, 0.5596, 0.56, 0.5608, 0.56, 0.5600, 0.56, 0.5611, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L84_4_46spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0967, 0.1, 0.1060, 0.11, 0.1183, 0.14, 0.1696, 0.18, 0.1976, 0.2, 0.2146, 0.22, 0.2361, 0.24, 0.2486, 0.25, 0.2527, 0.251, 0.2504, 0.25, 0.2420, 0.25, 0.2618, 0.3, 0.3581, 0.4, 0.5200, 0.6, 0.6329, 0.65, 0.6662, 0.67, + 0.6704, 0.67, 0.6620, 0.65, 0.6470, 0.645, 0.6405, 0.6402, 0.6404, 0.65, 0.6689, 0.7, 0.7383, 0.75, 0.7991, 0.8, 0.8336, 0.84, 0.8483, 0.85, 0.8569, 0.86, 0.8627, 0.865, 0.8680, 0.868, 0.8691, 0.869, 0.8693, 0.869, + 0.8685, 0.868, 0.8675, 0.8675, 0.8675, 0.8675, 0.8674, 0.87, 0.8737, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L84_4_46spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0967, 0.1, 0.1060, 0.12, 0.1183, 0.14, 0.1696, 0.18, 0.1976, 0.2, 0.2146, 0.22, 0.2361, 0.24, 0.2486, 0.25, 0.2527, 0.251, 0.2504, 0.25, 0.2420, 0.25, 0.2618, 0.3, 0.3581, 0.4, 0.5200, 0.6, 0.6329, 0.65, 0.6662, 0.67, + 0.6704, 0.67, 0.6620, 0.65, 0.6570, 0.645, 0.6405, 0.6402, 0.6404, 0.65, 0.6689, 0.7, 0.7383, 0.75, 0.7991, 0.8, 0.8336, 0.84, 0.8483, 0.85, 0.8569, 0.86, 0.8627, 0.865, 0.8680, 0.868, 0.8691, 0.869, 0.8693, 0.869, + 0.8685, 0.868, 0.8675, 0.8685, 0.8675, 0.8675, 0.8674, 0.87, 0.8737, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L75_m66_19spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0156, 0.0, 0.0098, 0.02, 0.0496, 0.1, 0.1201, 0.13, 0.1571, 0.18, 0.1958, 0.22, 0.2475, 0.28, 0.2978, 0.31, 0.3372, 0.35, 0.3735, 0.38, 0.3950, 0.4, 0.4291, 0.5, 0.5173, 0.6, 0.6511, 0.7, 0.7285, 0.72, 0.7189, 0.7, 0.6762, 0.67, 0.6258, 0.6, 0.5783, 0.56, 0.5509, 0.53, + 0.5265, 0.5, 0.4363, 0.3, 0.2287, 0.1, 0.0482, 0.0, -0.0474, -0.06, -0.0871, -0.1, -0.1017, -0.105, -0.1059, -0.105, -0.1043, -0.103, -0.1026, -0.104, -0.1055, -0.108, + -0.1092, -0.11, -0.1148, -0.115, -0.1179, -0.116, -0.1160, -0.11, -0.1098, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L75_m66_19spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0156, 0.0, 0.0098, 0.03, 0.0496, 0.1, 0.1201, 0.13, 0.1571, 0.18, 0.1958, 0.22, 0.2475, 0.28, 0.2978, 0.31, 0.3372, 0.35, 0.3735, 0.38, 0.3950, 0.4, 0.4291, 0.5, 0.5173, 0.6, 0.6511, 0.7, 0.7285, 0.72, 0.7189, 0.7, 0.6762, 0.67, 0.6258, 0.6, 0.5783, 0.56, 0.5509, 0.53, + 0.5265, 0.5, 0.4363, 0.3, 0.2587, 0.1, 0.0482, 0.0, -0.0494, -0.06, -0.0871, -0.1, -0.1017, -0.105, -0.1059, -0.105, -0.1043, -0.103, -0.1026, -0.104, -0.1055, -0.108, + -0.1092, -0.11, -0.1148, -0.115, -0.1179, -0.116, -0.1160, -0.11, -0.1098, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L64_m82_m6spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0171, 0.01, 0.0138, 0.05, 0.0628, 0.1, 0.1546, 0.2, 0.2056, 0.22, 0.2535, 0.3, 0.3138, 0.35, 0.3665, 0.4, 0.4005, 0.42, 0.4306, 0.44, 0.4457, 0.45, 0.4630, 0.5, 0.5062, 0.53, 0.5693, 0.58, 0.5909, 0.57, 0.5532, 0.5, 0.4940, 0.45, 0.4313, 0.4, + 0.3751, 0.35, 0.3425, 0.33, 0.3178, 0.3, 0.2396, 0.1, 0.0625, 0.0, -0.0910, -0.1, -0.1723, -0.2, -0.2062, -0.21, -0.2191, -0.22, -0.2221, -0.22, -0.2193, -0.219, -0.2165, -0.218, + -0.2193, -0.22, -0.2235, -0.23, -0.2302, -0.232, -0.2341, -0.232, -0.2317, -0.23, -0.2240, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L64_m82_m6spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0171, 0.01, 0.0138, 0.05, 0.0648, 0.1, 0.1546, 0.2, 0.2056, 0.22, 0.2535, 0.3, 0.3138, 0.35, 0.3665, 0.4, 0.4105, 0.42, 0.4306, 0.44, 0.4457, 0.45, 0.4630, 0.5, 0.5062, 0.53, 0.5693, 0.58, 0.5909, 0.57, 0.5532, 0.5, 0.4940, 0.45, 0.4313, 0.4, + 0.3751, 0.35, 0.3425, 0.33, 0.3378, 0.3, 0.2396, 0.1, 0.0625, 0.0, -0.0910, -0.1, -0.1723, -0.2, -0.2062, -0.21, -0.2191, -0.22, -0.2221, -0.22, -0.2193, -0.219, -0.2165, -0.218, + -0.2193, -0.22, -0.2235, -0.23, -0.2302, -0.232, -0.2341, -0.232, -0.2317, -0.23, -0.2240, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L66_m71_m17spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0007, 0.03, 0.0403, 0.08, 0.1029, 0.2, 0.2297, 0.25, 0.3019, 0.33, 0.3645, 0.4, 0.4407, 0.5, 0.5018, 0.52, 0.5344, 0.55, 0.5612, 0.57, 0.5702, 0.574, 0.5790, 0.6, 0.6080, 0.63, 0.6506, 0.65, 0.6510, 0.6, 0.5942, 0.55, 0.5179, 0.5, 0.4388, 0.4, + 0.3682, 0.34, 0.3275, 0.31, 0.3009, 0.25, 0.2329, 0.1, 0.0832, 0.0, -0.0461, -0.1, -0.1142, -0.12, -0.1425, -0.15, -0.1531, -0.154, -0.1542, -0.15, -0.1490, -0.145, + -0.1449, -0.148, -0.1478, -0.15, -0.1529, -0.16, -0.1611, -0.165, -0.1661, -0.164, -0.1630, -0.16, -0.1522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L66_m71_m17spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0007, 0.03, 0.0403, 0.08, 0.1429, 0.2, 0.2297, 0.25, 0.3019, 0.33, 0.3645, 0.4, 0.4407, 0.54, 0.5018, 0.52, 0.5344, 0.55, 0.5612, 0.57, 0.5702, 0.574, 0.5790, 0.6, 0.6080, 0.63, 0.6506, 0.65, 0.6510, 0.6, 0.5942, 0.55, 0.5179, 0.5, 0.4388, 0.4, + 0.3682, 0.34, 0.3275, 0.31, 0.3009, 0.28, 0.2329, 0.1, 0.0832, 0.0, -0.0461, -0.1, -0.1142, -0.12, -0.1425, -0.15, -0.1531, -0.154, -0.1542, -0.15, -0.1490, -0.145, + -0.1449, -0.148, -0.1478, -0.15, -0.1529, -0.16, -0.1611, -0.165, -0.1661, -0.164, -0.1630, -0.16, -0.1522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_m8_m60spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0228, 0.03, 0.0416, 0.06, 0.0715, 0.1, 0.1422, 0.15, 0.1848, 0.2, 0.2159, 0.24, 0.2505, 0.26, 0.2709, 0.272, 0.2720, 0.27, 0.2693, 0.265, 0.2605, 0.25, 0.2450, 0.22, 0.2153, 0.2, 0.1709, 0.15, 0.1245, 0.1, 0.0821, 0.06, 0.0434, 0.02, 0.0065, 0.0, + -0.0251, -0.03, -0.0432, -0.045, -0.0497, -0.043, -0.0419, -0.02, -0.0173, 0.0, 0.0051, 0.01, 0.0174, 0.03, 0.0226, 0.0225, 0.0247, 0.025, 0.0275, 0.03, 0.0317, 0.032, + 0.0343, 0.034, 0.0338, 0.032, 0.0318, 0.03, 0.0282, 0.027, 0.0259, 0.027, 0.0274, 0.03, 0.0335, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L22_m8_m60spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0228, 0.03, 0.0416, 0.07, 0.0715, 0.1, 0.1422, 0.15, 0.1848, 0.2, 0.2159, 0.26, 0.2505, 0.26, 0.2709, 0.272, 0.2720, 0.27, 0.2693, 0.265, 0.2605, 0.25, 0.2450, 0.22, 0.2153, 0.2, 0.1709, 0.15, 0.1245, 0.1, 0.0821, 0.06, 0.0434, 0.02, 0.0065, 0.0, + -0.0251, -0.03, -0.0432, -0.045, -0.0497, -0.043, -0.0419, -0.025, -0.0173, 0.0, 0.0051, 0.01, 0.0174, 0.03, 0.0226, 0.0225, 0.0247, 0.025, 0.0275, 0.03, 0.0317, 0.032, + 0.0343, 0.034, 0.0338, 0.032, 0.0318, 0.03, 0.0292, 0.027, 0.0259, 0.027, 0.0274, 0.03, 0.0335, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_m4_m42spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0109, 0.015, 0.0194, 0.02, 0.0328, 0.05, 0.0647, 0.07, 0.0839, 0.09, 0.0978, 0.1, 0.1134, 0.12, 0.1225, 0.123, 0.123, 0.122, 0.1217, 0.12, 0.1177, 0.115, 0.1108, 0.1, 0.0982, 0.08, 0.0795, 0.06, 0.0595, 0.05, 0.0408, 0.03, 0.0236, 0.01, + 0.0072, 0.007, -0.0070, -0.01, -0.0151, -0.016, -0.0180, -0.015, -0.0141, -0.001, -0.0023, 0.0, 0.0084, 0.01, 0.0143, 0.015, 0.0168, 0.017, 0.0178, 0.018, 0.0191, 0.02, + 0.0210, 0.022, 0.0222, 0.022, 0.0220, 0.022, 0.0211, 0.02, 0.0195, 0.019, 0.0185, 0.019, 0.0191, 0.02, 0.0219, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L15_m4_m42spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0109, 0.015, 0.0184, 0.02, 0.0328, 0.05, 0.0647, 0.07, 0.0839, 0.09, 0.0978, 0.1, 0.1134, 0.12, 0.1325, 0.123, 0.123, 0.122, 0.1217, 0.12, 0.1177, 0.115, 0.1108, 0.1, 0.0982, 0.08, 0.0795, 0.06, 0.0595, 0.05, 0.0408, 0.03, 0.0236, 0.01, + 0.0072, 0.007, -0.0070, -0.01, -0.0151, -0.016, -0.0180, -0.025, -0.0141, -0.001, -0.0023, 0.0, 0.0084, 0.01, 0.0143, 0.015, 0.0168, 0.017, 0.0178, 0.018, 0.0191, 0.02, + 0.0210, 0.022, 0.0222, 0.022, 0.0220, 0.022, 0.0211, 0.02, 0.0195, 0.019, 0.0185, 0.019, 0.0191, 0.02, 0.0219, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L13_3_m23spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0064, 0.007, 0.0098, 0.01, 0.0153, 0.02, 0.0290, 0.03, 0.0372, 0.04, 0.0430, 0.045, 0.0495, 0.05, 0.0531, 0.0531, 0.0531, 0.053, 0.0523, 0.051, 0.0503, 0.05, 0.0475, 0.045, + 0.0433, 0.04, 0.0373, 0.031, 0.0303, 0.025, 0.0232, 0.02, 0.0164, 0.01, 0.0098, 0.005, 0.0039, 0.001, 0.0007, 0.0, -0.0004, 0.0, 0.0024, 0.01, 0.0101, 0.012, 0.0170, 0.02, 0.0208, 0.023, 0.0223, 0.023, 0.0230, 0.0231, 0.0237, 0.024, + 0.0246, 0.025, 0.0251, 0.025, 0.0250, 0.0248, 0.0247, 0.0245, 0.0240, 0.024, 0.0236, 0.0236, 0.0239, 0.024, 0.0251, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L27_4_m90spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0543, 0.08, 0.0957, 0.12, 0.1617, 0.25, 0.3197, 0.35, 0.4152, 0.45, 0.4840, 0.5, 0.5600, 0.6, 0.6032, 0.603, 0.6029, 0.6, 0.5940, 0.595, 0.5722, 0.55, 0.5340, 0.5, 0.4601, 0.4, 0.3492, 0.3, 0.2374, 0.15, 0.1408, 0.1, + 0.0549, 0.0, -0.0262, -0.05, -0.0957, -0.1, -0.1353, -0.14, -0.1485, -0.13, -0.1237, -0.1, -0.0512, 0.0, 0.0139, 0.04, 0.0497, 0.05, 0.0646, 0.07, 0.0706, 0.071, 0.0773, 0.08, + 0.0870, 0.09, 0.0929, 0.092, 0.0920, 0.09, 0.0876, 0.08, 0.0798, 0.077, 0.0747, 0.076, 0.0781, 0.08, 0.0916, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L19_1_m29spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0109, 0.015, 0.0175, 0.02, 0.0278, 0.04, 0.0531, 0.06, 0.0682, 0.07, 0.0791, 0.08, 0.0912, 0.095, 0.0982, 0.098, 0.0983, 0.098, 0.0971, 0.095, 0.0936, 0.09, 0.0886, 0.085, 0.0806, 0.07, 0.0692, 0.06, 0.0561, 0.05, 0.0427, 0.03, 0.0299, 0.02, 0.0174, 0.01, + 0.0064, 0.003, 0.0002, 0.0, -0.0018, 0.0, 0.0025, 0.01, 0.0148, 0.02, 0.0259, 0.03, 0.0320, 0.033, 0.0346, 0.035, 0.0357, 0.036, 0.0368, 0.037, 0.0384, 0.039, + 0.0394, 0.0393, 0.0392, 0.039, 0.0385, 0.038, 0.0373, 0.037, 0.0366, 0.037, 0.0371, 0.038, 0.0393, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L27_4_m90spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0543, 0.09, 0.0957, 0.12, 0.1617, 0.28, 0.3197, 0.35, 0.4152, 0.45, 0.4840, 0.53, 0.5600, 0.6, 0.6032, 0.603, 0.6029, 0.6, 0.5940, 0.595, 0.5722, 0.55, 0.5340, 0.5, 0.4601, 0.4, 0.3492, 0.3, 0.2374, 0.15, 0.1408, 0.1, + 0.0549, 0.0, -0.0262, -0.05, -0.0957, -0.1, -0.1353, -0.15, -0.1485, -0.13, -0.1237, -0.1, -0.0512, 0.0, 0.0139, 0.04, 0.0497, 0.05, 0.0646, 0.07, 0.0706, 0.071, 0.0773, 0.08, + 0.0870, 0.09, 0.0929, 0.092, 0.0920, 0.09, 0.0876, 0.08, 0.0798, 0.077, 0.0747, 0.076, 0.0781, 0.08, 0.0916, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L16_0_m44spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0128, 0.02, 0.0219, 0.03, 0.0364, 0.06, 0.0714, 0.08, 0.0924, 0.1, 0.1076, 0.11, 0.1244, 0.13, 0.1341, 0.1341, 0.1343, 0.133, 0.1325, 0.13, 0.1278, 0.125, 0.1200, 0.11, 0.1057, 0.1, 0.0845, 0.07, 0.0623, 0.05, 0.0419, 0.03, 0.0232, 0.01, + 0.0055, 0.0, -0.0099, -0.01, -0.0186, -0.02, -0.0216, -0.02, -0.0163, -0.01, -0.0009, 0.0, 0.0130, 0.02, 0.0207, 0.022, 0.0239, 0.024, 0.0252, 0.026, 0.0267, 0.027, + 0.0288, 0.03, 0.0301, 0.03, 0.0299, 0.029, 0.0290, 0.028, 0.0273, 0.027, 0.0261, 0.0265, 0.0269, 0.028, 0.0299, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L16_0_m44spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0128, 0.02, 0.0219, 0.03, 0.0384, 0.06, 0.0714, 0.08, 0.0924, 0.1, 0.1076, 0.11, 0.1244, 0.13, 0.1371, 0.1341, 0.1343, 0.133, 0.1325, 0.13, 0.1278, 0.125, 0.1200, 0.11, 0.1057, 0.1, 0.0845, 0.07, 0.0623, 0.05, 0.0419, 0.03, 0.0232, 0.01, + 0.0055, 0.0, -0.0099, -0.01, -0.0186, -0.02, -0.0216, -0.02, -0.0163, -0.01, -0.0009, 0.0, 0.0130, 0.02, 0.0207, 0.022, 0.0239, 0.024, 0.0252, 0.026, 0.0267, 0.027, + 0.0288, 0.03, 0.0301, 0.03, 0.0299, 0.029, 0.0290, 0.028, 0.0283, 0.027, 0.0261, 0.0265, 0.0269, 0.028, 0.0299, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L13_m3_m36spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0078, 0.01, 0.0136, 0.02, 0.0228, 0.03, 0.0448, 0.05, 0.0581, 0.06, 0.0677, 0.07, 0.0784, 0.08, 0.0847, 0.085, 0.0850, 0.085, 0.0841, 0.083, 0.0813, 0.08, 0.0767, 0.07, 0.0682, 0.06, 0.0556, 0.05, 0.0420, 0.03, 0.0293, 0.02, 0.0175, 0.01, + 0.0062, 0.0, -0.0036, -0.005, -0.0092, -0.01, -0.0112, -0.003, -0.0084, -0.0001, -0.0001, 0.0, 0.0075, 0.01, 0.0117, 0.012, 0.0135, 0.014, 0.0142, 0.015, 0.0151, 0.016, + 0.0164, 0.017, 0.0172, 0.0171, 0.0171, 0.017, 0.0165, 0.016, 0.0154, 0.015, 0.0147, 0.015, 0.0151, 0.016, 0.0170, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L13_m3_m36spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0078, 0.01, 0.0136, 0.03, 0.0228, 0.03, 0.0448, 0.05, 0.0581, 0.06, 0.0677, 0.07, 0.0794, 0.08, 0.0847, 0.089, 0.0850, 0.085, 0.0841, 0.083, 0.0813, 0.08, 0.0767, 0.07, 0.0682, 0.06, 0.0556, 0.05, 0.0420, 0.03, 0.0293, 0.02, 0.0175, 0.01, + 0.0062, 0.0, -0.0036, -0.005, -0.0092, -0.01, -0.0112, -0.003, -0.0084, -0.0001, -0.0001, 0.0, 0.0085, 0.01, 0.0117, 0.012, 0.0135, 0.014, 0.0142, 0.015, 0.0151, 0.016, + 0.0164, 0.017, 0.0172, 0.0171, 0.0171, 0.017, 0.0165, 0.016, 0.0154, 0.015, 0.0147, 0.015, 0.0151, 0.016, 0.0170, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L31_m23_m60spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0283, 0.04, 0.0551, 0.07, 0.0978, 0.12, 0.1970, 0.23, 0.2564, 0.28, 0.3006, 0.34, 0.3502, 0.37, 0.3806, 0.381, 0.3845, 0.383, 0.3832, 0.38, 0.3728, 0.36, 0.3536, 0.33, 0.3176, 0.3, 0.2634, 0.25, 0.2037, 0.17, 0.1453, 0.1, 0.0903, 0.05, + 0.0375, 0.0, -0.0080, -0.05, -0.0340, -0.04, -0.0443, -0.04, -0.0399, -0.03, -0.0206, -0.02, -0.0026, 0.0, 0.0076, 0.01, 0.0119, 0.012, 0.0137, 0.015, 0.0171, 0.02, 0.0228, 0.025, + 0.0265, 0.026, 0.0256, 0.023, 0.0226, 0.02, 0.0175, 0.016, 0.0142, 0.016, 0.0164, 0.02, 0.0248, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L31_m23_m60spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0283, 0.04, 0.0551, 0.08, 0.0978, 0.12, 0.1970, 0.23, 0.2564, 0.28, 0.3006, 0.34, 0.3802, 0.37, 0.3806, 0.381, 0.3845, 0.385, 0.3832, 0.38, 0.3728, 0.36, 0.3536, 0.33, 0.3176, 0.3, 0.2634, 0.25, 0.2037, 0.17, 0.1453, 0.1, 0.0903, 0.05, + 0.0375, 0.0, -0.0080, -0.05, -0.0340, -0.04, -0.0443, -0.04, -0.0399, -0.03, -0.0206, -0.02, -0.0026, 0.0, 0.0076, 0.01, 0.0119, 0.012, 0.0137, 0.015, 0.0171, 0.02, 0.0228, 0.025, + 0.0265, 0.026, 0.0256, 0.023, 0.0246, 0.02, 0.0175, 0.016, 0.0142, 0.016, 0.0164, 0.02, 0.0248, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L17_3_m40spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0341, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1228, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.01, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L17_3_m40spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0361, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1248, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.015, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L17_3_m40spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0341, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1228, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.01, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L17_3_m40spect4[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0361, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1248, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.015, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L17_3_m40spect5[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0361, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1248, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.015, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L17_3_m40spect6[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.02, 0.0210, 0.03, 0.0361, 0.05, 0.0660, 0.07, 0.0852, 0.09, 0.0990, 0.11, 0.1142, 0.12, 0.1229, 0.1248, 0.1228, 0.121, 0.1209, 0.12, 0.1164, 0.11, 0.1092, 0.1, 0.0964, 0.08, 0.0777, 0.06, 0.0578, 0.04, 0.0396, 0.03, 0.0229, 0.02, + 0.0069, 0.0, -0.0069, -0.01, -0.0148, -0.015, -0.0173, -0.015, -0.0116, 0.0, 0.0046, 0.015, 0.0191, 0.02, 0.0270, 0.03, 0.0304, 0.031, 0.0317, 0.032, 0.0332, 0.034, + 0.0352, 0.036, 0.0364, 0.0363, 0.0362, 0.036, 0.0353, 0.034, 0.0338, 0.033, 0.0328, 0.033, 0.0335, 0.035, 0.0362, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L21_9_m7spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0096, 0.01, 0.0122, 0.014, 0.0162, 0.02, 0.0277, 0.03, 0.0346, 0.035, 0.0391, 0.04, 0.0440, 0.045, 0.0464, 0.046, 0.0458, 0.045, 0.0443, 0.043, 0.0419, 0.041, 0.0400, 0.04, 0.0391, 0.039, 0.0389, 0.037, 0.0369, 0.035, 0.0330, 0.03, 0.0288, 0.025, 0.0243, 0.022, + 0.0201, 0.02, 0.0178, 0.0176, 0.0175, 0.02, 0.0227, 0.03, 0.0360, 0.04, 0.0477, 0.05, 0.0541, 0.055, 0.0568, 0.057, 0.0580, 0.058, 0.0589, 0.059, 0.0598, 0.06, 0.0602, 0.0602, 0.0602, 0.06, 0.0599, 0.0599, + 0.0595, 0.0595, 0.0592, 0.0594, 0.0594, 0.06, 0.0605, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L78_4_m74spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2087, 0.3, 0.3297, 0.4, 0.5205, 0.8, 0.9908, 1.1, 1.2731, 1.3, 1.4747, 1.6, 1.6992, 1.75, 1.8277, 1.82, 1.8300, 1.82, 1.8050, 1.75, 1.7397, 1.7, 1.6470, 1.6, 1.5025, 1.4, 1.2968, 1.1, 1.0577, 1.0, 0.8101, 0.8, 0.5740, 0.4, 0.3430, 0.25, + 0.1407, 0.05, 0.0264, 0.0, -0.0107, 0.0, 0.0733, 0.2, 0.3116, 0.4, 0.5251, 0.6, 0.6429, 0.65, 0.6923, 0.7, 0.7137, 0.72, 0.7360, 0.75, 0.7658, 0.77, 0.7831, 0.782, + 0.7804, 0.77, 0.7677, 0.75, 0.7455, 0.74, 0.7313, 0.74, 0.7406, 0.77, 0.7819, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L31_m58_m66spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0229, 0.04, 0.0549, 0.08, 0.1059, 0.15, 0.2207, 0.24, 0.2892, 0.3, 0.3414, 0.36, 0.4006, 0.42, 0.4386, 0.44, 0.4461, 0.445, 0.4480, 0.44, 0.4387, 0.442, 0.4182, 0.4, 0.3771, 0.35, 0.3139, 0.3, 0.2436, 0.2, 0.1736, 0.15, 0.1070, 0.07, + 0.0432, 0.0, -0.0114, -0.02, -0.0429, -0.05, -0.0567, -0.06, -0.0618, -0.063, -0.0637, -0.0637, -0.0639, -0.0635, -0.0635, -0.0634, -0.0632, -0.0632, -0.0632, 0.06, -0.0601, -0.06, -0.0539, -0.05, + -0.0497, 0.05, -0.0510, -0.054, -0.0546, -0.06, -0.0608, -0.062, -0.0649, -0.0622, -0.0622, -0.055, -0.0526, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L61_m11_m12spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0509, 0.06, 0.0770, 0.1, 0.1178, 0.2, 0.2177, 0.25, 0.2762, 0.3, 0.3194, 0.32, 0.3695, 0.37, 0.4016, 0.402, 0.4093, 0.41, 0.4106, 0.41, 0.4017, 0.4, 0.3957, 0.4, 0.4047, 0.41, 0.4237, 0.42, 0.4184, 0.4, 0.3820, 0.35, 0.3365, 0.3, 0.2881, 0.25, + 0.2436, 0.22, 0.2188, 0.21, 0.2086, 0.21, 0.2133, 0.22, 0.2323, 0.24, 0.2499, 0.25, 0.2605, 0.265, 0.2650, 0.266, 0.2679, 0.27, 0.2720, 0.275, 0.2783, 0.28, 0.2816, 0.281, + 0.2808, 0.28, 0.2779, 0.275, 0.2731, 0.271, 0.2702, 0.272, 0.2720, 0.28, 0.2811, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L61_m11_m12spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0509, 0.06, 0.0770, 0.1, 0.1578, 0.2, 0.2177, 0.25, 0.2762, 0.3, 0.3194, 0.32, 0.3695, 0.37, 0.4016, 0.402, 0.4093, 0.41, 0.4106, 0.41, 0.4017, 0.4, 0.3957, 0.4, 0.4047, 0.41, 0.4237, 0.42, 0.4184, 0.4, 0.3820, 0.35, 0.3365, 0.3, 0.2881, 0.25, + 0.2436, 0.22, 0.2188, 0.21, 0.2186, 0.21, 0.2133, 0.22, 0.2323, 0.24, 0.2499, 0.25, 0.2605, 0.265, 0.2650, 0.266, 0.2679, 0.27, 0.2720, 0.275, 0.2783, 0.28, 0.2816, 0.281, + 0.2808, 0.28, 0.2779, 0.275, 0.2831, 0.271, 0.2702, 0.272, 0.2720, 0.28, 0.2811, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L29_1_m13spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0147, 0.02, 0.0212, 0.03, 0.0313, 0.04, 0.0571, 0.06, 0.0724, 0.08, 0.0832, 0.09, 0.0955, 0.1, 0.1026, 0.102, 0.1031, 0.102, 0.1019, 0.1, 0.0985, 0.096, 0.0950, 0.094, 0.0930, 0.092, 0.0914, 0.09, 0.0855, 0.08, 0.0749, 0.07, 0.0634, 0.06, 0.0515, 0.05, + 0.0407, 0.04, 0.0346, 0.04, 0.0327, 0.033, 0.0377, 0.04, 0.0517, 0.06, 0.0642, 0.07, 0.0711, 0.072, 0.0740, 0.075, 0.0754, 0.076, 0.0768, 0.077, 0.0785, 0.079, 0.0794, 0.0793, + 0.0792, 0.079, 0.0786, 0.078, 0.0774, 0.077, 0.0767, 0.077, 0.0772, 0.078, 0.0795, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L29_1_m13spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0147, 0.02, 0.0212, 0.03, 0.0343, 0.04, 0.0571, 0.06, 0.0724, 0.08, 0.0832, 0.09, 0.0995, 0.1, 0.1026, 0.102, 0.1031, 0.102, 0.1019, 0.1, 0.0985, 0.096, 0.0950, 0.094, 0.0930, 0.092, 0.0914, 0.09, 0.0855, 0.08, 0.0749, 0.07, 0.0634, 0.06, 0.0515, 0.05, + 0.0407, 0.04, 0.0346, 0.04, 0.0327, 0.033, 0.0377, 0.04, 0.0517, 0.06, 0.0642, 0.07, 0.0711, 0.072, 0.0740, 0.075, 0.0754, 0.076, 0.0768, 0.077, 0.0785, 0.079, 0.0794, 0.0793, + 0.0792, 0.079, 0.0786, 0.078, 0.0794, 0.077, 0.0767, 0.077, 0.0772, 0.078, 0.0795, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L2_14_m1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0020, 0.002, 0.0021, 0.0021, 0.0022, 0.003, 0.0030, 0.0033, 0.0036, 0.0035, 0.0038, 0.0038, 0.0039, 0.0038, 0.0036, 0.0035, 0.0030, 0.003, 0.0024, 0.002, 0.0017, 0.0015, 0.0011, 0.001, 0.0004, 0.0, -0.0004, -0.001, -0.0010, -0.0011, -0.0012, -0.0011, -0.0011, -0.0011, -0.0011, -0.001, + -0.0011, -0.0011, -0.0011, -0.001, -0.0008, 0.0, 0.0012, 0.004, 0.0061, 0.01, 0.0104, 0.011, 0.0127, 0.013, 0.0136, 0.014, 0.0140, 0.0142, 0.0142, 0.0143, 0.0144, 0.0144, + 0.0144, 0.0144, 0.0144, 0.0145, 0.0145, 0.0145, 0.0145, 0.0145, 0.0145, 0.0145, 0.0145, 0.0145, 0.0146, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L5_39_m7spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0070, 0.007, 0.0072, 0.0075, 0.0076, 0.01, 0.0108, 0.011, 0.0129, 0.013, 0.0136, 0.014, 0.0140, 0.0135, 0.0131, 0.012, 0.0112, 0.01, 0.0088, 0.008, 0.0066, 0.005, 0.0046, 0.003, 0.0021, 0.0, -0.0009, -0.002, -0.0032, -0.003, + -0.0039, -0.0039, -0.0039, -0.004, -0.0040, -0.004, -0.0041, -0.0041, -0.0041, -0.0035, -0.0032, 0.0, 0.0038, 0.03, 0.0205, 0.03, 0.0351, 0.04, 0.0429, 0.045, 0.0462, 0.047, + 0.0476, 0.048, 0.0483, 0.0485, 0.0487, 0.0488, 0.0489, 0.049, 0.0490, 0.049, 0.0490, 0.049, 0.0491, 0.0491, 0.0491, 0.0491, 0.0491, 0.0492, 0.0494, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L15_5_m13spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0064, 0.007, 0.0089, 0.01, 0.0129, 0.02, 0.0233, 0.025, 0.0295, 0.03, 0.0338, 0.035, 0.0386, 0.04, 0.0411, 0.041, 0.0409, 0.04, 0.0400, 0.039, 0.0383, 0.037, 0.0364, 0.035, 0.0345, 0.033, 0.0321, 0.03, 0.0285, 0.025, 0.0240, 0.02, 0.0194, 0.015, 0.0148, 0.012, + 0.0106, 0.01, 0.0083, 0.008, 0.0077, 0.01, 0.0107, 0.015, 0.0188, 0.02, 0.0260, 0.027, 0.0299, 0.03, 0.0316, 0.032, 0.0323, 0.033, 0.0330, 0.033, 0.0337, 0.034, 0.0341, 0.034, + 0.0340, 0.034, 0.0338, 0.033, 0.0333, 0.033, 0.0330, 0.033, 0.0332, 0.034, 0.0342, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L12_5_m6spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0039, 0.004, 0.0052, 0.006, 0.0072, 0.01, 0.0127, 0.013, 0.0159, 0.016, 0.0181, 0.02, 0.0205, 0.021, 0.0218, 0.0217, 0.0217, 0.0215, 0.0212, 0.021, 0.0202, 0.02, 0.0194, 0.019, 0.0190, 0.019, 0.0187, 0.018, 0.0177, 0.016, 0.0157, 0.014, + 0.0135, 0.012, 0.0112, 0.01, 0.0091, 0.008, 0.0079, 0.0077, 0.0077, 0.008, 0.0096, 0.01, 0.0145, 0.015, 0.0189, 0.02, 0.0213, 0.021, 0.0223, 0.0222, 0.0227, 0.023, + 0.0231, 0.0231, 0.0235, 0.0236, 0.0237, 0.0237, 0.0237, 0.0236, 0.0235, 0.0233, 0.0233, 0.0232, 0.0233, 0.0233, 0.0235, 0.0238, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L12_5_m6spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0039, 0.004, 0.0062, 0.006, 0.0072, 0.01, 0.0147, 0.013, 0.0159, 0.016, 0.0181, 0.02, 0.0205, 0.021, 0.0218, 0.0257, 0.0217, 0.0215, 0.0212, 0.021, 0.0202, 0.02, 0.0194, 0.019, 0.0190, 0.019, 0.0187, 0.018, 0.0177, 0.016, 0.0157, 0.014, + 0.0135, 0.012, 0.0112, 0.01, 0.0099, 0.008, 0.0079, 0.0087, 0.0077, 0.008, 0.0096, 0.01, 0.0145, 0.015, 0.0189, 0.02, 0.0213, 0.021, 0.0223, 0.0222, 0.0227, 0.023, + 0.0231, 0.0231, 0.0235, 0.0236, 0.0237, 0.0237, 0.0237, 0.0236, 0.0235, 0.0233, 0.0233, 0.0232, 0.0233, 0.0233, 0.0235, 0.0238, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L37_m59_m24spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0007, 0.01, 0.0162, 0.03, 0.0407, 0.06, 0.0911, 0.1, 0.1203, 0.13, 0.1448, 0.16, 0.1741, 0.18, 0.1965, 0.2, 0.2068, 0.21, 0.2149, 0.215, 0.2165, 0.216, 0.2159, 0.216, 0.2165, 0.2165, 0.2165, 0.21, 0.2046, 0.19, 0.1781, 0.16, 0.1472, 0.13, 0.1161, 0.1, + 0.0889, 0.08, 0.0732, 0.07, 0.0636, 0.05, 0.0426, 0.0, -0.0029, -0.02, -0.0419, -0.05, -0.0625, -0.07, -0.0711, -0.073, -0.0743, -0.074, -0.0744, -0.073, -0.0722, -0.071, + -0.0705, -0.071, -0.0715, -0.072, -0.0735, -0.075, -0.0766, -0.077, -0.0786, -0.078, -0.0773, -0.074, -0.0731, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_L37_m59_m24spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0007, 0.01, 0.0162, 0.03, 0.0427, 0.06, 0.0911, 0.1, 0.1203, 0.13, 0.1548, 0.16, 0.1741, 0.18, 0.1965, 0.2, 0.2068, 0.24, 0.2149, 0.215, 0.2165, 0.216, 0.2159, 0.216, 0.2165, 0.2165, 0.2165, 0.21, 0.2046, 0.19, 0.1781, 0.16, 0.1472, 0.13, 0.1161, 0.1, + 0.0889, 0.08, 0.0732, 0.07, 0.0636, 0.05, 0.0426, 0.0, -0.0029, -0.02, -0.0429, -0.05, -0.0625, -0.07, -0.0711, -0.073, -0.0743, -0.074, -0.0744, -0.073, -0.0722, -0.071, + -0.0705, -0.071, -0.0715, -0.072, -0.0735, -0.075, -0.0766, -0.077, -0.0786, -0.078, -0.0773, -0.074, -0.0731, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_55_23spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0184, 0.017, 0.0169, 0.015, 0.0143, 0.015, 0.0153, 0.016, 0.0164, 0.015, 0.0147, 0.013, 0.0119, 0.01, 0.0070, 0.005, 0.0012, 0.0, -0.0052, -0.01, -0.0106, -0.012, -0.0143, -0.015, -0.0166, -0.016, -0.0177, -0.017, -0.0169, -0.015, + -0.0134, -0.01, -0.0085, -0.005, -0.0041, -0.0008, -0.0008, 0.0, 0.0014, 0.002, 0.0049, 0.02, 0.0244, 0.05, 0.0701, 0.1, 0.1100, 0.12, 0.1315, 0.14, 0.1405, 0.142, 0.1443, 0.145, + 0.1461, 0.1463, 0.1469, 0.1469, 0.1469, 0.148, 0.1474, 0.1476, 0.1478, 0.148, 0.1483, 0.1485, 0.1486, 0.1486, 0.1484, 0.1485, 0.1487, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L11_m55_m11spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0164, 0.017, 0.0170, 0.017, 0.0179, 0.02, 0.0254, 0.03, 0.0304, 0.0302, 0.0321, 0.031, 0.0331, 0.032, 0.0310, 0.03, 0.0264, 0.025, 0.0209, 0.02, 0.0156, 0.0120, 0.0108, 0.01, 0.0048, 0.0, -0.0025, -0.005, -0.0079, -0.008, -0.0098, -0.0098, -0.0098, -0.0098, -0.0099, -0.01, + -0.0103, -0.0102, -0.0102, -0.01, -0.0080, 0.0, 0.0084, 0.02, 0.0478, 0.06, 0.0823, 0.09, 0.1008, 0.105, 0.1086, 0.11, 0.1118, 0.112, 0.1135, 0.114, 0.1145, 0.1146, 0.1148, 0.115, + 0.1152, 0.1152, 0.1153, 0.1153, 0.1153, 0.1153, 0.1154, 0.1154, 0.1154, 0.116, 0.1162, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L8_m10_m2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0006, 0.001, 0.0013, 0.002, 0.0025, 0.004, 0.0050, 0.0055, 0.0064, 0.007, 0.0076, 0.008, 0.0090, 0.01, 0.0101, 0.0102, 0.0106, 0.011, 0.0111, 0.0111, 0.0111, 0.0112, 0.0113, 0.012, 0.0122, 0.013, 0.0135, 0.014, 0.0140, 0.014, + 0.0131, 0.012, 0.0118, 0.011, 0.0104, 0.01, 0.0091, 0.009, 0.0083, 0.008, 0.0079, 0.0075, 0.0070, 0.006, 0.0050, 0.004, 0.0033, 0.003, 0.0024, 0.0022, 0.0021, 0.002, 0.0019, 0.002, 0.0020, 0.002, 0.0021, 0.0022, 0.0022, 0.0021, + 0.0021, 0.002, 0.0020, 0.002, 0.0019, 0.0018, 0.0018, 0.0018, 0.0018, 0.0019, 0.0021, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L14_m10_m7spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0023, 0.003, 0.0042, 0.006, 0.0071, 0.01, 0.0139, 0.015, 0.0179, 0.02, 0.0209, 0.022, 0.0245, 0.026, 0.0270, 0.0275, 0.0278, 0.028, 0.0283, 0.028, 0.0280, 0.028, 0.0277, 0.028, 0.0282, 0.029, 0.0293, 0.029, 0.0286, 0.027, 0.0258, 0.024, 0.0224, 0.02, + 0.0188, 0.017, 0.0156, 0.014, 0.0137, 0.013, 0.0128, 0.0125, 0.0120, 0.011, 0.0107, 0.01, 0.0096, 0.0094, 0.0091, 0.009, 0.0089, 0.0089, 0.0089, 0.009, 0.0091, 0.0092, 0.0095, 0.0095, + 0.0097, 0.0096, 0.0096, 0.0095, 0.0094, 0.0093, 0.0090, 0.009, 0.0088, 0.0089, 0.0089, 0.009, 0.0095, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_m16_m13spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0039, 0.005, 0.0080, 0.01, 0.0144, 0.02, 0.0290, 0.03, 0.0375, 0.04, 0.0442, 0.05, 0.0519, 0.054, 0.0573, 0.058, 0.0591, 0.06, 0.0600, 0.06, 0.0594, 0.059, 0.0584, 0.058, 0.0579, 0.0578, 0.0575, 0.056, 0.0540, 0.05, 0.0471, 0.04, + 0.0393, 0.035, 0.0313, 0.03, 0.0242, 0.022, 0.0202, 0.02, 0.0182, 0.017, 0.0161, 0.014, 0.0125, 0.01, 0.0095, 0.009, 0.0081, 0.008, 0.0075, 0.0074, 0.0073, 0.0075, + 0.0076, 0.008, 0.0084, 0.0087, 0.0089, 0.0088, 0.0087, 0.0085, 0.0082, 0.008, 0.0074, 0.007, 0.0069, 0.007, 0.0073, 0.008, 0.0085, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L8_m10_m2spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0006, 0.001, 0.0013, 0.003, 0.0025, 0.004, 0.0050, 0.0055, 0.0064, 0.007, 0.0076, 0.009, 0.0090, 0.01, 0.0101, 0.0102, 0.0106, 0.012, 0.0111, 0.0111, 0.0121, 0.0122, 0.0113, 0.012, 0.0122, 0.013, 0.0135, 0.014, 0.0140, 0.014, + 0.0131, 0.012, 0.0128, 0.011, 0.0114, 0.01, 0.0091, 0.009, 0.0083, 0.008, 0.0079, 0.0075, 0.0070, 0.006, 0.0050, 0.004, 0.0033, 0.003, 0.0024, 0.0022, 0.0021, 0.002, 0.0019, 0.002, 0.0020, 0.002, 0.0021, 0.0022, 0.0022, 0.0021, + 0.0021, 0.002, 0.0020, 0.002, 0.0019, 0.0018, 0.0018, 0.0018, 0.0018, 0.0019, 0.0021, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L14_m10_m7spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0023, 0.003, 0.0042, 0.006, 0.0091, 0.01, 0.0149, 0.015, 0.0179, 0.02, 0.0209, 0.022, 0.0265, 0.026, 0.0270, 0.0275, 0.0278, 0.028, 0.0293, 0.028, 0.0280, 0.029, 0.0277, 0.028, 0.0282, 0.029, 0.0293, 0.029, 0.0286, 0.027, 0.0258, 0.024, 0.0224, 0.02, + 0.0198, 0.017, 0.0156, 0.014, 0.0137, 0.013, 0.0128, 0.0125, 0.0120, 0.011, 0.0107, 0.01, 0.0096, 0.0094, 0.0091, 0.009, 0.0089, 0.0089, 0.0089, 0.009, 0.0091, 0.0092, 0.0095, 0.0095, + 0.0097, 0.0096, 0.0096, 0.0095, 0.0094, 0.0093, 0.0090, 0.009, 0.0088, 0.0089, 0.0089, 0.009, 0.0095, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_m16_m13spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0039, 0.005, 0.0080, 0.01, 0.0144, 0.02, 0.0290, 0.03, 0.0375, 0.04, 0.0442, 0.05, 0.0519, 0.054, 0.0573, 0.06, 0.0591, 0.06, 0.0600, 0.06, 0.0654, 0.065, 0.0654, 0.065, 0.0659, 0.0578, 0.0575, 0.056, 0.0540, 0.05, 0.0471, 0.04, + 0.0393, 0.035, 0.0313, 0.03, 0.0242, 0.022, 0.0202, 0.02, 0.0182, 0.017, 0.0161, 0.014, 0.0125, 0.01, 0.0095, 0.009, 0.0081, 0.008, 0.0075, 0.0074, 0.0073, 0.0075, + 0.0076, 0.008, 0.0084, 0.0087, 0.0089, 0.0088, 0.0087, 0.0085, 0.0082, 0.008, 0.0074, 0.007, 0.0069, 0.007, 0.0073, 0.008, 0.0085, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L6_m9_1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0002, 0.0005, 0.0007, 0.001, 0.0014, 0.002, 0.0030, 0.0035, 0.0039, 0.004, 0.0046, 0.005, 0.0056, 0.006, 0.0064, 0.0064, 0.0069, 0.007, 0.0073, 0.0073, 0.0074, 0.0076, 0.0077, 0.008, 0.0087, 0.009, 0.0101, 0.0102, 0.0108, 0.011, + 0.0103, 0.01, 0.0095, 0.009, 0.0085, 0.008, 0.0076, 0.0075, 0.0071, 0.007, 0.0068, 0.006, 0.0058, 0.004, 0.0037, 0.002, 0.0018, 0.001, 0.0008, 0.0006, 0.0004, 0.0004, + 0.0003, 0.0003, 0.0003, 0.0003, 0.0003, 0.0004, 0.0004, 0.0004, 0.0004, 0.0003, 0.0003, 0.0003, 0.0002, 0.0002, 0.0001, 0.0001, 0.0002, 0.0002, 0.0003, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_m9_m10spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0050, 0.006, 0.0084, 0.01, 0.0139, 0.02, 0.0266, 0.03, 0.0342, 0.035, 0.0398, 0.04, 0.0464, 0.05, 0.0507, 0.052, 0.0518, 0.052, 0.0522, 0.052, 0.0513, 0.051, 0.0503, 0.0502, 0.0502, 0.0503, 0.0504, 0.05, 0.0480, 0.048, 0.0425, 0.04, 0.0361, 0.03, + 0.0296, 0.025, 0.0236, 0.022, 0.0203, 0.02, 0.0188, 0.0185, 0.0185, 0.0188, 0.0188, 0.019, 0.0191, 0.0195, 0.0195, 0.0195, 0.0196, 0.0197, 0.0198, 0.02, 0.0202, 0.0205, + 0.0209, 0.021, 0.0214, 0.0214, 0.0213, 0.021, 0.0209, 0.0205, 0.0202, 0.02, 0.0198, 0.02, 0.0201, 0.021, 0.0212, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L85_10_45spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1141, 0.12, 0.1230, 0.13, 0.1346, 0.16, 0.1906, 0.2, 0.2220, 0.23, 0.2391, 0.25, 0.2598, 0.26, 0.2687, 0.267, 0.2673, 0.26, 0.2587, 0.25, 0.2448, 0.25, 0.2597, 0.3, 0.3501, 0.4, 0.5052, 0.55, 0.6139, 0.63, 0.6472, 0.65, + 0.6535, 0.65, 0.6470, 0.64, 0.6334, 0.63, 0.6279, 0.63, 0.6307, 0.66, 0.6778, 0.7, 0.7914, 0.82, 0.8909, 0.9, 0.9462, 0.95, 0.9695, 0.97, 0.9817, 0.982, + 0.9893, 0.99, 0.9956, 0.996, 0.9969, 0.997, 0.9975, 0.997, 0.9969, 0.9965, 0.9962, 0.9963, 0.9963, 0.9962, 0.9962, 1.0, 1.0030, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L90_m7_82spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0733, 0.073, 0.0730, 0.07, 0.0698, 0.07, 0.0777, 0.0777, 0.0779, 0.078, 0.0780, 0.08, 0.0835, 0.09, 0.0925, 0.1, 0.1077, 0.11, 0.1187, 0.12, 0.1248, 0.15, 0.1700, 0.25, 0.3233, 0.4, 0.5715, 0.65, 0.7545, 0.8, 0.8254, 0.84, 0.8529, 0.86, 0.8634, 0.864, 0.8632, 0.864, + 0.8651, 0.864, 0.8637, 0.86, 0.8584, 0.85, 0.8439, 0.84, 0.8309, 0.83, 0.8259, 0.825, 0.8241, 0.824, 0.8265, 0.827, 0.8286, 0.83, 0.8306, 0.83, 0.8299, 0.829, + 0.8296, 0.8296, 0.8296, 0.83, 0.8301, 0.831, 0.8314, 0.831, 0.8305, 0.832, 0.8331, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L95_2_18spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1508, 0.16, 0.1879, 0.2, 0.2437, 0.3, 0.4029, 0.45, 0.4951, 0.52, 0.5582, 0.6, 0.6321, 0.65, 0.6760, 0.68, 0.6838, 0.68, 0.6784, 0.66, 0.6570, 0.66, 0.6625, 0.7, 0.7471, 0.8, 0.8962, 0.9, 0.9795, 0.97, 0.9654, 0.95, 0.9187, 0.9, + 0.8583, 0.8, 0.7967, 0.78, 0.7639, 0.76, 0.7546, 0.77, 0.7979, 0.85, 0.9113, 1.0, 1.0117, 1.04, 1.0684, 1.08, 1.0924, 1.1, 1.1055, 1.11, 1.1164, 1.12, 1.1286, 1.13, + 1.1336, 1.133, 1.1330, 1.13, 1.1293, 1.125, 1.1232, 1.122, 1.1200, 1.121, 1.1220, 1.13, 1.1380, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_7_4spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0233, 0.025, 0.0285, 0.03, 0.0364, 0.04, 0.0599, 0.065, 0.0737, 0.08, 0.0827, 0.09, 0.0929, 0.095, 0.0982, 0.098, 0.0978, 0.096, 0.0954, 0.094, 0.0910, 0.09, 0.0896, 0.093, 0.0965, 0.1, 0.1100, 0.112, 0.1163, 0.113, 0.1124, 0.11, 0.1055, 0.1, 0.0970, 0.09, + 0.0885, 0.086, 0.0840, 0.084, 0.0834, 0.09, 0.0936, 0.1, 0.1194, 0.13, 0.1421, 0.15, 0.1547, 0.157, 0.1600, 0.162, 0.1625, 0.163, 0.1644, 0.165, 0.1663, 0.167, 0.1671, 0.1671, + 0.1671, 0.167, 0.1666, 0.166, 0.1658, 0.1656, 0.1653, 0.1655, 0.1656, 0.167, 0.1679, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_4_1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0226, 0.025, 0.0290, 0.03, 0.0386, 0.05, 0.0656, 0.07, 0.0815, 0.09, 0.0923, 0.1, 0.1046, 0.11, 0.1114, 0.1113, 0.1116, 0.11, 0.1098, 0.108, 0.1056, 0.104, 0.1038, 0.108, 0.1097, 0.11, 0.1214, 0.123, 0.1256, 0.12, 0.1193, 0.115, + 0.1100, 0.1, 0.0992, 0.09, 0.0888, 0.085, 0.0831, 0.082, 0.0817, 0.085, 0.0903, 0.1, 0.1126, 0.12, 0.1324, 0.135, 0.1434, 0.145, 0.1480, 0.15, 0.1503, 0.152, 0.1521, 0.153, + 0.1541, 0.155, 0.1550, 0.155, 0.1549, 0.1545, 0.1543, 0.154, 0.1533, 0.153, 0.1527, 0.153, 0.1531, 0.154, 0.1557, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_3_m1spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0221, 0.025, 0.0288, 0.03, 0.0392, 0.05, 0.0673, 0.07, 0.0839, 0.09, 0.0953, 0.1, 0.1083, 0.11, 0.1158, 0.116, 0.1163, 0.115, 0.1147, 0.112, 0.1105, 0.11, 0.1087, 0.11, 0.1140, 0.12, 0.1248, 0.125, 0.1279, 0.125, 0.1207, 0.115, 0.1104, 0.1, 0.0988, 0.09, 0.0876, 0.085, 0.0816, 0.08, 0.0799, 0.08, + 0.0877, 0.09, 0.1083, 0.11, 0.1265, 0.13, 0.1367, 0.14, 0.1410, 0.142, 0.1431, 0.144, 0.1449, 0.146, 0.1470, 0.1474, 0.1479, 0.1478, 0.1478, 0.1475, 0.1472, 0.147, 0.1460, 0.146, 0.1454, 0.1456, 0.1458, 0.147, 0.1485, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_3_m2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0242, 0.03, 0.0316, 0.035, 0.0430, 0.06, 0.0740, 0.08, 0.0923, 0.1, 0.1049, 0.11, 0.1192, 0.12, 0.1272, 0.1275, 0.1275, 0.126, 0.1256, 0.124, 0.1208, 0.12, 0.1184, 0.12, 0.1232, 0.13, 0.1333, 0.134, 0.1355, 0.13, 0.1272, 0.12, + 0.1157, 0.11, 0.1029, 0.1, 0.0906, 0.09, 0.0840, 0.083, 0.0822, 0.09, 0.0913, 0.1, 0.1150, 0.12, 0.1360, 0.14, 0.1477, 0.15, 0.1526, 0.154, 0.1550, 0.156, 0.1570, 0.158, + 0.1593, 0.16, 0.1603, 0.1602, 0.1602, 0.16, 0.1595, 0.1594, 0.1582, 0.158, 0.1575, 0.158, 0.1580, 0.159, 0.1609, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_2_2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0173, 0.02, 0.0222, 0.025, 0.0296, 0.04, 0.0501, 0.055, 0.0621, 0.07, 0.0704, 0.075, 0.0798, 0.08, 0.0852, 0.085, 0.0856, 0.085, 0.0845, 0.083, 0.0815, 0.081, 0.0806, 0.084, 0.0864, 0.09, 0.0975, 0.1, 0.1021, 0.1, 0.0979, 0.095, + 0.0909, 0.09, 0.0827, 0.08, 0.0747, 0.073, 0.0703, 0.07, 0.0692, 0.07, 0.0752, 0.08, 0.0908, 0.1, 0.1046, 0.11, 0.1124, 0.113, 0.1156, 0.116, 0.1173, 0.118, 0.1187, 0.123, + 0.1202, 0.1205, 0.1209, 0.1208, 0.1208, 0.1205, 0.1203, 0.12, 0.1195, 0.1194, 0.1191, 0.1193, 0.1194, 0.12, 0.1213, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_7_4spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0233, 0.028, 0.0285, 0.03, 0.0364, 0.04, 0.0599, 0.065, 0.0737, 0.08, 0.0927, 0.09, 0.0929, 0.095, 0.0982, 0.098, 0.0978, 0.096, 0.0954, 0.094, 0.0910, 0.09, 0.0896, 0.093, 0.0965, 0.1, 0.1100, 0.112, 0.1163, 0.113, 0.1124, 0.11, 0.1055, 0.1, 0.0970, 0.09, + 0.0885, 0.086, 0.0840, 0.084, 0.0834, 0.09, 0.0936, 0.1, 0.1294, 0.15, 0.1521, 0.17, 0.1647, 0.167, 0.1600, 0.162, 0.1625, 0.163, 0.1644, 0.165, 0.1663, 0.167, 0.1671, 0.1671, + 0.1671, 0.167, 0.1666, 0.166, 0.1658, 0.1656, 0.1653, 0.1655, 0.1656, 0.167, 0.1679, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_4_1spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0226, 0.025, 0.0290, 0.035, 0.0386, 0.05, 0.0656, 0.07, 0.0855, 0.09, 0.0923, 0.105, 0.1046, 0.11, 0.1114, 0.1113, 0.1216, 0.13, 0.1298, 0.118, 0.1056, 0.104, 0.1038, 0.108, 0.1097, 0.11, 0.1214, 0.123, 0.1256, 0.12, 0.1193, 0.115, + 0.1100, 0.1, 0.0992, 0.09, 0.0888, 0.085, 0.0831, 0.082, 0.0817, 0.085, 0.0903, 0.1, 0.1126, 0.12, 0.1324, 0.135, 0.1434, 0.145, 0.1480, 0.15, 0.1503, 0.152, 0.1521, 0.153, + 0.1541, 0.155, 0.1550, 0.155, 0.1549, 0.1545, 0.1543, 0.154, 0.1533, 0.153, 0.1527, 0.153, 0.1531, 0.154, 0.1557, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L39_3_m1spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0221, 0.025, 0.0288, 0.03, 0.0392, 0.05, 0.0693, 0.07, 0.0839, 0.09, 0.0953, 0.1, 0.1083, 0.11, 0.1258, 0.126, 0.1263, 0.125, 0.1247, 0.122, 0.1205, 0.11, 0.1087, 0.11, 0.1140, 0.12, 0.1248, 0.125, 0.1279, 0.125, 0.1207, 0.115, 0.1104, 0.1, 0.0988, 0.09, 0.0876, 0.085, 0.0816, 0.08, 0.0799, 0.08, + 0.0877, 0.09, 0.1083, 0.11, 0.1265, 0.13, 0.1367, 0.14, 0.1410, 0.142, 0.1431, 0.144, 0.1449, 0.146, 0.1470, 0.1474, 0.1479, 0.1478, 0.1478, 0.1475, 0.1472, 0.147, 0.1460, 0.146, 0.1454, 0.1456, 0.1458, 0.147, 0.1485, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_3_m2spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0242, 0.03, 0.0316, 0.035, 0.0430, 0.06, 0.080, 0.088, 0.0923, 0.1, 0.1049, 0.11, 0.1192, 0.12, 0.1372, 0.1375, 0.1375, 0.136, 0.1356, 0.134, 0.1308, 0.13, 0.1284, 0.12, 0.1232, 0.13, 0.1333, 0.134, 0.1355, 0.13, 0.1272, 0.12, + 0.1157, 0.11, 0.1029, 0.1, 0.0906, 0.09, 0.0840, 0.083, 0.0822, 0.09, 0.0913, 0.1, 0.1150, 0.12, 0.1360, 0.14, 0.1477, 0.15, 0.1526, 0.154, 0.1550, 0.156, 0.1570, 0.158, + 0.1593, 0.16, 0.1603, 0.1602, 0.1602, 0.16, 0.1595, 0.1594, 0.1582, 0.158, 0.1575, 0.158, 0.1580, 0.159, 0.1609, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L36_2_2spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0173, 0.02, 0.0222, 0.025, 0.0296, 0.05, 0.0501, 0.055, 0.0621, 0.07, 0.0704, 0.075, 0.0798, 0.08, 0.0852, 0.085, 0.0856, 0.095, 0.0945, 0.083, 0.0815, 0.081, 0.0806, 0.084, 0.0864, 0.09, 0.0975, 0.1, 0.1021, 0.1, 0.0979, 0.095, + 0.0909, 0.09, 0.0827, 0.08, 0.0747, 0.073, 0.0703, 0.07, 0.0692, 0.07, 0.0752, 0.08, 0.0908, 0.11, 0.1146, 0.12, 0.1224, 0.123, 0.1256, 0.126, 0.1273, 0.128, 0.1287, 0.123, + 0.1202, 0.1205, 0.1209, 0.1208, 0.1208, 0.1205, 0.1203, 0.12, 0.1195, 0.1194, 0.1191, 0.1193, 0.1194, 0.12, 0.1213, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_4_m2spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0248, 0.03, 0.0323, 0.04, 0.0437, 0.06, 0.0752, 0.08, 0.0937, 0.1, 0.1064, 0.11, 0.1208, 0.124, 0.1289, 0.129, 0.1292, 0.128, 0.1271, 0.125, 0.1222, 0.12, 0.1197, 0.12, 0.1246, 0.13, 0.1350, 0.136, 0.1373, 0.13, 0.1289, 0.12, 0.1174, 0.11, + 0.1045, 0.1, 0.0921, 0.09, 0.0854, 0.084, 0.0837, 0.09, 0.0931, 0.1, 0.1177, 0.12, 0.1396, 0.14, 0.1517, 0.153, 0.1568, 0.158, 0.1593, 0.16, 0.1613, 0.162, 0.1636, 0.164, + 0.1647, 0.1646, 0.1646, 0.164, 0.1639, 0.163, 0.1626, 0.162, 0.1619, 0.162, 0.1624, 0.164, 0.1654, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_1_m6spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0259, 0.03, 0.0352, 0.04, 0.0494, 0.07, 0.0872, 0.1, 0.1094, 0.11, 0.1250, 0.13, 0.1427, 0.15, 0.1530, 0.153, 0.1539, 0.153, 0.1522, 0.15, 0.1470, 0.145, 0.1436, 0.145, 0.1469, 0.15, 0.1549, 0.155, 0.1541, 0.15, 0.1421, 0.13, 0.1269, 0.12, + 0.1105, 0.1, 0.0951, 0.09, 0.0866, 0.085, 0.0840, 0.09, 0.0926, 0.1, 0.1159, 0.12, 0.1366, 0.14, 0.1482, 0.15, 0.1531, 0.154, 0.1555, 0.156, 0.1577, 0.16, 0.1603, 0.161, + 0.1616, 0.1615, 0.1614, 0.161, 0.1605, 0.16, 0.1588, 0.158, 0.1579, 0.158, 0.1585, 0.16, 0.1620, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_4_m2spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0248, 0.03, 0.0323, 0.04, 0.0437, 0.06, 0.0752, 0.08, 0.0937, 0.1, 0.1064, 0.11, 0.1208, 0.134, 0.1389, 0.139, 0.1292, 0.128, 0.1271, 0.125, 0.1222, 0.12, 0.1197, 0.12, 0.1246, 0.13, 0.1350, 0.136, 0.1373, 0.13, 0.1289, 0.12, 0.1174, 0.11, + 0.1145, 0.12, 0.0921, 0.09, 0.0854, 0.084, 0.0837, 0.09, 0.0931, 0.1, 0.1177, 0.12, 0.1396, 0.14, 0.1517, 0.153, 0.1568, 0.158, 0.1593, 0.16, 0.1613, 0.162, 0.1636, 0.164, + 0.1647, 0.1646, 0.1646, 0.164, 0.1639, 0.163, 0.1626, 0.162, 0.1619, 0.162, 0.1624, 0.164, 0.1654, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_1_m6spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0259, 0.03, 0.0352, 0.04, 0.0494, 0.07, 0.0872, 0.1, 0.1194, 0.12, 0.1350, 0.14, 0.1527, 0.15, 0.1530, 0.153, 0.1539, 0.153, 0.1522, 0.15, 0.1470, 0.145, 0.1436, 0.145, 0.1469, 0.15, 0.1549, 0.155, 0.1541, 0.15, 0.1421, 0.13, 0.1269, 0.12, + 0.1105, 0.1, 0.0951, 0.09, 0.0866, 0.085, 0.0840, 0.09, 0.0926, 0.1, 0.1259, 0.13, 0.1366, 0.14, 0.1482, 0.15, 0.1531, 0.154, 0.1555, 0.156, 0.1577, 0.16, 0.1603, 0.161, + 0.1616, 0.1615, 0.1614, 0.161, 0.1605, 0.16, 0.1588, 0.158, 0.1579, 0.158, 0.1585, 0.16, 0.1620, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_12_14spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0272, 0.03, 0.0306, 0.033, 0.0354, 0.04, 0.0536, 0.06, 0.0644, 0.07, 0.0705, 0.074, 0.0774, 0.078, 0.0799, 0.079, 0.0780, 0.075, 0.0744, 0.07, 0.0694, 0.069, 0.0688, 0.07, 0.0795, 0.09, 0.0995, 0.1, 0.1121, 0.113, 0.1134, 0.112, + 0.1112, 0.11, 0.1069, 0.105, 0.1018, 0.1, 0.0993, 0.1, 0.1001, 0.11, 0.1147, 0.13, 0.1503, 0.16, 0.1815, 0.19, 0.1986, 0.2, 0.2058, 0.206, 0.2093, 0.21, 0.2114, 0.212, + 0.2132, 0.2134, 0.2137, 0.2139, 0.2139, 0.2138, 0.2137, 0.2134, 0.2133, 0.2132, 0.2131, 0.2132, 0.2132, 0.214, 0.2152, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L41_12_14spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0272, 0.03, 0.0306, 0.035, 0.0354, 0.04, 0.0536, 0.06, 0.0644, 0.07, 0.0705, 0.074, 0.0774, 0.078, 0.0799, 0.079, 0.0780, 0.075, 0.0744, 0.07, 0.0694, 0.069, 0.0688, 0.07, 0.0795, 0.09, 0.0995, 0.1, 0.1121, 0.113, 0.1134, 0.112, + 0.1112, 0.11, 0.1069, 0.105, 0.1018, 0.1, 0.0993, 0.11, 0.1101, 0.12, 0.1147, 0.13, 0.1503, 0.16, 0.1815, 0.19, 0.1986, 0.2, 0.2058, 0.206, 0.2093, 0.21, 0.2114, 0.212, + 0.2132, 0.2134, 0.2137, 0.2239, 0.2139, 0.2158, 0.2237, 0.2234, 0.2133, 0.2132, 0.2131, 0.2132, 0.2132, 0.214, 0.2152, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L10_0_m22spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0048, 0.006, 0.0077, 0.009, 0.0124, 0.015, 0.0238, 0.025, 0.0306, 0.033, 0.0356, 0.04, 0.0410, 0.042, 0.0442, 0.0443, 0.0443, 0.044, 0.0438, 0.043, 0.0422, 0.041, 0.0400, 0.038, 0.0363, 0.035, 0.0310, 0.03, 0.0250, 0.02, 0.0188, 0.015, 0.0130, 0.01, + 0.0073, 0.005, 0.0024, 0.0, -0.0004, -0.0005, -0.0014, 0.0, 0.0004, 0.001, 0.0057, 0.01, 0.0104, 0.012, 0.0130, 0.013, 0.0141, 0.0144, 0.0146, 0.015, 0.0151, 0.0155, + 0.0158, 0.016, 0.0162, 0.0162, 0.0161, 0.016, 0.0158, 0.0155, 0.0153, 0.015, 0.0149, 0.015, 0.0152, 0.016, 0.0162, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L38_60_8spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0621, 0.0625, 0.0627, 0.0627, 0.0627, 0.07, 0.0842, 0.09, 0.0982, 0.1, 0.1014, 0.102, 0.1024, 0.1, 0.0937, 0.08, 0.0780, 0.07, 0.0591, 0.05, 0.0416, 0.03, 0.0288, 0.025, 0.0210, 0.02, 0.0170, 0.016, 0.0150, 0.016, 0.0173, 0.02, 0.0226, 0.025, + 0.0263, 0.027, 0.0279, 0.029, 0.0298, 0.03, 0.0382, 0.07, 0.0962, 0.12, 0.2343, 0.3, 0.3551, 0.4, 0.4203, 0.43, 0.4476, 0.45, 0.4592, 0.46, 0.4651, 0.466, 0.4686, 0.469, + 0.4694, 0.48, 0.4706, 0.471, 0.4711, 0.4712, 0.4717, 0.472, 0.4721, 0.472, 0.4719, 0.473, 0.4745, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L49_85_39spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1217, 0.12, 0.1146, 0.11, 0.1016, 0.11, 0.1161, 0.12, 0.1275, 0.123, 0.1207, 0.11, 0.1072, 0.09, 0.0793, 0.06, 0.0447, 0.05, 0.0051, 0.0, -0.0289, -0.03, -0.0507, -0.055, -0.0582, -0.055, -0.0533, -0.05, -0.0417, -0.02, -0.0198, 0.0, 0.0081, 0.02, 0.0321, 0.04, + 0.0494, 0.05, 0.0614, 0.07, 0.0824, 0.1, 0.2039, 0.35, 0.4906, 0.6, 0.7408, 0.84, 0.8758, 0.9, 0.9322, 0.94, 0.9562, 0.96, 0.9675, 0.97, 0.9731, 0.974, 0.9738, 0.975, + 0.9766, 0.977, 0.9786, 0.98, 0.9814, 0.983, 0.9833, 0.983, 0.9822, 0.984, 0.9851, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L42_1_m18spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0312, 0.04, 0.0454, 0.06, 0.0676, 0.1, 0.1240, 0.14, 0.1575, 0.17, 0.1813, 0.19, 0.2081, 0.21, 0.2238, 0.223, 0.2249, 0.223, 0.2224, 0.22, 0.2149, 0.21, 0.2071, 0.205, 0.2014, 0.2, 0.1956, 0.19, 0.1811, 0.17, 0.1572, 0.14, 0.1316, 0.12, 0.1053, 0.1, + 0.0815, 0.07, 0.0682, 0.065, 0.0639, 0.07, 0.0744, 0.09, 0.1040, 0.11, 0.1304, 0.135, 0.1451, 0.15, 0.1513, 0.153, 0.1542, 0.155, 0.1571, 0.16, 0.1608, 0.161, 0.1628, 0.1625, + 0.1625, 0.162, 0.1610, 0.16, 0.1585, 0.157, 0.1569, 0.157, 0.1579, 0.16, 0.1630, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L48_19_m25spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0617, 0.07, 0.0822, 0.1, 0.1139, 0.15, 0.2009, 0.22, 0.2533, 0.27, 0.2882, 0.3, 0.3264, 0.33, 0.3452, 0.342, 0.3406, 0.335, 0.3301, 0.32, 0.3131, 0.3, 0.2953, 0.28, 0.2766, 0.26, 0.2542, 0.24, 0.2234, 0.2, 0.1866, 0.17, 0.1506, 0.13, 0.1139, 0.1, 0.0806, 0.07, + 0.0623, 0.06, 0.0591, 0.08, 0.0942, 0.14, 0.1841, 0.21, 0.2635, 0.28, 0.3069, 0.31, 0.3251, 0.33, 0.3331, 0.335, 0.3391, 0.34, 0.3455, 0.346, 0.3487, 0.3467, 0.3486, 0.347, + 0.3467, 0.345, 0.3432, 0.342, 0.3411, 0.342, 0.3425, 0.35, 0.3505, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_21_m25spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0291, 0.03, 0.0386, 0.04, 0.0533, 0.08, 0.0940, 0.1, 0.1187, 0.12, 0.1349, 0.14, 0.1524, 0.16, 0.1605, 0.16, 0.1574, 0.155, 0.1515, 0.15, 0.1428, 0.14, 0.1330, 0.13, 0.1204, 0.11, 0.1039, 0.09, 0.0852, 0.07, 0.0667, 0.05, + 0.0496, 0.04, 0.0326, 0.02, 0.0173, 0.01, 0.0089, 0.008, 0.0078, 0.005, 0.0265, 0.005, 0.0738, 0.1, 0.1155, 0.12, 0.1383, 0.14, 0.1478, 0.15, 0.1519, 0.154, 0.1548, 0.156, + 0.1579, 0.158, 0.1594, 0.1594, 0.1594, 0.159, 0.1585, 0.1575, 0.1570, 0.156, 0.1559, 0.156, 0.1566, 0.159, 0.1603, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_10_m15spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0079, 0.01, 0.0107, 0.012, 0.0149, 0.02, 0.0264, 0.03, 0.0334, 0.035, 0.0381, 0.04, 0.0431, 0.044, 0.0456, 0.045, 0.0449, 0.044, 0.0435, 0.042, 0.0412, 0.04, 0.0386, 0.036, 0.0355, 0.033, 0.0316, 0.03, 0.0268, 0.025, 0.0216, 0.02, 0.0167, 0.015, + 0.0118, 0.01, 0.0073, 0.006, 0.0049, 0.004, 0.0045, 0.008, 0.0092, 0.001, 0.0212, 0.003, 0.0318, 0.0033, 0.0376, 0.04, 0.0401, 0.042, 0.0411, 0.0411, 0.0419, 0.042, + 0.0428, 0.043, 0.0432, 0.0432, 0.0432, 0.043, 0.0429, 0.0426, 0.0425, 0.0423, 0.0422, 0.0423, 0.0424, 0.043, 0.0434, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L48_19_m25spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0617, 0.07, 0.0822, 0.1, 0.1339, 0.25, 0.2009, 0.22, 0.2533, 0.29, 0.2882, 0.333, 0.3264, 0.38, 0.3452, 0.362, 0.3406, 0.335, 0.3301, 0.32, 0.3131, 0.3, 0.2953, 0.28, 0.2766, 0.26, 0.2542, 0.24, 0.2234, 0.2, 0.1866, 0.17, 0.1506, 0.13, 0.1139, 0.1, 0.0806, 0.07, + 0.0623, 0.06, 0.0591, 0.08, 0.0942, 0.14, 0.1841, 0.21, 0.2635, 0.28, 0.3069, 0.31, 0.3251, 0.33, 0.3331, 0.335, 0.3391, 0.34, 0.3455, 0.346, 0.3487, 0.3467, 0.3486, 0.347, + 0.3467, 0.345, 0.3432, 0.342, 0.3411, 0.342, 0.3425, 0.35, 0.3505, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_21_m25spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0291, 0.03, 0.0386, 0.04, 0.0533, 0.08, 0.0940, 0.1, 0.1187, 0.12, 0.1349, 0.15, 0.1624, 0.18, 0.1805, 0.18, 0.1774, 0.165, 0.1715, 0.15, 0.1428, 0.14, 0.1330, 0.13, 0.1204, 0.11, 0.1039, 0.09, 0.0852, 0.07, 0.0667, 0.05, + 0.0496, 0.04, 0.0326, 0.02, 0.0173, 0.01, 0.0089, 0.008, 0.0078, 0.005, 0.0265, 0.005, 0.0738, 0.1, 0.1155, 0.12, 0.1383, 0.14, 0.1478, 0.15, 0.1519, 0.154, 0.1548, 0.156, + 0.1579, 0.158, 0.1594, 0.1594, 0.1594, 0.159, 0.1585, 0.1575, 0.1570, 0.156, 0.1559, 0.156, 0.1566, 0.159, 0.1603, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L15_10_m15spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0079, 0.01, 0.0107, 0.012, 0.0149, 0.02, 0.0364, 0.04, 0.0434, 0.045, 0.0481, 0.04, 0.0431, 0.044, 0.0456, 0.045, 0.0449, 0.044, 0.0435, 0.042, 0.0412, 0.04, 0.0386, 0.036, 0.0355, 0.033, 0.0316, 0.03, 0.0268, 0.025, 0.0216, 0.02, 0.0167, 0.015, + 0.0118, 0.01, 0.0073, 0.006, 0.0049, 0.004, 0.0045, 0.008, 0.0092, 0.001, 0.0212, 0.003, 0.0318, 0.0033, 0.0376, 0.04, 0.0401, 0.042, 0.0411, 0.0411, 0.0419, 0.042, + 0.0528, 0.053, 0.0532, 0.0532, 0.0532, 0.043, 0.0429, 0.0426, 0.0425, 0.0423, 0.0422, 0.0423, 0.0424, 0.043, 0.0434, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L60_26_m25spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1040, 0.12, 0.1343, 0.15, 0.1812, 0.25, 0.3138, 0.35, 0.3938, 0.42, 0.4460, 0.48, 0.5027, 0.51, 0.5290, 0.52, 0.5196, 0.51, 0.5009, 0.49, 0.4726, 0.46, 0.4448, 0.43, 0.4186, 0.4, 0.3893, 0.36, 0.3469, 0.3, 0.2943, 0.28, 0.2426, 0.2, 0.1892, 0.16, 0.1403, 0.13, + 0.1136, 0.112, 0.1104, 0.15, 0.1729, 0.2, 0.3309, 0.4, 0.4702, 0.5, 0.5463, 0.56, 0.5782, 0.58, 0.5922, 0.6, 0.6022, 0.61, 0.6123, 0.615, 0.6171, 0.616, 0.6173, 0.616, + 0.6145, 0.61, 0.6095, 0.62, 0.6064, 0.607, 0.6085, 0.61, 0.6208, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_26_m45spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0615, 0.07, 0.0862, 0.1, 0.1249, 0.2, 0.2272, 0.25, 0.2893, 0.3, 0.3312, 0.35, 0.3766, 0.38, 0.3991, 0.395, 0.3933, 0.39, 0.3810, 0.37, 0.3613, 0.35, 0.3361, 0.3, 0.2979, 0.26, 0.2449, 0.2, 0.1884, 0.15, 0.1364, 0.1, 0.0895, 0.06, 0.0437, 0.04, + 0.0034, 0.0, -0.0191, -0.002, -0.0235, 0.0, 0.0145, 0.1, 0.1129, 0.15, 0.2000, 0.22, 0.2475, 0.25, 0.2673, 0.27, 0.2757, 0.28, 0.2822, 0.285, 0.2894, 0.29, + 0.2933, 0.293, 0.2932, 0.292, 0.2908, 0.29, 0.2865, 0.286, 0.2837, 0.285, 0.2855, 0.29, 0.2947, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_26_m45spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0615, 0.07, 0.0862, 0.1, 0.1249, 0.2, 0.2272, 0.25, 0.2893, 0.3, 0.3312, 0.35, 0.3766, 0.38, 0.3991, 0.395, 0.3933, 0.39, 0.3810, 0.37, 0.3613, 0.35, 0.3361, 0.3, 0.2979, 0.26, 0.2449, 0.2, 0.1884, 0.15, 0.1364, 0.1, 0.0895, 0.06, 0.0437, 0.04, + 0.0034, 0.0, -0.0191, -0.002, -0.0235, 0.0, 0.0145, 0.1, 0.1129, 0.15, 0.2000, 0.22, 0.2475, 0.25, 0.2673, 0.27, 0.2757, 0.28, 0.2822, 0.285, 0.2894, 0.29, + 0.2933, 0.293, 0.2932, 0.292, 0.2908, 0.29, 0.2865, 0.286, 0.2837, 0.285, 0.2855, 0.29, 0.2947, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_10_m45spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0196, 0.02, 0.0309, 0.04, 0.0487, 0.08, 0.0931, 0.1, 0.1199, 0.12, 0.1388, 0.14, 0.1595, 0.16, 0.1708, 0.17, 0.1699, 0.167, 0.1665, 0.16, 0.1595, 0.15, 0.1489, 0.14, 0.1303, 0.12, 0.1032, 0.09, 0.0751, 0.06, 0.0499, 0.03, 0.0273, 0.04, + 0.0056, 0.0, -0.0131, -0.02, -0.0237, -0.025, -0.0268, -0.02, -0.0165, 0.01, 0.0117, 0.02, 0.0369, 0.04, 0.0507, 0.051, 0.0564, 0.057, 0.0588, 0.06, 0.0610, 0.062, + 0.0639, 0.064, 0.0656, 0.0655, 0.0654, 0.065, 0.0642, 0.063, 0.0622, 0.061, 0.0608, 0.061, 0.0617, 0.064, 0.0656, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_10_m45spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0196, 0.02, 0.0309, 0.04, 0.0487, 0.08, 0.0931, 0.1, 0.1299, 0.14, 0.1588, 0.16, 0.1795, 0.18, 0.1908, 0.18, 0.1799, 0.187, 0.1665, 0.16, 0.1595, 0.15, 0.1489, 0.14, 0.1303, 0.12, 0.1032, 0.09, 0.0751, 0.06, 0.0499, 0.03, 0.0273, 0.04, + 0.0056, 0.0, 0., 0., 0., 0., 0., 0., 0., 0.01, 0.0117, 0.02, 0.0369, 0.04, 0.0507, 0.051, 0.0564, 0.057, 0.0588, 0.06, 0.0610, 0.062, + 0.0639, 0.064, 0.0656, 0.0655, 0.0654, 0.065, 0.0642, 0.063, 0.0622, 0.061, 0.0608, 0.061, 0.0617, 0.064, 0.0656, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L20_10_m45spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0196, 0.02, 0.0309, 0.04, 0.0387, 0.08, 0.0831, 0.1, 0.1099, 0.11, 0.1188, 0.11, 0.1395, 0.14, 0.1508, 0.16, 0.1599, 0.157, 0.1465, 0.16, 0.1595, 0.15, 0.1489, 0.14, 0.1303, 0.12, 0.1032, 0.09, 0.0751, 0.06, 0.0499, 0.03, 0.0273, 0.04, + 0.0056, 0.0, -0.0131, -0.02, -0.0237, -0.025, -0.0268, -0.02, -0.0165, 0.01, 0.0117, 0.02, 0.0369, 0.04, 0.0507, 0.051, 0.0564, 0.057, 0.0588, 0.06, 0.0610, 0.062, + 0.0639, 0.064, 0.0656, 0.0655, 0.0654, 0.065, 0.0642, 0.063, 0.0622, 0.061, 0.0608, 0.061, 0.0617, 0.064, 0.0656, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyK3_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4939, 0.435, 0.3859, 0.403, 0.4298, 0.456, 0.4880, 0.525, 0.5528, 0.572, 0.5672, 0.578, 0.5880, 0.595, 0.5994, 0.602, 0.6029, 0.600, 0.5981, 0.588, 0.5808, 0.571, 0.5618, 0.551, + 0.5369, 0.503, 0.4819, 0.452, 0.4190, 0.404, 0.3921, 0.386, 0.3815, 0.364, 0.3400, 0.321, 0.2991, 0.298, 0.2977, 0.304, 0.3090, 0.309, 0.3088, 0.302, 0.2930, 0.284, 0.2753, 0.271, + 0.2660, 0.265, 0.2636, 0.266, 0.2678, 0.275, 0.2811, 0.290, 0.2995, 0.306, 0.3125, 0.314, 0.3153, 0.313, 0.3111, 0.307, 0.3006, 0.298, .2952, 0.306, 0.3116, 0.325, 0.3584, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyK9_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4058, 0.441, 0.4734, 0.562, 0.5572, 0.65, 0.6051, 0.643, 0.7098, 0.725, 0.7392, 0.735, 0.7118, 0.712, 0.7135, 0.711, 0.7071, 0.702, 0.6938, 0.681, 0.6702, 0.663, 0.6511, 0.642, + 0.6282, 0.604, 0.5732, 0.542, 0.5103, 0.499, 0.4913, 0.492, 0.4926, 0.475, 0.4604, 0.452, 0.4341, 0.453, 0.4648, 0.496, 0.5111, 0.525, 0.5335, 0.531, 0.5283, 0.522, 0.5154, 0.512, + 0.5098, 0.509, 0.5093, 0.513, 0.5151, 0.523, 0.5309, 0.544, 0.5520, 0.562, 0.5642, 0.565, 0.5657, 0.562, 0.5598, 0.554, 0.5489, 0.546, 0.5430, 0.553, 0.5601, 0.576, 0.6067, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyC4_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3280, 0.2950, 0.2611, 0.334, 0.3981, 0.453, 0.4946, 0.548, 0.5692, 0.585, 0.5932, 0.611, 0.6512, 0.6621, 0.6507, 0.631, 0.6310, 0.625, 0.6181, 0.607, 0.5847, 0.563, 0.5488, 0.524, + 0.5066, 0.465, 0.4358, 0.398, 0.3585, 0.336, 0.3151, 0.302, 0.2855, 0.254, 0.2309, 0.203, 0.1786, 0.166, 0.1546, 0.149, 0.1443, 0.143, 0.1359, 0.131, 0.1245, 0.123, 0.115, 0.114, + 0.1120, 0.112, 0.1127, 0.114, 0.1169, 0.122, 0.1275, 0.133, 0.1421, 0.147, 0.1504, 0.149, 0.1488, 0.145, 0.1416, 0.136, 0.1303, 0.127, 0.1241, 0.132, 0.1355, 0.155, 0.1739, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyC14_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5697, 0.511, 0.4660, 0.481, 0.5500, 0.588, 0.5560, 0.633, 0.6572, 0.682, 0.6902, 0.693, 0.6932, 0.684, 0.6950, 0.699, 0.7069, 0.717, 0.7292, 0.735, 0.7488, 0.757, 0.7678, 0.773, + 0.7786, 0.776, 0.7721, 0.765, 0.7544, 0.746, 0.7394, 0.731, 0.7232, 0.704, 0.6889, 0.674, 0.6446, 0.631, 0.6171, 0.606, 0.5966, 0.585, 0.5743, 0.5570, 0.5425, 0.529, 0.5093, 0.498, + 0.4884, 0.482, 0.4784, 0.478, 0.4774, 0.481, 0.4822, 0.487, 0.4944, 0.503, 0.5076, 0.512, 0.5186, 0.522, 0.5268, 0.529, 0.5303, 0.532, 0.5332, 0.539, 0.5454, 0.565, 0.5760, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyE4_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1483, 0.161, 0.1756, 0.213, 0.2536, 0.283, 0.3584, 0.391, 0.3965, 0.437, 0.4589, 0.495, 0.4946, 0.526, 0.5427, 0.569, 0.5239, 0.522, 0.5193, 0.508, 0.4917, 0.476, 0.4569, 0.431, + 0.4123, 0.375, 0.3422, 0.309, 0.2672, 0.242, 0.2179, 0.208, 0.1820, 0.162, 0.1356, 0.113, 0.0972, 0.091, 0.0784, 0.073, 0.0698, 0.066, 0.0646, 0.062, 0.0592, 0.057, 0.0556, 0.055, + 0.0546, 0.055, 0.0551, 0.056, 0.0571, 0.059, 0.0611, 0.064, 0.0670, 0.069, 0.0701, 0.070, 0.0692, 0.067, 0.0661, 0.065, 0.0620, 0.061, 0.0606, 0.063, 0.0663, 0.072, 0.0834, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyM1_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3100, 0.303, 0.2922, 0.322, 0.3514, 0.376, 0.4342, 0.484, 0.4843, 0.497, 0.4969, 0.497, 0.5502, 0.557, 0.5633, 0.556, 0.5187, 0.518, 0.5179, 0.511, 0.5057, 0.497, 0.4928, 0.483, + 0.4729, 0.454, 0.4235, 0.398, 0.3643, 0.346, 0.3371, 0.329, 0.3234, 0.301, 0.2827, 0.263, 0.2418, 0.235, 0.2338, 0.235, 0.2370, 0.236, 0.2329, 0.226, 0.2184, 0.213, 0.2028, 0.198, + 0.1958, 0.194, 0.1937, 0.196, 0.1973, 0.203, 0.2084, 0.212, 0.2244, 0.233, 0.2351, 0.236, 0.2372, 0.234, 0.2331, 0.229, 0.2239, 0.222, 0.2178, 0.224, 0.2319, 0.251, 0.2731, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSky2B1_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5277, 0.485, 0.4431, 0.476, 0.5472, 0.599, 0.5920, 0.667, 0.6887, 0.693, 0.6950, 0.721, 0.7401, 0.737, 0.7640, 0.718, 0.7202, 0.720, 0.7193, 0.713, 0.7053, 0.695, 0.6891, 0.674, + 0.6657, 0.632, 0.6181, 0.587, 0.5614, 0.543, 0.5312, 0.521, 0.5101, 0.483, 0.4589, 0.431, 0.4045, 0.398, 0.3857, 0.385, 0.3826, 0.376, 0.3751, 0.364, 0.3574, 0.346, 0.3393, 0.335, + 0.3314, 0.331, 0.3304, 0.333, 0.3368, 0.346, 0.3523, 0.363, 0.3742, 0.382, 0.3874, 0.385, 0.3883, 0.384, 0.3818, 0.375, 0.3693, 0.364, 0.3616, 0.374, 0.3800, 0.396, 0.4324, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyT7_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1943, 0.256, 0.3199, 0.376, 0.4836, 0.554, 0.5843, 0.592, 0.6643, 0.661, 0.6899, 0.694, 0.6939, 0.708, 0.7525, 0.756, 0.7329, 0.741, 0.7482, 0.751, 0.7527, 0.752, 0.7514, 0.745, + 0.7383, 0.721, 0.7028, 0.675, 0.6526, 0.631, 0.6034, 0.589, 0.5500, 0.512, 0.4708, 0.432, 0.3848, 0.342, 0.3268, 0.311, 0.2929, 0.282, 0.2712, 0.261, 0.2493, 0.236, 0.2316, 0.227, + 0.2243, 0.223, 0.2234, 0.229, 0.2288, 0.235, 0.2436, 0.255, 0.2640, 0.268, 0.2762, 0.277, 0.2767, 0.272, 0.2693, 0.263, 0.2566, 0.254, 0.2489, 0.255, 0.2665, 0.275, 0.3165, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyU19_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5829, 0.534, 0.4865, 0.489, 0.5227, 0.552, 0.5890, 0.633, 0.6621, 0.661, 0.6832, 0.682, 0.6928, 0.694, 0.6932, 0.687, 0.6989, 0.688, 0.6884, 0.683, 0.6771, 0.671, 0.6648, 0.665, + 0.6465, 0.622, 0.6038, 0.583, 0.5524, 0.542, 0.5297, 0.523, 0.5194, 0.492, 0.4797, 0.451, 0.4387, 0.436, 0.4356, 0.442, 0.4455, 0.445, 0.4444, 0.432, 0.4282, 0.413, 0.4094, 0.404, + 0.4009, 0.400, 0.3992, 0.402, 0.4046, 0.411, 0.4185, 0.426, 0.4385, 0.446, 0.4515, 0.452, 0.4545, 0.452, 0.4505, 0.446, 0.4411, 0.438, 0.4368, 0.443, 0.4539, 0.467, 0.5013, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorBlueSkyU2_spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3594, 0.345, 0.3625, 0.363, 0.3614, 0.376, 0.3854, 0.397, 0.4497, 0.484, 0.4960, 0.496, 0.4990, 0.497, 0.4993, 0.494, 0.5302, 0.537, 0.5434, 0.538, 0.5476, 0.564, 0.5745, 0.583, + 0.5940, 0.593, 0.5901, 0.580, 0.5703, 0.563, 0.5545, 0.546, 0.5384, 0.521, 0.5029, 0.478, 0.4592, 0.444, 0.4334, 0.421, 0.4149, 0.408, 0.3947, 0.378, 0.3657, 0.352, 0.3363, 0.324, + 0.3177, 0.313, 0.3087, 0.308, 0.3077, 0.310, 0.3123, 0.317, 0.3231, 0.329, 0.3351, 0.339, 0.3454, 0.348, 0.3520, 0.353, 0.3545, 0.355, 0.3562, 0.359, 0.3674, 0.375, 0.3976, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_1_m40spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0411, 0.05, 0.0646, 0.09, 0.1016, 0.15, 0.1929, 0.22, 0.2476, 0.26, 0.2868, 0.3, 0.3304, 0.34, 0.3556, 0.356, 0.3564, 0.352, 0.3519, 0.34, 0.3395, 0.33, 0.3223, 0.3, 0.2967, 0.28, 0.2606, 0.23, 0.2170, 0.19, 0.1700, 0.15, 0.1245, 0.1, 0.0798, 0.06, + 0.0405, 0.03, 0.0183, 0.015, 0.0110, 0.02, 0.0267, 0.05, 0.0715, 0.1, 0.1117, 0.12, 0.1339, 0.14, 0.1432, 0.145, 0.1473, 0.15, 0.1516, 0.155, 0.1574, 0.16, 0.1608, 0.1605, + 0.1602, 0.16, 0.1578, 0.155, 0.1535, 0.153, 0.1507, 0.152, 0.1525, 0.158, 0.1605, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_4_m30spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0229, 0.03, 0.0346, 0.04, 0.0531, 0.08, 0.0995, 0.11, 0.1274, 0.13, 0.1471, 0.15, 0.1690, 0.17, 0.1813, 0.182, 0.1812, 0.18, 0.1784, 0.175, 0.1716, 0.17, 0.1627, 0.16, 0.1501, 0.14, 0.1326, 0.12, 0.1112, 0.1, 0.0880, 0.07, 0.0655, 0.05, + 0.0433, 0.03, 0.0237, 0.02, 0.0126, 0.009, 0.0092, 0.01, 0.0190, 0.03, 0.0460, 0.06, 0.0701, 0.075, 0.0834, 0.085, 0.0889, 0.09, 0.0914, 0.092, 0.0937, 0.095, 0.0967, 0.097, + 0.0984, 0.0982, 0.0982, 0.098, 0.0970, 0.096, 0.0949, 0.094, 0.0935, 0.094, 0.0944, 0.097, 0.0985, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L8_11_m25spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0057, 0.007, 0.0084, 0.01, 0.0126, 0.02, 0.0234, 0.025, 0.0300, 0.032, 0.0345, 0.036, 0.0395, 0.04, 0.0420, 0.042, 0.0415, 0.041, 0.0404, 0.04, 0.0385, 0.037, 0.0358, 0.034, 0.0314, 0.03, 0.0250, 0.02, 0.0184, 0.015, 0.0126, 0.01, + 0.0073, 0.005, 0.0022, 0.0, -0.0022, -0.003, -0.0047, -0.005, -0.0053, -0.003, -0.0019, 0.0, 0.0070, 0.01, 0.0149, 0.016, 0.0192, 0.02, 0.0210, 0.022, 0.0217, 0.022, 0.0224, 0.0224, + 0.0231, 0.0234, 0.0235, 0.0235, 0.0235, 0.0233, 0.0232, 0.023, 0.0227, 0.0225, 0.0224, 0.0225, 0.0226, 0.023, 0.0236, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L40_1_m40spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0411, 0.05, 0.0686, 0.09, 0.1016, 0.15, 0.1929, 0.22, 0.2776, 0.28, 0.2968, 0.34, 0.3804, 0.39, 0.3756, 0.356, 0.3564, 0.352, 0.3519, 0.34, 0.3395, 0.33, 0.3223, 0.3, 0.2967, 0.28, 0.2606, 0.23, 0.2170, 0.19, 0.1700, 0.15, 0.1245, 0.1, 0.0798, 0.06, + 0.0405, 0.03, 0.0183, 0.015, 0.0110, 0.02, 0.0267, 0.05, 0.0715, 0.1, 0.1117, 0.12, 0.1339, 0.14, 0.1432, 0.145, 0.1473, 0.15, 0.1516, 0.155, 0.1574, 0.16, 0.1608, 0.1605, + 0.1602, 0.16, 0.1578, 0.155, 0.1535, 0.153, 0.1507, 0.152, 0.1525, 0.158, 0.1605, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L30_4_m30spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0229, 0.03, 0.0346, 0.04, 0.0531, 0.08, 0.0995, 0.11, 0.1274, 0.13, 0.1871, 0.19, 0.1990, 0.21, 0.2013, 0.212, 0.2012, 0.18, 0.1784, 0.175, 0.1716, 0.17, 0.1627, 0.16, 0.1501, 0.14, 0.1326, 0.12, 0.1112, 0.1, 0.0880, 0.07, 0.0655, 0.05, + 0.0433, 0.03, 0.0237, 0.02, 0.0126, 0.009, 0.0092, 0.01, 0.0190, 0.03, 0.0460, 0.06, 0.0701, 0.075, 0.0834, 0.085, 0.0889, 0.09, 0.0914, 0.092, 0.0937, 0.095, 0.0967, 0.097, + 0.0984, 0.0982, 0.0982, 0.098, 0.0970, 0.096, 0.0949, 0.094, 0.0935, 0.094, 0.0944, 0.097, 0.0985, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L8_11_m25spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0057, 0.007, 0.0094, 0.01, 0.0126, 0.02, 0.0234, 0.045, 0.0300, 0.032, 0.0445, 0.036, 0.0395, 0.04, 0.0440, 0.042, 0.0415, 0.041, 0.0404, 0.04, 0.0455, 0.037, 0.0358, 0.034, 0.0314, 0.03, 0.0250, 0.02, 0.0184, 0.015, 0.0126, 0.01, + 0.0073, 0.005, 0.0022, 0.0, -0.0022, -0.003, -0.0047, -0.005, -0.0053, -0.003, -0.0019, 0.0, 0.0070, 0.01, 0.0149, 0.016, 0.0192, 0.02, 0.0210, 0.022, 0.0217, 0.022, 0.0224, 0.0224, + 0.0231, 0.0234, 0.0235, 0.0235, 0.0235, 0.0233, 0.0232, 0.023, 0.0227, 0.0225, 0.0224, 0.0225, 0.0226, 0.023, 0.0236, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::Colorlab_L26_m8_m25spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0133, 0.02, 0.0223, 0.03, 0.0365, 0.05, 0.0706, 0.08, 0.0908, 0.1, 0.1057, 0.11, 0.1225, 0.13, 0.1328, 0.133, 0.1343, 0.134, 0.1337, 0.1232, 0.1300, 0.126, 0.1247, 0.12, 0.1174, 0.11, 0.1072, 0.1, 0.0930, 0.08, 0.0757, 0.06, 0.0583, 0.05, + 0.0410, 0.03, 0.0258, 0.02, 0.0172, 0.015, 0.0139, 0.015, 0.0166, 0.02, 0.0259, 0.03, 0.0344, 0.036, 0.0392, 0.04, 0.0412, 0.042, 0.0421, 0.043, 0.0435, 0.044, + 0.0456, 0.046, 0.0468, 0.0465, 0.0465, 0.046, 0.0455, 0.044, 0.0439, 0.043, 0.0428, 0.043, 0.0435, 0.045, 0.0465, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L26_m8_m25spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0133, 0.02, 0.0223, 0.03, 0.0385, 0.07, 0.0806, 0.09, 0.1008, 0.12, 0.1357, 0.13, 0.1425, 0.14, 0.1428, 0.143, 0.1443, 0.134, 0.1337, 0.1232, 0.1300, 0.126, 0.1247, 0.12, 0.1174, 0.11, 0.1072, 0.1, 0.0930, 0.08, 0.0757, 0.06, 0.0583, 0.05, + 0.0410, 0.03, 0.0258, 0.02, 0.0172, 0.015, 0.0139, 0.015, 0.0166, 0.02, 0.0259, 0.03, 0.0344, 0.036, 0.0392, 0.04, 0.0412, 0.042, 0.0421, 0.043, 0.0435, 0.044, + 0.0456, 0.046, 0.0468, 0.0465, 0.0465, 0.046, 0.0455, 0.044, 0.0439, 0.043, 0.0428, 0.043, 0.0435, 0.045, 0.0465, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L26_m8_m25spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0133, 0.02, 0.0223, 0.03, 0.0265, 0.05, 0.0606, 0.08, 0.0808, 0.09, 0.1057, 0.10, 0.1125, 0.12, 0.1228, 0.123, 0.1243, 0.124, 0.1337, 0.1232, 0.1300, 0.126, 0.1247, 0.12, 0.1174, 0.11, 0.1072, 0.1, 0.0930, 0.08, 0.0757, 0.06, 0.0583, 0.05, + 0.0410, 0.03, 0.0258, 0.02, 0.0172, 0.015, 0.0139, 0.015, 0.0166, 0.02, 0.0259, 0.03, 0.0344, 0.036, 0.0392, 0.04, 0.0412, 0.042, 0.0421, 0.043, 0.0435, 0.044, + 0.0456, 0.046, 0.0468, 0.0465, 0.0465, 0.046, 0.0455, 0.044, 0.0439, 0.043, 0.0428, 0.043, 0.0435, 0.045, 0.0465, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_1_m42spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0170, 0.02, 0.0284, 0.03, 0.0463, 0.06, 0.0898, 0.1, 0.1160, 0.12, 0.1348, 0.14, 0.1557, 0.16, 0.1678, 0.168, 0.1680, 0.167, 0.1658, 0.164, 0.1600, 0.155, 0.1507, 0.14, 0.1346, 0.12, 0.1109, 0.1, 0.0853, 0.07, 0.0608, 0.05, 0.0380, 0.02, 0.0161, 0.0, + -0.0028, -0.01, -0.0136, -0.015, -0.0172, -0.012, -0.0104, 0.0, 0.0095, 0.02, 0.0274, 0.03, 0.0372, 0.04, 0.0413, 0.042, 0.0431, 0.044, 0.0450, 0.046, 0.0477, 0.048, 0.0493, 0.049, + 0.0490, 0.048, 0.0478, 0.046, 0.0457, 0.045, 0.0444, 0.045, 0.0453, 0.048, 0.0490, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_1_m42spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0170, 0.02, 0.0284, 0.03, 0.0463, 0.06, 0.0898, 0.1, 0.1160, 0.12, 0.1548, 0.16, 0.1657, 0.17, 0.1778, 0.168, 0.1680, 0.167, 0.1658, 0.164, 0.1600, 0.155, 0.1507, 0.14, 0.1346, 0.12, 0.1109, 0.1, 0.0853, 0.07, 0.0608, 0.05, 0.0380, 0.02, 0.0161, 0.0, + -0.0028, -0.01, -0.0136, -0.015, -0.0172, -0.012, -0.0104, 0.0, 0.0095, 0.02, 0.0274, 0.03, 0.0372, 0.04, 0.0413, 0.042, 0.0431, 0.044, 0.0450, 0.046, 0.0477, 0.048, 0.0493, 0.049, + 0.0490, 0.048, 0.0478, 0.046, 0.0457, 0.045, 0.0444, 0.045, 0.0453, 0.048, 0.0490, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_1_m42spect3[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0170, 0.02, 0.0284, 0.03, 0.0463, 0.06, 0.0898, 0.1, 0.1160, 0.12, 0.1548, 0.16, 0.1657, 0.17, 0.1778, 0.168, 0.1680, 0.167, 0.1658, 0.164, 0.1600, 0.155, 0.1507, 0.14, 0.1346, 0.12, 0.1109, 0.1, 0.0853, 0.07, 0.0608, 0.05, 0.0380, 0.02, 0.0161, 0.0, + 0.0, 0.0, 0.01, 0.01, 0.01, 0.01, 0.0, 0.0, 0.0095, 0.02, 0.0274, 0.03, 0.0372, 0.04, 0.0413, 0.042, 0.0431, 0.044, 0.0450, 0.046, 0.0477, 0.048, 0.0493, 0.049, + 0.0490, 0.048, 0.0478, 0.046, 0.0457, 0.045, 0.0444, 0.045, 0.0453, 0.048, 0.0490, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L22_1_m42spect4[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0170, 0.02, 0.0284, 0.03, 0.0463, 0.06, 0.0898, 0.1, 0.1160, 0.12, 0.1548, 0.16, 0.1657, 0.17, 0.1778, 0.168, 0.1680, 0.167, 0.1658, 0.164, 0.1600, 0.155, 0.1507, 0.14, 0.1346, 0.12, 0.1109, 0.1, 0.0853, 0.07, 0.0608, 0.05, 0.0380, 0.02, 0.0161, 0.0, + 0.0, 0.0, 0.01, 0.01, 0.01, 0.01, 0.0, 0.0, 0.0095, 0.02, 0.0274, 0.03, 0.0372, 0.04, 0.0413, 0.042, 0.0431, 0.044, 0.0450, 0.046, 0.0477, 0.048, 0.0493, 0.049, + 0.0490, 0.048, 0.0478, 0.046, 0.0457, 0.045, 0.0444, 0.045, 0.0453, 0.048, 0.0490, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L27_m1_m47spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0237, 0.03, 0.0400, 0.05, 0.0657, 0.09, 0.1278, 0.14, 0.1651, 0.18, 0.1921, 0.21, 0.2221, 0.23, 0.2395, 0.24, 0.2400, 0.24, 0.2371, 0.23, 0.2289, 0.22, 0.2159, 0.2, 0.1930, 0.18, 0.1595, 0.14, 0.1230, 0.1, + 0.0879, 0.07, 0.0553, 0.04, 0.0239, 0.0, -0.0034, -0.01, -0.0188, -0.02, -0.0241, -0.02, -0.0151, 0.0, 0.0117, 0.02, 0.0359, 0.04, 0.0492, 0.05, 0.0548, 0.055, 0.0571, 0.058, + 0.0598, 0.06, 0.0637, 0.065, 0.0660, 0.066, 0.0656, 0.064, 0.0638, 0.062, 0.0608, 0.06, 0.0589, 0.06, 0.0601, 0.065, 0.0655, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L27_m1_m47spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0237, 0.03, 0.0450, 0.05, 0.0657, 0.09, 0.1478, 0.16, 0.1751, 0.21, 0.2221, 0.23, 0.2421, 0.24, 0.2495, 0.25, 0.2500, 0.25, 0.2471, 0.24, 0.2389, 0.22, 0.2159, 0.2, 0.1930, 0.18, 0.1595, 0.14, 0.1230, 0.1, + 0.0879, 0.07, 0.0553, 0.04, 0.0239, 0.0, -0.0034, -0.01, -0.0188, -0.02, -0.0241, -0.02, -0.0151, 0.0, 0.0117, 0.02, 0.0359, 0.04, 0.0492, 0.05, 0.0548, 0.055, 0.0571, 0.058, + 0.0598, 0.06, 0.0637, 0.065, 0.0660, 0.066, 0.0656, 0.064, 0.0638, 0.062, 0.0608, 0.06, 0.0589, 0.06, 0.0601, 0.065, 0.0655, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_30_m30spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0552, 0.06, 0.0713, 0.08, 0.0964, 0.12, 0.1678, 0.19, 0.2112, 0.22, 0.2391, 0.25, 0.2689, 0.275, 0.2818, 0.28, 0.2749, 0.27, 0.2630, 0.25, 0.2464, 0.23, 0.2282, 0.21, 0.2049, 0.19, 0.1748, 0.16, 0.1415, 0.12, 0.1097, 0.1, + 0.0810, 0.07, 0.0523, 0.04, 0.0265, 0.02, 0.0123, 0.012, 0.0113, 0.03, 0.0487, 0.1, 0.1428, 0.18, 0.2257, 0.25, 0.2708, 0.28, 0.2897, 0.29, 0.2977, 0.3, 0.3033, 0.304, + 0.3088, 0.31, 0.3115, 0.3116, 0.3117, 0.3108, 0.3102, 0.31, 0.3076, 0.306, 0.3059, 0.306, 0.3070, 0.31, 0.3136, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_30_m30spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0552, 0.06, 0.0713, 0.08, 0.0864, 0.1, 0.1478, 0.19, 0.212, 0.22, 0.2391, 0.24, 0.2589, 0.255, 0.2818, 0.28, 0.2749, 0.27, 0.2630, 0.25, 0.2464, 0.23, 0.2282, 0.21, 0.2049, 0.19, 0.1748, 0.16, 0.1415, 0.12, 0.1097, 0.1, + 0.0810, 0.07, 0.0523, 0.04, 0.0265, 0.02, 0.0123, 0.012, 0.0113, 0.03, 0.0487, 0.1, 0.1428, 0.18, 0.2257, 0.25, 0.2708, 0.28, 0.2897, 0.29, 0.2977, 0.3, 0.3033, 0.304, + 0.3088, 0.3, 0.3015, 0.3016, 0.3017, 0.3108, 0.3002, 0.29, 0.2876, 0.286, 0.2859, 0.286, 0.2870, 0.28, 0.2836, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_20_m35spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0502, .06, 0.0694, 0.08, 0.0994, 0.13, 0.1794, 0.2, 0.2277, 0.25, 0.2604, 0.28, 0.2959, 0.3, 0.3137, 0.31, 0.3096, 0.305, 0.3004, 0.29, 0.2852, 0.27, 0.2669, 0.25, 0.2418, 0.22, 0.2080, 0.19, + 0.1696, 0.15, 0.1312, 0.1, 0.0955, 0.08, 0.0602, 0.04, 0.0288, 0.02, 0.0113, 0.01, 0.0078, 0.03, 0.0373, 0.1, 0.1136, 0.15, 0.1811, 0.2, 0.2180, 0.22, 0.2334, 0.24, + 0.2400, 0.241, 0.2452, 0.25, 0.2508, 0.252, 0.2538, 0.254, 0.2537, 0.252, 0.2519, 0.25, 0.2485, 0.246, 0.2464, 0.247, 0.2478, 0.26, 0.2550, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_L40_20_m35spect2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0502, .06, 0.0694, 0.08, 0.0994, 0.13, 0.1794, 0.2, 0.2277, 0.25, 0.2604, 0.28, 0.2959, 0.3, 0.3137, 0.31, 0.2896, 0.285, 0.2804, 0.27, 0.2652, 0.25, 0.2469, 0.25, 0.2418, 0.22, 0.2080, 0.19, + 0.1696, 0.15, 0.1312, 0.1, 0.0955, 0.08, 0.0602, 0.04, 0.0288, 0.02, 0.0113, 0.01, 0.0078, 0.03, 0.0373, 0.1, 0.1136, 0.15, 0.1811, 0.2, 0.2180, 0.22, 0.2334, 0.24, + 0.2400, 0.241, 0.2452, 0.23, 0.2308, 0.232, 0.2338, 0.234, 0.2337, 0.232, 0.2319, 0.23, 0.2385, 0.236, 0.2364, 0.237, 0.2378, 0.24, 0.2450, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//3 A3 0.0552 0.0713 0.0964 0.1678 0.2112 0.2391 0.2689 0.2818 0.2749 0.2630 0.2464 0.2282 0.2049 0.1748 0.1415 0.1097 0.0810 0.0523 0.0265 0.0123 0.0113 0.0487 0.1428 0.2257 0.2708 0.2897 0.2977 0.3033 0.3088 0.3115 0.3117 0.3102 0.3076 0.3059 0.3070 0.3136 +//4 A4 0.0502 0.0694 0.0994 0.1794 0.2277 0.2604 0.2959 0.3137 0.3096 0.3004 0.2852 0.2669 0.2418 0.2080 0.1696 0.1312 0.0955 0.0602 0.0288 0.0113 0.0078 0.0373 0.1136 0.1811 0.2180 0.2334 0.2400 0.2452 0.2508 0.2538 0.2537 0.2519 0.2485 0.2464 0.2478 0.2550 + + /* * Name: XYZtoCorColorTemp.c * @@ -2686,7 +4303,7 @@ int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp) return 0; /* success */ } -void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, double &CAM02BB01, double &CAM02BB02, double &CAM02BB10, double &CAM02BB11, double &CAM02BB12, double &CAM02BB20, double &CAM02BB21, double &CAM02BB22, double adap ) +void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, double &CAM02BB01, double &CAM02BB02, double &CAM02BB10, double &CAM02BB11, double &CAM02BB12, double &CAM02BB20, double &CAM02BB21, double &CAM02BB22, double adap) { // CIECAT02 - J.Desmis January 2012 review September 2012 @@ -2738,20 +4355,20 @@ void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, dou inv_white_orig[2][2] = 1. / cam_orig[2]; // 1/BeS //intermediates computation - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3 ; j++) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { intermed[i][j] = inv_white_orig[i][i] * CAT02[i][j]; } - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3 ; j++) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { intermed_2[i][j] = cam_dest[i] * intermed[i][j]; } //and CAM02 - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3; j++) - for(int k = 0; k < 3; k++) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { CAM02[i][j] += INVCAT02[i][k] * intermed_2[k][j]; } @@ -2969,19 +4586,20 @@ void ColorTemp::icieCAT02float(float Xw, float Yw, float Zw, float &iCAM02BB00, } -void ColorTemp::temp2mulxyz (double temp, const std::string &method, StandardObserver observer, double &Xxyz, double &Zxyz) +void ColorTemp::temp2mulxyz(double temp, const std::string &method, StandardObserver observer, double &Xxyz, double &Zxyz) { double x, y, z; // We first test for specially handled methods const auto iterator = spectMap.find(method); const auto &color_match = (observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; -/* if(observer == StandardObserver::TEN_DEGREES){ - printf("General Observer 10°\n"); - } else { - printf("General Observer 2°\n"); - } -*/ +/* + if(observer == StandardObserver::TEN_DEGREES){ + printf("General Observer 10°\n"); + } else { + printf("General Observer 2°\n"); + } +*/ if (iterator != spectMap.end()) { spectrum_to_xyz_preset(iterator->second, x, y, z, color_match); } else { @@ -2998,7 +4616,7 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, StandardObs x_D = -4.6070e9 / (temp * temp * temp) + 2.9678e6 / (temp * temp) + 0.09911e3 / temp + 0.244063; } else if (temp <= 25000) { x_D = -2.0064e9 / (temp * temp * temp) + 1.9018e6 / (temp * temp) + 0.24748e3 / temp + 0.237040; - } else /*if (temp > 25000)*/ { + } else { /*if (temp > 25000)*/ x_D = -2.0064e9 / (temp * temp * temp) + 1.9018e6 / (temp * temp) + 0.24748e3 / temp + 0.237040 - ((temp - 25000) / 25000) * 0.025; //Jacques empirical adjustment for very high temp (underwater !) } @@ -3016,7 +4634,7 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, StandardObs Zxyz = (1.0 - x - y) / y; } -void ColorTemp::temp2mul (double temp, double green, double equal, StandardObserver observer, double& rmul, double& gmul, double& bmul) const +void ColorTemp::temp2mul(double temp, double green, double equal, StandardObserver observer, double& rmul, double& gmul, double& bmul) const { clip(temp, green, equal); double Xwb, Zwb; @@ -3024,8 +4642,8 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser double adj = 1.0; - if(equal < 0.9999 || equal > 1.0001 ) { - adj = (100.0 + ( 1000.0 - (1000.0 * equal) ) / 20.0) / 100.0; + if (equal < 0.9999 || equal > 1.0001) { + adj = (100.0 + (1000.0 - (1000.0 * equal)) / 20.0) / 100.0; } @@ -3048,7 +4666,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser bmul /= maxRGB; - if(settings->CRI_color != 0) { //activate if CRi_color !=0 + if (settings->CRI_color != 0) { //activate if CRi_color !=0 // begin CRI_RT : color rendering index RT - adaptation of CRI by J.Desmis // CRI = 100 for Blackbody and Daylight // calculate from spectral data values X, Y, Z , for color of colorchecker24 , SG, DC, JDC_468 @@ -3083,7 +4701,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser bool CRI_type = false; double tempw; - if (method == "Fluo F1") { + if (method == "Fluo F1") { CRI_type = true; tempw = 6430; illum = 1; @@ -3151,7 +4769,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser CRI_type = true; tempw = 3930; illum = 17; - } else if (method == "Solux Lamp 4700K" ) { + } else if (method == "Solux Lamp 4700K") { CRI_type = true; tempw = 4700; illum = 18; @@ -3188,20 +4806,21 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser float CRI_RTs = 0.0, CRIs[8]; const auto &color_match = (observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; + //exceptional must be used by advice people - if(observer == StandardObserver::TEN_DEGREES){ + if (observer == StandardObserver::TEN_DEGREES) { printf("CRI Observer 10°\n"); } else { printf("CRI Observer 2°\n"); } - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i], color_match); } //calculate XYZ for each color : for Blackbody and Daylight at tempw - if(tempw <= INITIALBLACKBODY) { - for(int i = 0; i < N_c; i++) { + if (tempw <= INITIALBLACKBODY) { + for (int i = 0; i < N_c; i++) { spectrum_to_color_xyz_blackbody(spec_color[i], tempw, Xchk[i], Ychk[i], Zchk[i], color_match); } @@ -3222,7 +4841,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser m11 = (-1.3515 - 1.7703 * x_DD + 5.9114 * y_DD) / interm2; m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { spectrum_to_color_xyz_daylight(spec_color[i], m11, m22, Xchk[i], Ychk[i], Zchk[i], color_match); } @@ -3245,7 +4864,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser cieCAT02(Xwb, Ywb, Zwb, CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22, adap); //here new value of X,Y,Z for lamp with chromatic CAM02 adaptation - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { Xcam02Lamp[i] = CAM02BB00 * XchkLamp[i] + CAM02BB01 * YchkLamp[i] + CAM02BB02 * ZchkLamp[i] ; Ycam02Lamp[i] = CAM02BB10 * XchkLamp[i] + CAM02BB11 * YchkLamp[i] + CAM02BB12 * ZchkLamp[i] ; Zcam02Lamp[i] = CAM02BB20 * XchkLamp[i] + CAM02BB21 * YchkLamp[i] + CAM02BB22 * ZchkLamp[i] ; @@ -3257,7 +4876,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser //here new value of X,Y,Z for blackbody with chromatic CAM02 adaptation - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { Xcam02[i] = CAM02BB00 * Xchk[i] + CAM02BB01 * Ychk[i] + CAM02BB02 * Zchk[i] ; Ycam02[i] = CAM02BB10 * Xchk[i] + CAM02BB11 * Ychk[i] + CAM02BB12 * Zchk[i] ; Zcam02[i] = CAM02BB20 * Xchk[i] + CAM02BB21 * Ychk[i] + CAM02BB22 * Zchk[i] ; @@ -3269,25 +4888,25 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser // Lamp double fx[50], fy[50], fz[50]; - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { xr[i] = Xcam02Lamp[i] / whiteD50[0]; yr[i] = Ycam02Lamp[i] / whiteD50[1]; zr[i] = Zcam02Lamp[i] / whiteD50[2]; // xr, yr , zr > epsilon - if(xr[i] > epsilon) { + if (xr[i] > epsilon) { fx[i] = std::cbrt(xr[i]); } else { fx[i] = (903.3 * xr[i] + 16.0) / 116.0; } - if(yr[i] > epsilon) { + if (yr[i] > epsilon) { fy[i] = std::cbrt(yr[i]); } else { fy[i] = (903.3 * yr[i] + 16.0) / 116.0; } - if(zr[i] > epsilon) { + if (zr[i] > epsilon) { fz[i] = std::cbrt(zr[i]); } else { fz[i] = (903.3 * zr[i] + 16.0) / 116.0; @@ -3295,32 +4914,33 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser } double Llamp[50], alamp[50], blamp[50]; - for(int i = 0; i < N_c; i++) { + + for (int i = 0; i < N_c; i++) { Llamp[i] = 116.0 * fy[i] - 16.0; alamp[i] = 500.0 * (fx[i] - fy[i]); blamp[i] = 200.0 * (fy[i] - fz[i]); } //blackbody at tempx - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { xr[i] = Xcam02[i] / whiteD50[0]; yr[i] = Ycam02[i] / whiteD50[1]; zr[i] = Zcam02[i] / whiteD50[2]; // - if(xr[i] > epsilon) { + if (xr[i] > epsilon) { fx[i] = std::cbrt(xr[i]); } else { fx[i] = (903.3 * xr[i] + 16.0) / 116.0; } - if(yr[i] > epsilon) { + if (yr[i] > epsilon) { fy[i] = std::cbrt(yr[i]); } else { fy[i] = (903.3 * yr[i] + 16.0) / 116.0; } - if(zr[i] > epsilon) { + if (zr[i] > epsilon) { fz[i] = std::cbrt(zr[i]); } else { fz[i] = (903.3 * zr[i] + 16.0) / 116.0; @@ -3329,61 +4949,61 @@ void ColorTemp::temp2mul (double temp, double green, double equal, StandardObser double Lbb[50], abb[50], bbb[50]; - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { Lbb[i] = 116.*fy[i] - 16.; abb[i] = 500.*(fx[i] - fy[i]); bbb[i] = 200.*(fy[i] - fz[i]); } //display value to verify calculus - if(settings->CRI_color != 0) { + if (settings->CRI_color != 0) { printf("Color Number %i\n", numero_color); printf("L_refer=%2.2f a=%2.2f b=%2.2f\n", Lbb[numero_color], abb[numero_color], bbb[numero_color]); printf("L_lamp=%2.2f al=%2.2f bl=%2.2f\n", Llamp[numero_color], alamp[numero_color], blamp[numero_color]); } //then calculate DeltaE CIE 1976 - for(int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { DeltaEs[i] = sqrt((Lbb[i] - Llamp[i]) * (Lbb[i] - Llamp[i]) + (abb[i] - alamp[i]) * (abb[i] - alamp[i]) + (bbb[i] - blamp[i]) * (bbb[i] - blamp[i])); } - for(int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { CRIs[i] = 100 - 3.f * DeltaEs[i]; //3.0 coef to adapt ==> same results than CRI "official" } - for(int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { CRI_RTs += CRIs[i]; } CRI_RTs /= 8; - for(int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) { quadCRIs += (CRIs[i] - CRI_RTs) * (CRIs[i] - CRI_RTs); } quadCRIs /= 8; - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { DeltaE[i] = sqrt((Lbb[i] - Llamp[i]) * (Lbb[i] - Llamp[i]) + (abb[i] - alamp[i]) * (abb[i] - alamp[i]) + (bbb[i] - blamp[i]) * (bbb[i] - blamp[i])); } - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { CRI[i] = 100 - 3.f * DeltaE[i]; //3.0 coef to adapt ==> same results than CRI "official" } - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { CRI_RT += CRI[i]; } CRI_RT /= N_c; - for(int i = 0; i < N_c; i++) { + for (int i = 0; i < N_c; i++) { quadCRI += (CRI[i] - CRI_RT) * (CRI[i] - CRI_RT); } quadCRI /= N_c; - if(settings->CRI_color != 0) { + if (settings->CRI_color != 0) { printf("CRI_standard=%i CRI:1->8=%i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RTs, (int) CRIs[0], (int) CRIs[1], (int) CRIs[2], (int) CRIs[3], (int) CRIs[4], (int) CRIs[5], (int) CRIs[6], (int) CRIs[7], sqrt(static_cast(quadCRIs))); printf("CRI_RT_exten=%i CRI:9->20=%i %i %i %i %i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RT, (int) CRI[8], (int) CRI[9], (int) CRI[10], (int) CRI[11], (int) CRI[12], (int) CRI[13], (int) CRI[14], (int) CRI[15], (int) CRI[16], (int) CRI[17], (int) CRI[18], (int) CRI[19], static_cast(sqrt(quadCRI))); } @@ -3400,6 +5020,7 @@ double ColorTemp::blackbody_spect(double wavelength, double temperature) const double wlm = wavelength * 1e-9; /* Wavelength in meters */ return (3.7417715247e-16 / rtengine::pow5(wlm)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light (xexp(1.438786e-2 / (wlm * temperature)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant + } /* @@ -3427,6 +5048,7 @@ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, doub for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = daylight_spect(lambda, _m1, _m2); + // printf("Day Me=%f \n", Me); X += Me * color_match[i][0]; Y += Me * color_match[i][1]; Z += Me * color_match[i][2]; @@ -3526,7 +5148,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match) { int i; - double lambda, X = 0, Y = 0, Z = 0; + double lambda, X = 0, Y = 0, Z = 0, Yo = 0; for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; @@ -3536,16 +5158,67 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double Z += Mc * color_match[i][2] * Me; } - xx = X / Y; - yy = 1.0; - zz = Z / Y; + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + const double Mc1 = daylight_spect(lambda, _m1, _m2); + Yo += color_match[i][1] * Mc1; + } + + xx = X / Yo; + yy = Y / Yo; + zz = Z / Yo; } -//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 +void ColorTemp::whitepoint(double tempw, double &xx, double &yy, double &zz, const color_match_type &color_match) +{ + if (tempw <= INITIALBLACKBODY) { + spectrum_to_whitepoint_xyz_blackbody(tempw, xx, yy, zz, color_match); + } else { + double m11, m22, x_DD, y_DD, interm2; + + if (tempw <= 7000) { + x_DD = -4.6070e9 / (tempw * tempw * tempw) + 2.9678e6 / (tempw * tempw) + 0.09911e3 / tempw + 0.244063; + } else { + x_DD = -2.0064e9 / (tempw * tempw * tempw) + 1.9018e6 / (tempw * tempw) + 0.24748e3 / tempw + 0.237040; + } + + y_DD = -3.0 * x_DD * x_DD + 2.87 * x_DD - 0.275; + //calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D + //S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda) + interm2 = (0.0241 + 0.2562 * x_DD - 0.734 * y_DD); + m11 = (-1.3515 - 1.7703 * x_DD + 5.9114 * y_DD) / interm2; + m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; + + spectrum_to_whitepoint_xyz_daylight(m11, m22, xx, yy, zz, color_match); + } +} + +void ColorTemp::spectrum_to_whitepoint_xyz_daylight(double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match) +{ + int i; + double lambda, X = 0, Z = 0, Yo = 0; + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + const double Mc = daylight_spect(lambda, _m1, _m2); + X += Mc * color_match[i][0]; + Z += Mc * color_match[i][2]; + } + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + const double Mc1 = daylight_spect(lambda, _m1, _m2); + Yo += color_match[i][1] * Mc1; + } + + xx = X / Yo; + yy = 1.; + zz = Z / Yo; +} + +//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 bug found 4/2023 void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match) { int i; - double lambda, X = 0, Y = 0, Z = 0; + double lambda, X = 0, Y = 0, Z = 0, Yo = 0; for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { const double Me = spec_color[i]; @@ -3555,11 +5228,39 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double Z += Mc * color_match[i][2] * Me; } - xx = X / Y; - yy = 1.0; - zz = Z / Y; + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + const double Mc1 = blackbody_spect(lambda, _temp); + Yo += color_match[i][1] * Mc1; + } + + xx = X / Yo; + yy = Y / Yo; + zz = Z / Yo; } +void ColorTemp::spectrum_to_whitepoint_xyz_blackbody(double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match) +{ + int i; + double lambda, X = 0, Z = 0, Yo = 0; + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + const double Mc = blackbody_spect(lambda, _temp); + X += Mc * color_match[i][0]; + Z += Mc * color_match[i][2]; + } + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + const double Mc1 = blackbody_spect(lambda, _temp); + Yo += color_match[i][1] * Mc1; + } + + xx = X / Yo; + yy = 1.; + zz = Z / Yo; +} + + + double ColorTemp::daylight_spect(double wavelength, double m1, double m2) { //Values for Daylight illuminant: s0 s1 s2 @@ -3581,17 +5282,116 @@ double ColorTemp::daylight_spect(double wavelength, double m1, double m2) 9.60, 9.05, 8.50, 7.75, 7.00, 7.30, 7.60, 7.80, 8.00, 7.35, 6.70, 5.95, 5.20, 6.30, 7.40, 7.10, 6.80, 6.90, 7.00, 6.70, 6.40, 5.95, 5.50, 5.80, 6.10, 6.30, 6.50 }; - int wlm = (int) ((wavelength - 350.) / 5.); + int wlm = (int)((wavelength - 350.) / 5.); return (s0[wlm] + m1 * s1[wlm] + m2 * s2[wlm]); } -//tempxy : return x and y of xyY for 200 or more refreence color, and for T temperature from 2000K to 12000K + + +//tempxy : return x and y of xyY for 406 or more refreence color, and for T temperature from 2000K to 12000K // we can change step for temperature and increase number for T > 7500K if necessary //these values Temp, x, y are references for all calculations and very precise. -//copyright J.Desmis august 2017 and june 2018 -void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar) +//copyright J.Desmis august 2017 and june 2018 - 05/2023 +void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar, int ttbeg, int ttend, double &wpx, double &wpz, double *WPX, double *WPZ) { const double* spec_colorforxcyc[] = {//color references + JDC468_BluH10_spect, JDC468_BluD6_spect, ColorchechCyaF3_spect, JDC468_BluM5_spect, // 0 3 + ColorGreenM25_spect, JDC468_GreK7_spect, ColabSky42_0_m24_spect, ColabSky60_0_m31_spect, ColorchechBluC150_m5_m22_spect,//8 + JDC468_GreQ7_spect, ColorchechDCBluN881_m7_m14_spect, ColorchechGreB3_spect, ColorchechPurD2_spect, //12 + ColorchechSGBlaN3_6_spect, ColorchechGraC4_67_spect, JDC468_K15_87greyspect,//15 + JDC468_GraK14_44_spect, ColorGreenalsi_spect, Fictif_61greyspect, ColorchechGreD1_spect,//19 + ColorchechWhiA496_spect, JDC468_GreA10_spect, JDC468_GreI8_spect,//22 + ColabSkin91_4_14_spect, JDC468_PurE24_spect, //24 + ColorchechSGSkiK285_11_17_spect, ColorchechGreE2_spect, ColorchechMagE3_spect, //27 + ColorchechSkiB166_18_18_spect, ColabSkin70_7_32_spect, ColorchechSGSkiF763_14_26_spect,//30 + ColorchechSkiA138_13_14_spect, ColabSkin57_22_18_spect, JDC468_YelN10_spect,//33 + ColabSkin35_15_17_spect, ColabSkin40_17_17_spect, ColorRedkurttu_spect, ColorYellowkeltano_spect, ColorchechYelD3_spect, JDC468_OraO18_spect,//39 + JDC468_GreN7_spect, JDC468_RedG21va_spect, JDC468_OraD17_spect,//42 + ColorchechredC3_spect, JDC468_RedI9_spect, ColorRedpetunia_spect, ColorchechOraA2_spect,//46 + ColabSkin87_8_8_spect, ColabSkin89_8_21_spect, ColabSkin75_8_4_spect, ColabSkin75_10_33_spect,//50 + ColabSkin65_33_11_spect, ColabSkin65_7_24_spect, ColabSkin57_19_6_spect, ColabSkin57_4_19_spect, ColabSkin57_10_28_spect, ColabSkin40_17_6_spect,//56 + ColabSkin26_18_18_spect, ColabSkin90_m1_20_spect, ColorRedlupiini_spect, ColorRedhevosminttu_spect, //60 + ColorRedneilikka_spect, ColorRedpelagornia_spect, ColorRedtalvio_spect, ColorBrownpoimulehti_spect, ColorOrangetuntematon_spect,//65 + ColorOrangetlehmus_spect, ColorOrangvaahtera_spect, ColorBrownlehmus_spect, ColorBrownuotiosammal_spect,//69 + ColorBlacksoil_spect, ColorGraynahjajaekaelae_spect, //71 + ColorGreennuotisammal_spect, ColorGreenleskenlehti_spect, ColorGreenlinnunkaali_spect, //74 + ColorGreenpelto_spect, ColorGreenrodvoikukka, ColorGreenlehmus, ColorGreenlinden, ColorYellowlehmus, ColorYellowsuikeroalpi, //80 + ColorYellowpensashanhikki1, ColorYellowpensashanhikki2, ColorBluehiidenvirna, ColorBluekurkkuyrtti, //84 + ColorPinksiankaersaemoe, ColorVioletharakankello, ColorVioletalsikeapila, ColorVioletakilleija, ColorOrangekehaekukka,//89 + ColorRedpihlaja, ColorVioletpetunia, ColorVioletorvokki, ColorBluesinisievikki, ColorBlueiisoppi, ColorBluelobelia, //95 + ColorWhiteojaka, ColorWhitepetunia, ColorWhitepelargonia, ColorWhitepaeivaen, JDC468_B14_75Redspect,//100 + ColorGreenkoriste, ColorGreenpoimulehti, ColorGreenhopeapaju, //103 + ColorReduuden, ColorRedpajuan, ColorRedjaloan, ColorBlueukon, ColorBlueorvokki, ColorBluemalvikki, //109 + ColorBlackmaito, ColorOrangpihlaja, ColorBlackpihlaja, //112 + ColorViolA1_spect, ColorViolA4_spect, ColorViolA6_spect, ColorBlueSkyK3_spect, ColorBlueSkyK9_spect, //117 + ColorBlueSkyC4_spect, ColorBlueSkyC14_spect, ColorBlueSkyE4_spect, //120 + ColorBlueSkyM1_spect, ColorBlueSky2B1_spect, ColorBlueSkyT7_spect, //123 + ColorBlueSkyU19_spect, ColorBlueSkyU2_spect, ColorBlueSkyT17_spect, //126 + ColorBlackM8_spect, ColorBlackM12_spect, ColorBlackM13_spect, ColorWhite2B12_spect, ColorWhite2B14_spect, //131 + JDC468_Blackred97_spect, JDC468_Blackredbl443_spect, JDC468_Blackbl27_spect, JDC468_Blackbl28_spect, //135 + JDC468_Blackgr214_spect, JDC468_Blackbl436_spect, JDC468_Whitebl455_spect, JDC468_Blackvio101_spect, JDC468_Whitebl92_spect, JDC468_Greyredbl94_spect, //141 + JDC468_Blue32_spect, JDC468_Blue236_spect, JDC468_Gre300_spect, //144 + JDC468_Blue340_spect, JDC468_Gree110_spect, JDC468_Gree457_spect, JDC468_Yel241_spect, JDC468_Ora321_spect, JDC468_Yellow353_spect, JDC468_Mag465_spect, //151 + JDC468_Mag333_spect, JDC468_Mag203_spect, J570_BlueB6_spect, J570_BlueB15_spect, J570_BlueC2_spect, J570_BlueC14_spect, J570_BlueC16_spect,//158 + J570_BlueF1_spect, J570_BlueF2_spect, J570_BlueF10_spect, J570_BlueF13_spect, J570_BlueG9_spect, J570_BlueG19_spect, J570_BlueI5_spect,//165 + J570_BlueI3_spect, J570_BlueI19_spect, J570_BlueJ4_spect, J570_BlueJ6_spect, J570_BlueJ11_spect, J570_BlueK5_spect, //171 + J570_BlueN1_spect, J570_BlueN4_spect, J570_BlueO19_spect, J570_BlueU8_spect, J570_NeuN8_spect,//176 + J570_NeuN9_spect, J570_NeuO8_spect, J570_NeuO11_spect, J570_NeuD5_spect,//180 + J570_NeuE11_spect, J570_NeuK16_spect, J570_NeuM3_spect, J570_NeuN18_spect, J570_NeuQ1_spect, J570_NeuS7_spect, J570_NeuV10_spect, J570_NeuW18_spect, J570_NeuZ14_spect, //189 + J570_NeuC18_spect, J570_NeuD17_spect, J570_NeuJ11_spect, J570_NeuL4_spect, Colorlab_n72_n2_spect,//194 + Colorlab_10_n70_spect, Colorlab_n33_n70_spect, Colorlab_n8_n74_spect, Colorlab_19_n69_spect, Colorlab_n80_10_spect, Colorlab_n80_26_spect,//200 + Colorlab_n80_5_9_5_9spect, /* JDC468_greyc14_66_spect, JDC468_greym13_325_spect, JDC468_greyf26_156_spect, Colorlab_n57_5_6_9spect,*/ Colorlab_L61_110_110Rec2020spect,//202 + Colorlab_L63_120_m56Rec2020spect, Colorlab_L63_m50_m60Rec2020spect, Colorlab_L63_m120_80Rec2020spect, Colorlab_L42_110_m100Prospect, Colorlab_L42_m70_m100Prospect,//207 + Colorlab_L56_m120_90Prospect, Colorlab_L25_60_m120Prospect, Colorlab_L75_50_120Prospect, Colorlab_L75_m120_0Prospect, J570_NeuN8_spect2, J570_NeuN9_spect2, //213 + J570_NeuO8_spect2, J570_NeuO11_spect2, J570_NeuD5_spect2, J570_NeuE11_spect2, J570_NeuK16_spect2, J570_NeuM3_spect2, Colorlab_L22_2_1_3Prospect,//220 + Colorlab_L44_2_8_3_9spect, Colorlab_L44_2_8_3_9spect2, Colorlab_L95_2_3_15_6spect, Colorlab_L95_2_3_15_6spect2, Colorlab_L40_3_5_10_7spect,//225 + Colorlab_L40_3_5_10_7spect2, /*Colorlab_L40_3_5_10_7Prospect3,*/ Colorlab_L34_1_8_1_9spect, Colorlab_L34_1_8_1_9spect2, Colorlab_L64_1_8_m1_9spect,//229 + Colorlab_L84_0_8_m1spect, Colorlab_L63_1_3_m2spect, Colorlab_L44_2_3_m3spect, Colorlab_L65_96_45spect, Colorlab_L52_47_57spect, Colorlab_L31_62_27spect, //235 + Colorlab_L79_m9_m28spect, Colorlab_L58_50_31spect, Colorlab_L31_m52_27spect, Colorlab_L44_2_2_m7_35spect, Colorlab_L47_m10_8_0_41spect, Colorlab_L32_4_8_m3_2spect,//241 + Colorlab_L57_m6_9_2_9spect, Colorlab_L33_2_4_m4_5spect, Colorlab_L35_11_65_m1_1spect, Colorlab_L52_m2_7_8_9spect, Colorlab_L32_7_m2_5spect, Colorlab_L32_3_4_m3_8spect,//247 + Colorlab_L50_m5_3_6_5spect, Colorlab_L44_3_96_m8_8spect, Colorlab_L34_3_6_m5_4spect, Colorlab_L31_5_9_m4spect, Colorlab_L35_3_4_m11spect, Colorlab_L31_4_5_m4_7spect, //253 + Colorlab_L35_4_8_m6_4spect, Colorlab_L95_10_7_m14_3spect, Colorlab_L36_34_m7_5spect, Colorlab_L37_59_2spect, Colorlab_L69_14_m9spect, Colorlab_L92_13_m16spect,//259 + Colorlab_L49_21_m12spect, Colorlab_L56_20_m15spect, Colorlab_L68_21_m19spect, //262 + Colorlab_L98_m2_m32spect, Colorlab_L98_m2_m32spect2, Colorlab_L41_m27_m16spect, Colorlab_L41_m27_m16spect2, Colorlab_L15_m9_4spect, Colorlab_L15_m9_4spect2,//268 + Colorlab_L11_m11_2spect, Colorlab_L14_m4_3spect, Colorlab_L41_38_24spect, Colorlab_L41_38_24spect2, Colorlab_L53_48_58spect, Colorlab_L53_48_58spect2,//274 + Colorlab_L70_44_86spect, Colorlab_L70_44_86spect2, Colorlab_L38_42_19spect, Colorlab_L38_42_19spect2, //278 + Colorlab_L60_63_85spect, Colorlab_L60_63_85spect2, Colorlab_L80_75_30spect, Colorlab_L80_75_30spect2, Colorlab_L28_m21_24spect,//284 + Colorlab_L45_m33_47spect, Colorlab_L45_m33_47spect2, Colorlab_L26_m7_404spect, Colorlab_L34_m61_2spect, Colorlab_L32_m16_17spect, Colorlab_L30_m19_15spect, + Colorlab_L30_m17_16spect, Colorlab_L35_m8_4spect, Colorlab_L37_m7_5spect, Colorlab_L45_m7_2spect, Colorlab_L40_m6_5spect, Colorlab_L46_m6_2spect, Colorlab_L48_m69_16spect, + Colorlab_L51_89_53spect, Colorlab_L49_84_33spect, Colorlab_L59_m51_31spect, Colorlab_L48_m69_16spect2, Colorlab_L53_m71_6spect, Colorlab_L51_m89_53spect2, + Colorlab_L49_84_33spect2, Colorlab_L36_m27_28spect, Colorlab_L36_m27_28spect2, Colorlab_L36_m27_28spect3, Colorlab_L63_16_71spect, + Colorlab_L84_4_46spect, Colorlab_L84_4_46spect2, Colorlab_L75_m66_19spect, Colorlab_L75_m66_19spect2, Colorlab_L64_m82_m6spect, Colorlab_L64_m82_m6spect2, + Colorlab_L66_m71_m17spect, Colorlab_L66_m71_m17spect2, Colorlab_L22_m8_m60spect, //317 + Colorlab_L22_m8_m60spect2, Colorlab_L15_m4_m42spect, Colorlab_L15_m4_m42spect2, Colorlab_L13_3_m23spect, Colorlab_L27_4_m90spect, Colorlab_L19_1_m29spect, + Colorlab_L27_4_m90spect2, Colorlab_L16_0_m44spect, Colorlab_L16_0_m44spect2, Colorlab_L13_m3_m36spect, Colorlab_L13_m3_m36spect2, + Colorlab_L31_m23_m60spect, Colorlab_L31_m23_m60spect2, Colorlab_L17_3_m40spect, Colorlab_L17_3_m40spect2, Colorlab_L21_9_m7spect, Colorlab_L78_4_m74spect, + Colorlab_L31_m58_m66spect, Colorlab_L61_m11_m12spect, Colorlab_L61_m11_m12spect2, Colorlab_L29_1_m13spect, Colorlab_L29_1_m13spect2, Colorlab_L2_14_m1spect, //339 + Colorlab_L5_39_m7spect, Colorlab_L15_5_m13spect, Colorlab_L12_5_m6spect, Colorlab_L12_5_m6spect2, Colorlab_L37_m59_m24spect, Colorlab_L37_m59_m24spect2,//345 + Colorlab_L15_55_23spect, Colorlab_L11_m55_m11spect, Colorlab_L8_m10_m2spect, Colorlab_L14_m10_m7spect, Colorlab_L20_m16_m13spect, Colorlab_L8_m10_m2spect2, Colorlab_L14_m10_m7spect2, Colorlab_L20_m16_m13spect2, //353 + Colorlab_L6_m9_1spect, Colorlab_L20_m9_m10spect, Colorlab_L85_10_45spect, Colorlab_L90_m7_82spect, Colorlab_L95_2_18spect, + Colorlab_L39_7_4spect, Colorlab_L39_4_1spect, Colorlab_L39_3_m1spect, Colorlab_L40_3_m2spect, Colorlab_L36_2_2spect, + Colorlab_L39_7_4spect2, Colorlab_L39_4_1spect2, Colorlab_L39_3_m1spect2, Colorlab_L40_3_m2spect2, Colorlab_L36_2_2spect2, //369 + Colorlab_L40_4_m2spect, Colorlab_L41_1_m6spect, Colorlab_L40_4_m2spect2, Colorlab_L41_1_m6spect2, Colorlab_L41_12_14spect, Colorlab_L41_12_14spect2, + Colorlab_L10_0_m22spect, Colorlab_L38_60_8spect, Colorlab_L49_85_39spect, Colorlab_L42_1_m18spect, //379 + Colorlab_L48_19_m25spect, Colorlab_L30_21_m25spect, Colorlab_L15_10_m15spect, Colorlab_L48_19_m25spect2, Colorlab_L30_21_m25spect2, Colorlab_L15_10_m15spect2, + Colorlab_L60_26_m25spect, Colorlab_L40_26_m45spect, Colorlab_L20_10_m45spect, //388 + ColorBlueSkyK3_spect2, ColorBlueSkyK9_spect2, ColorBlueSkyC4_spect2, ColorBlueSkyC14_spect2, ColorBlueSkyE4_spect2, + ColorBlueSkyM1_spect2, ColorBlueSky2B1_spect2, ColorBlueSkyT7_spect2, ColorBlueSkyU19_spect2, ColorBlueSkyU2_spect2, + Colorlab_L40_1_m40spect, Colorlab_L30_4_m30spect, Colorlab_L8_11_m25spect, Colorlab_L40_1_m40spect2, Colorlab_L30_4_m30spect2, Colorlab_L8_11_m25spect2, + Colorlab_L26_m8_m25spect, Colorlab_L26_m8_m25spect2, //406 + Colorlab_L17_3_m40spect3, Colorlab_L17_3_m40spect4, Colorlab_L17_3_m40spect5, Colorlab_L40_26_m45spect2, Colorlab_L17_3_m40spect6, ColorchechCyaF3_spect2, ColorchechCyaF3_spect3, + Colorlab_L22_1_m42spect, Colorlab_L27_m1_m47spect, Colorlab_L26_m8_m25spect3, Colorlab_L22_1_m42spect2, Colorlab_L27_m1_m47spect2, + Colorlab_L40_30_m30spect, Colorlab_L40_20_m35spect, Colorlab_L20_10_m45spect2, Colorlab_L20_10_m45spect3, + Colorlab_L40_30_m30spect2, Colorlab_L40_20_m35spect2, Colorlab_10_n70_spect2, Colorlab_L22_1_m42spect3, Colorlab_10_n70_spect3, Colorlab_L22_1_m42spect4, Colorlab_10_n70_spect4 + //J570_NeuN18_spect2, J570_NeuQ1_spect2 //J570_NeuS7_spect2, J570_NeuV10_spect2, J570_NeuW18_spect2, + //J570_NeuZ14_spect2, + //J570_NeuC18_spect2, + //J570_NeuD17_spect2, + //J570_NeuJ11_spect2, + //J570_NeuL4_spect2 + };// + + const double* spec_colorforxcyc_old[] = {//color references for 5.9 JDC468_BluH10_spect, JDC468_BluD6_spect, ColorchechCyaF3_spect, JDC468_BluM5_spect, // 0 3 ColorGreenM25_spect, JDC468_GreK7_spect, ColabSky42_0_m24_spect, ColabSky60_0_m31_spect, ColorchechBluC150_m5_m22_spect,//8 JDC468_GreQ7_spect, ColorchechDCBluN881_m7_m14_spect, ColorchechGreB3_spect, ColorchechPurD2_spect, //12 @@ -3641,17 +5441,212 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float Colorlab_10_n70_spect, Colorlab_n33_n70_spect, Colorlab_n8_n74_spect, Colorlab_19_n69_spect, Colorlab_n80_10_spect, Colorlab_n80_26_spect, Colorlab_n80_5_9_5_9spect //, Colorlab_n57_5_6_9spect - /*JDC468_greyc14_66_spect, JDC468_greym13_325_spect, JDC468_greyf26_156_spect*/ }; + typedef struct WbTxyz { double Tem; double XX; double ZZ; } WbTxyz; //probably can be "passed" with rawimagesource.cc but I don't know how to do this. - constexpr WbTxyz Txyz[118] = {//temperature Xwb Zwb 118 values - same table as in Rawimagesource.cc x wb and y wb are calculated after + constexpr WbTxyz Txyz[191] = {//temperature Xwb Zwb 191 values - same table as in Rawimagesource.cc x wb and y wb are calculated after + {2001., 1.273842, 0.145295}, + {2051., 1.258802, 0.156066}, + {2101., 1.244008, 0.167533}, + {2151., 1.230570, 0.178778}, + {2201., 1.217338, 0.190697}, + {2251., 1.205305, 0.202338}, + {2301., 1.193444, 0.214632}, + {2351., 1.182648, 0.226598}, + {2401., 1.171996, 0.239195}, + {2451., 1.162290, 0.251421}, + {2501., 1.152883, 0.264539}, + {2551., 1.143965, 0.276682}, + {2605., 1.134667, 0.290722}, + {2655., 1.126659, 0.303556}, + {2705., 1.119049, 0.316446}, + {2755., 1.111814, 0.329381}, + {2790., 1.106961, 0.338455}, + {2803., 1.105381, 0.342193}, + {2825., 1.102275, 0.347542}, + {2856., 1.098258, 0.355599}, + {2880., 1.095233, 0.361840}, + {2910., 1.091550, 0.369645}, + {2930., 1.089155, 0.374849}, + {2960., 1.085649, 0.382655}, + {2980., 1.083369, 0.387858}, + {3003., 1.080982, 0.394258}, + {3025., 1.078397, 0.399561}, + {3050., 1.075727, 0.406057}, + {3075., 1.073122, 0.412550}, + {3103., 1.070277, 0.419815}, + {3128., 1.067801, 0.426296}, + {3153., 1.065384, 0.432769}, + {3175., 1.063305, 0.438459}, + {3203., 1.060906, 0.446161}, + {3225., 1.058738, 0.451367}, + {3250., 1.056535, 0.457806}, + {3280., 1.053960, 0.465519}, + {3303., 1.052034, 0.471422}, + {3353., 1.047990, 0.484218}, + {3400., 1.044547, 0.496719}, + {3450., 1.040667, 0.508891}, + {3500., 1.037145, 0.521523}, + {3550., 1.033783, 0.534090}, + {3600., 1.030574, 0.546590}, + {3650., 1.027510, 0.559020}, + {3699., 1.024834, 0.571722}, + {3801., 1.019072, 0.596102}, + {3851., 1.016527, 0.608221}, + {3902., 1.014244, 0.621136}, + {3952., 1.011729, 0.632447}, + {4002., 0.996153, 0.609518}, + {4052., 0.993720, 0.620805}, + {4102., 0.993908, 0.631520}, + {4152., 0.989179, 0.643262}, + {4202., 0.989283, 0.653999}, + {4252., 0.985039, 0.665536}, + {4302., 0.985067, 0.676288}, + {4352., 0.981271, 0.687599}, + {4402., 0.981228, 0.698349}, + {4452., 0.977843, 0.709425}, + {4502., 0.977736, 0.720159}, + {4552., 0.974728, 0.730993}, + {4602., 0.974562, 0.741698}, + {4652., 0.971899, 0.752284}, + {4702., 0.971681, 0.762949}, + {4752., 0.969335, 0.773285}, + {4802., 0.969069, 0.783899}, + {4827., 0.967570, 0.788836}, + {4852., 0.967011, 0.793982}, + {4877., 0.966465, 0.799108}, + {4902., 0.965933, 0.804214}, + {4914., 0.965682, 0.806658}, + {4927., 0.965414, 0.809229}, + {4940., 0.965149, 0.811937}, + {4952., 0.964908, 0.814366}, + {4965., 0.964650, 0.816993}, + {4977., 0.964415, 0.819412}, + {4990., 0.964163, 0.822028}, + {5002., 0.963934, 0.824438},//80 + {5015., 0.963689, 0.827044}, + {5027., 0.963465, 0.829444}, + {5040., 0.963226, 0.832039}, + {5051., 0.963008, 0.834429}, + {5065., 0.963226, 0.832039}, + {5077., 0.962563, 0.839395}, + {5090., 0.962336, 0.841968}, + {5102., 0.962129, 0.844339}, + {5115., 0.961907, 0.846902}, + {5127., 0.961706, 0.849263}, + {5140., 0.961490, 0.851815}, + {5151., 0.961294, 0.854166}, + {5177., 0.960893, 0.859049}, + {5202., 0.960501, 0.863911}, + {5253., 0.959749, 0.873572}, + {5302., 0.959313, 0.883815}, + {5351., 0.958361, 0.892644}, + {5402., 0.957903, 0.902793}, + {5452., 0.957116, 0.911379}, + {5502., 0.956639, 0.921431}, + {5553., 0.956002, 0.929779}, + {5602., 0.955509, 0.939728}, + {5652., 0.955008, 0.947842}, + {5702., 0.954502, 0.957685}, + {5752., 0.954124, 0.965569}, + {5802., 0.953608, 0.975303}, + {5852., 0.953342, 0.982963}, + {5902., 0.952818, 0.992584}, + {5952., 0.952652, 1.000025}, + {6002., 0.952122, 1.009532}, + {6052., 0.952047, 1.016759}, + {6102., 0.951514, 1.026149}, + {6152., 0.951520, 1.033168}, + {6202., 0.950985, 1.042439}, + {6252., 0.951064, 1.049256}, + {6302., 0.950530, 1.058406}, + {6352., 0.950674, 1.065027}, + {6380., 0.950576, 1.069386}, + {6402., 0.950143, 1.074055}, + {6425., 0.950428, 1.076341}, + {6452., 0.950345, 1.080484}, + {6475., 0.950277, 1.083996}, + {6502., 0.950201, 1.088097}, + {6525., 0.950139, 1.091573}, + {6552., 0.950070, 1.095633}, + {6575., 0.950014, 1.099075}, + {6602., 0.949952, 1.103094}, + {6625., 0.949902, 1.106501}, + {6652., 0.949846, 1.110479}, + {6675., 0.949801, 1.113852}, + {6702., 0.949752, 1.119138}, + {6725., 0.949712, 1.121128}, + {6752., 0.949668, 1.125027}, + {6802., 0.949596, 1.132190}, + {6852., 0.949533, 1.139281}, + {6902., 0.949033, 1.147691}, + {6952., 0.949437, 1.153246}, + {7002., 0.949402, 1.160129}, + {7052., 0.949376, 1.166966}, + {7102., 0.949358, 1.173732}, + {7152., 0.949348, 1.180429}, + {7202., 0.949346, 1.187058}, + {7252., 0.949350, 1.193619}, + {7301., 0.948896, 1.201432}, + {7352., 0.949380, 1.206541}, + {7402., 0.949405, 1.212904}, + {7451., 0.949434, 1.219076}, + {7501., 0.949471, 1.225312}, + {7551., 0.949512, 1.231485}, + {7601., 0.949099, 1.239061}, + {7675., 0.949638, 1.246525}, + {7751., 0.949729, 1.255559}, + {7825., 0.949828, 1.264225}, + {7901., 0.949498, 1.274460}, + {7952., 0.950018, 1.278800}, + {8025., 0.950137, 1.287013}, + {8095., 0.950259, 1.294777}, + {8151., 0.950361, 1.300912}, + {8225., 0.950501, 1.308915}, + {8301., 0.950253, 1.318464}, + {8375., 0.950804, 1.324786}, + {8451., 0.950966, 1.332651}, + {8525., 0.951129, 1.340199}, + {8601., 0.950941, 1.349261}, + {8701., 0.951533, 1.357724}, + {8801., 0.951772, 1.367421}, + {8901., 0.952018, 1.376935}, + {9001., 0.951969, 1.387639}, + {9201., 0.952784, 1.404422}, + {9401., 0.953081, 1.423213},//since 5 2023 I increased the number of temp references above 9401K + {9651., 0.953993, 1.442883}, + {9901., 0.954537, 1.464134}, + {10201., 0.955520, 1.485825}, + {10501., 0.956321, 1.508623}, + {10751., 0.957057, 1.524806}, + {11001., 0.957747, 1.541281}, + {11251., 0.958436, 1.557207}, + {11501., 0.959112, 1.572366}, + {11751., 0.959784, 1.587037}, + {12001., 0.960440, 1.601019},//since 5 2023 I increased the number of temp references above 12000K + {12251., 0.961090, 1.614566}, + {12501., 0.963963, 1.627492}, + {12751., 0.962350, 1.640031}, + {13001., 0.962962, 1.652055}, + {13251., 0.963561, 1.663638}, + {13501., 0.964147, 1.674804}, + {13751., 0.964720, 1.685571}, + {14001., 0.965279, 1.695919}, + {14251., 0.965827, 1.705950}, + {14501., 0.966363, 1.715637}, + {14751., 0.966886, 1.724998}, + {15001., 0.967397, 1.734047} + }; + + //compatibility 5.9 + constexpr WbTxyz Txyzs[118] = {//temperature Xwb Zwb 118 values - same table as in Rawimagesource.cc x wb and y wb are calculated after for 5.9 {2001., 1.273842, 0.145295}, {2101., 1.244008, 0.167533}, {2201., 1.217338, 0.190697}, @@ -3773,12 +5768,28 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float }; int N_c = sizeof(spec_colorforxcyc) / sizeof(spec_colorforxcyc[0]); //number of color + + if (wbpar.itcwb_sampling) { + N_c = sizeof(spec_colorforxcyc_old) / sizeof(spec_colorforxcyc_old[0]); //number of color 5.9 + } + + int N_t = sizeof(Txyz) / sizeof(Txyz[0]); //number of temperature White point + + if (wbpar.itcwb_sampling) { + N_t = sizeof(Txyzs) / sizeof(Txyzs[0]); //number of temperature White point 5.9 + } + + if (settings->verbose) { + printf("Number max spectral colors=%i Number sampling temp=%i\n", N_c, N_t); + } + typedef struct XYZref { double Xref; double Yref; double Zref; } XYZref; + XYZref Refxyz[N_c + 1]; for (int i = 0; i < N_c; i++) { @@ -3787,16 +5798,33 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float Refxyz[i].Zref = 0.f; } - const color_match_type &color_match = (wbpar.observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; - - // const color_match_type &color_match = (wbpar.observer == StandardObserver::TEN_DEGREES) ? cie_colour_match_jd : cie_colour_match_jd2; + bool observerchoice = false; + + observerchoice = (wbpar.observer == StandardObserver::TEN_DEGREES); + + if (wbpar.itcwb_sampling) { + observerchoice = false; + } + + const color_match_type &color_match = observerchoice ? cie_colour_match_jd : cie_colour_match_jd2; if (separated) { - const double tempw = Txyz[repref].Tem; + double tempw = Txyz[repref].Tem; + + if (wbpar.itcwb_sampling) { + tempw = Txyzs[repref].Tem; + } + + double yy = 0.; + whitepoint(tempw, wpx, yy, wpz, color_match); if (tempw <= INITIALBLACKBODY) { - for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i], color_match); + for (int i = 0; i < N_c; i++) { + if (! wbpar.itcwb_sampling) { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i], color_match); + } else { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc_old[i], tempw, TX[i], TY[i], TZ[i], color_match); + } } } else { double m11, m22, x_DD, y_DD, interm2; @@ -3815,16 +5843,33 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i], color_match); + if (! wbpar.itcwb_sampling) { + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i], color_match); + } else { + spectrum_to_color_xyz_daylight(spec_colorforxcyc_old[i], m11, m22, TX[i], TY[i], TZ[i], color_match); + } } } } else { - for (int tt = 0; tt < N_t; tt++) { - const double tempw = Txyz[tt].Tem; + for (int tt = ttbeg; tt < ttend; tt++) { + double tempw = Txyz[tt].Tem; + + if (wbpar.itcwb_sampling) { + tempw = Txyzs[repref].Tem; + } + + double yy = 0.; + whitepoint(tempw, wpx, yy, wpz, color_match); + WPX[tt] = wpx; + WPZ[tt] = wpz; if (tempw <= INITIALBLACKBODY) { for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + if (! wbpar.itcwb_sampling) { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + } else { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc_old[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + } } } else { double x_DD; @@ -3843,7 +5888,11 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float const double m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; for (int i = 0; i < N_c; i++) { - spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + if (! wbpar.itcwb_sampling) { + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + } else { + spectrum_to_color_xyz_daylight(spec_colorforxcyc_old[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match); + } } } diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index 0fe56b7cd..db69abe2d 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -56,13 +56,13 @@ private: void temp2mul (double temp, double green, double equal, StandardObserver observer, double& rmul, double& gmul, double& bmul) const; const static std::map spectMap; public: - static constexpr StandardObserver DEFAULT_OBSERVER = StandardObserver::TEN_DEGREES; - + // static constexpr StandardObserver DEFAULT_OBSERVER = StandardObserver::TEN_DEGREES; + static constexpr StandardObserver DEFAULT_OBSERVER = StandardObserver::TWO_DEGREES; ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {} explicit ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} ColorTemp (double t, double g, double e, const std::string &m, StandardObserver o); ColorTemp (double mulr, double mulg, double mulb, double e, StandardObserver observer); - static void tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar); + static void tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar, int ttbeg, int ttend, double &wpx, double &wpz, double *WPX, double *WPZ); void update (const double rmul, const double gmul, const double bmul, const double equal, StandardObserver observer, const double tempBias=0.0) { @@ -169,6 +169,8 @@ public: static const double ColorchechGreE2_spect[97]; static const double ColorchechGreB3_spect[97]; static const double ColorchechCyaF3_spect[97]; + static const double ColorchechCyaF3_spect2[97]; + static const double ColorchechCyaF3_spect3[97]; static const double ColorchechPurD2_spect[97]; static const double ColorchechMagE3_spect[97]; static const double ColorchechSkiA138_13_14_spect[97]; @@ -376,21 +378,259 @@ public: static const double J570_NeuD17_spect[97];//neutral static const double J570_NeuJ11_spect[97];//neutral static const double J570_NeuL4_spect[97];//neutral + + static const double J570_NeuN8_spect2[97];//neutral + static const double J570_NeuN9_spect2[97];//neutral + static const double J570_NeuO8_spect2[97];//neutral + static const double J570_NeuO11_spect2[97];//neutral + static const double J570_NeuD5_spect2[97];//neutral + static const double J570_NeuE11_spect2[97];//neutral + static const double J570_NeuK16_spect2[97];//neutral + static const double J570_NeuM3_spect2[97];//neutral + static const double J570_NeuN18_spect2[97];//neutral + static const double J570_NeuQ1_spect2[97];//neutral + static const double J570_NeuS7_spect2[97];//neutral + static const double J570_NeuV10_spect2[97];//neutral + + static const double J570_NeuW18_spect2[97];//neutral + static const double J570_NeuZ14_spect2[97];//neutral + static const double J570_NeuC18_spect2[97];//neutral + static const double J570_NeuD17_spect2[97];//neutral + static const double J570_NeuJ11_spect2[97];//neutral + static const double J570_NeuL4_spect2[97];//neutral + static const double Colorlab_n72_n2_spect[97]; static const double Colorlab_10_n70_spect[97]; + static const double Colorlab_10_n70_spect2[97]; + static const double Colorlab_10_n70_spect3[97]; + static const double Colorlab_10_n70_spect4[97]; static const double Colorlab_n33_n70_spect[97]; static const double Colorlab_n8_n74_spect[97]; static const double Colorlab_19_n69_spect[97]; static const double Colorlab_n80_10_spect[97]; static const double Colorlab_n80_26_spect[97]; static const double Colorlab_n80_5_9_5_9spect[97]; +// static const double JDC468_greyc14_66_spect[97]; +// static const double JDC468_greym13_325_spect[97]; +// static const double JDC468_greyf26_156_spect[97]; // static const double Colorlab_n57_5_6_9spect[97]; - - /* - static const double JDC468_greyc14_66_spect[97]; - static const double JDC468_greym13_325_spect[97]; - static const double JDC468_greyf26_156_spect[97]; - */ + static const double Colorlab_L61_110_110Rec2020spect[97]; + static const double Colorlab_L63_120_m56Rec2020spect[97]; + static const double Colorlab_L63_m50_m60Rec2020spect[97]; + static const double Colorlab_L63_m120_80Rec2020spect[97]; + static const double Colorlab_L42_110_m100Prospect[97]; + static const double Colorlab_L42_m70_m100Prospect[97]; + static const double Colorlab_L56_m120_90Prospect[97]; + static const double Colorlab_L25_60_m120Prospect[97]; + static const double Colorlab_L75_50_120Prospect[97]; + static const double Colorlab_L75_m120_0Prospect[97]; + static const double Colorlab_L22_2_1_3Prospect[97]; + static const double Colorlab_L44_2_8_3_9spect[97]; + static const double Colorlab_L44_2_8_3_9spect2[97]; + static const double Colorlab_L95_2_3_15_6spect[97]; + static const double Colorlab_L95_2_3_15_6spect2[97]; + static const double Colorlab_L40_3_5_10_7spect[97]; + static const double Colorlab_L40_3_5_10_7spect2[97]; + static const double Colorlab_L40_3_5_10_7spect3[97]; + static const double Colorlab_L34_1_8_1_9spect[97]; + static const double Colorlab_L34_1_8_1_9spect2[97]; + static const double Colorlab_L64_1_8_m1_9spect[97]; + static const double Colorlab_L84_0_8_m1spect[97]; + static const double Colorlab_L63_1_3_m2spect[97]; + static const double Colorlab_L44_2_3_m3spect[97]; + static const double Colorlab_L65_96_45spect[97]; + static const double Colorlab_L52_47_57spect[97]; + static const double Colorlab_L31_62_27spect[97]; + static const double Colorlab_L79_m9_m28spect[97]; + static const double Colorlab_L58_50_31spect[97]; + static const double Colorlab_L31_m52_27spect[97]; + static const double Colorlab_L44_2_2_m7_35spect[97]; + static const double Colorlab_L47_m10_8_0_41spect[97]; + static const double Colorlab_L32_4_8_m3_2spect[97]; + static const double Colorlab_L57_m6_9_2_9spect[97]; + static const double Colorlab_L33_2_4_m4_5spect[97]; + static const double Colorlab_L35_11_65_m1_1spect[97]; + static const double Colorlab_L52_m2_7_8_9spect[97]; + static const double Colorlab_L32_7_m2_5spect[97]; + static const double Colorlab_L32_3_4_m3_8spect[97]; + static const double Colorlab_L50_m5_3_6_5spect[97]; + static const double Colorlab_L44_3_96_m8_8spect[97]; + static const double Colorlab_L34_3_6_m5_4spect[97]; + static const double Colorlab_L31_5_9_m4spect[97]; + static const double Colorlab_L35_3_4_m11spect[97]; + static const double Colorlab_L31_4_5_m4_7spect[97]; + static const double Colorlab_L35_4_8_m6_4spect[97]; + static const double Colorlab_L95_10_7_m14_3spect[97]; + static const double Colorlab_L36_34_m7_5spect[97]; + static const double Colorlab_L37_59_2spect[97]; + static const double Colorlab_L69_14_m9spect[97]; + static const double Colorlab_L92_13_m16spect[97]; + static const double Colorlab_L49_21_m12spect[97]; + static const double Colorlab_L56_20_m15spect[97]; + static const double Colorlab_L68_21_m19spect[97]; + static const double Colorlab_L98_m2_m32spect[97]; + static const double Colorlab_L98_m2_m32spect2[97]; + static const double Colorlab_L41_m27_m16spect[97]; + static const double Colorlab_L41_m27_m16spect2[97]; + static const double Colorlab_L15_m9_4spect[97]; + static const double Colorlab_L15_m9_4spect2[97]; + static const double Colorlab_L11_m11_2spect[97]; + static const double Colorlab_L14_m4_3spect[97]; + static const double Colorlab_L41_38_24spect[97]; + static const double Colorlab_L41_38_24spect2[97]; + static const double Colorlab_L53_48_58spect[97]; + static const double Colorlab_L53_48_58spect2[97]; + static const double Colorlab_L70_44_86spect[97]; + static const double Colorlab_L70_44_86spect2[97]; + static const double Colorlab_L38_42_19spect[97]; + static const double Colorlab_L38_42_19spect2[97]; + static const double Colorlab_L60_63_85spect[97]; + static const double Colorlab_L60_63_85spect2[97]; + static const double Colorlab_L80_75_30spect[97]; + static const double Colorlab_L80_75_30spect2[97]; + static const double Colorlab_L28_m21_24spect[97]; + static const double Colorlab_L28_m21_24spect2[97]; + static const double Colorlab_L45_m33_47spect[97]; + static const double Colorlab_L45_m33_47spect2[97]; + static const double Colorlab_L26_m7_404spect[97]; + static const double Colorlab_L34_m61_2spect[97]; + static const double Colorlab_L32_m16_17spect[97]; + static const double Colorlab_L30_m19_15spect[97]; + static const double Colorlab_L30_m17_16spect[97]; + static const double Colorlab_L35_m8_4spect[97]; + static const double Colorlab_L37_m7_5spect[97]; + static const double Colorlab_L45_m7_2spect[97]; + static const double Colorlab_L40_m6_5spect[97]; + static const double Colorlab_L46_m6_2spect[97]; + static const double Colorlab_L48_m69_16spect[97]; + static const double Colorlab_L51_89_53spect[97]; + static const double Colorlab_L49_84_33spect[97]; + static const double Colorlab_L59_m51_31spect[97]; + static const double Colorlab_L48_m69_16spect2[97]; + static const double Colorlab_L53_m71_6spect[97]; + static const double Colorlab_L51_m89_53spect2[97]; + static const double Colorlab_L49_84_33spect2[97]; + static const double Colorlab_L36_m27_28spect[97]; + static const double Colorlab_L36_m27_28spect2[97]; + static const double Colorlab_L36_m27_28spect3[97]; + static const double Colorlab_L63_16_71spect[97]; + static const double Colorlab_L84_4_46spect[97]; + static const double Colorlab_L84_4_46spect2[97]; + static const double Colorlab_L75_m66_19spect[97]; + static const double Colorlab_L75_m66_19spect2[97]; + static const double Colorlab_L64_m82_m6spect[97]; + static const double Colorlab_L64_m82_m6spect2[97]; + static const double Colorlab_L66_m71_m17spect[97]; + static const double Colorlab_L66_m71_m17spect2[97]; + static const double Colorlab_L22_m8_m60spect[97]; + static const double Colorlab_L22_m8_m60spect2[97]; + static const double Colorlab_L15_m4_m42spect[97]; + static const double Colorlab_L15_m4_m42spect2[97]; + static const double Colorlab_L13_3_m23spect[97]; + static const double Colorlab_L27_4_m90spect[97]; + static const double Colorlab_L19_1_m29spect[97]; + static const double Colorlab_L27_4_m90spect2[97]; + static const double Colorlab_L16_0_m44spect[97]; + static const double Colorlab_L16_0_m44spect2[97]; + static const double Colorlab_L13_m3_m36spect[97]; + static const double Colorlab_L13_m3_m36spect2[97]; + static const double Colorlab_L31_m23_m60spect[97]; + static const double Colorlab_L31_m23_m60spect2[97]; + static const double Colorlab_L17_3_m40spect[97]; + static const double Colorlab_L17_3_m40spect2[97]; + static const double Colorlab_L17_3_m40spect3[97]; + static const double Colorlab_L17_3_m40spect4[97]; + static const double Colorlab_L17_3_m40spect5[97]; + static const double Colorlab_L17_3_m40spect6[97]; + static const double Colorlab_L21_9_m7spect[97]; + static const double Colorlab_L78_4_m74spect[97]; + static const double Colorlab_L31_m58_m66spect[97]; + static const double Colorlab_L61_m11_m12spect[97]; + static const double Colorlab_L61_m11_m12spect2[97]; + static const double Colorlab_L29_1_m13spect[97]; + static const double Colorlab_L29_1_m13spect2[97]; + static const double Colorlab_L2_14_m1spect[97]; + static const double Colorlab_L5_39_m7spect[97]; + static const double Colorlab_L15_5_m13spect[97]; + static const double Colorlab_L12_5_m6spect[97]; + static const double Colorlab_L12_5_m6spect2[97]; + static const double Colorlab_L37_m59_m24spect[97]; + static const double Colorlab_L37_m59_m24spect2[97]; + static const double Colorlab_L15_55_23spect[97]; + static const double Colorlab_L11_m55_m11spect[97]; + static const double Colorlab_L8_m10_m2spect[97]; + static const double Colorlab_L14_m10_m7spect[97]; + static const double Colorlab_L20_m16_m13spect[97]; + static const double Colorlab_L8_m10_m2spect2[97]; + static const double Colorlab_L14_m10_m7spect2[97]; + static const double Colorlab_L20_m16_m13spect2[97]; + static const double Colorlab_L6_m9_1spect[97]; + static const double Colorlab_L20_m9_m10spect[97]; + static const double Colorlab_L85_10_45spect[97]; + static const double Colorlab_L90_m7_82spect[97]; + static const double Colorlab_L95_2_18spect[97]; + static const double Colorlab_L39_7_4spect[97]; + static const double Colorlab_L39_4_1spect[97]; + static const double Colorlab_L39_3_m1spect[97]; + static const double Colorlab_L40_3_m2spect[97]; + static const double Colorlab_L36_2_2spect[97]; + static const double Colorlab_L39_7_4spect2[97]; + static const double Colorlab_L39_4_1spect2[97]; + static const double Colorlab_L39_3_m1spect2[97]; + static const double Colorlab_L40_3_m2spect2[97]; + static const double Colorlab_L36_2_2spect2[97]; + static const double Colorlab_L40_4_m2spect[97]; + static const double Colorlab_L41_1_m6spect[97]; + static const double Colorlab_L40_4_m2spect2[97]; + static const double Colorlab_L41_1_m6spect2[97]; + static const double Colorlab_L41_12_14spect[97]; + static const double Colorlab_L41_12_14spect2[97]; + static const double Colorlab_L10_0_m22spect[97]; + static const double Colorlab_L38_60_8spect[97]; + static const double Colorlab_L49_85_39spect[97]; + static const double Colorlab_L42_1_m18spect[97]; + static const double Colorlab_L48_19_m25spect[97]; + static const double Colorlab_L30_21_m25spect[97]; + static const double Colorlab_L15_10_m15spect[97]; + static const double Colorlab_L48_19_m25spect2[97]; + static const double Colorlab_L30_21_m25spect2[97]; + static const double Colorlab_L15_10_m15spect2[97]; + static const double Colorlab_L60_26_m25spect[97]; + static const double Colorlab_L40_26_m45spect[97]; + static const double Colorlab_L40_26_m45spect2[97]; + static const double Colorlab_L20_10_m45spect[97]; + static const double Colorlab_L20_10_m45spect2[97]; + static const double Colorlab_L20_10_m45spect3[97]; + static const double ColorBlueSkyK3_spect2[97]; + static const double ColorBlueSkyK9_spect2[97]; + static const double ColorBlueSkyC4_spect2[97]; + static const double ColorBlueSkyC14_spect2[97]; + static const double ColorBlueSkyE4_spect2[97]; + static const double ColorBlueSkyM1_spect2[97]; + static const double ColorBlueSky2B1_spect2[97]; + static const double ColorBlueSkyT7_spect2[97]; + static const double ColorBlueSkyU19_spect2[97]; + static const double ColorBlueSkyU2_spect2[97]; + static const double Colorlab_L40_1_m40spect[97]; + static const double Colorlab_L30_4_m30spect[97]; + static const double Colorlab_L8_11_m25spect[97]; + static const double Colorlab_L40_1_m40spect2[97]; + static const double Colorlab_L30_4_m30spect2[97]; + static const double Colorlab_L8_11_m25spect2[97]; + static const double Colorlab_L26_m8_m25spect[97]; + static const double Colorlab_L26_m8_m25spect2[97]; + static const double Colorlab_L26_m8_m25spect3[97]; + static const double Colorlab_L22_1_m42spect[97]; + static const double Colorlab_L22_1_m42spect2[97]; + static const double Colorlab_L22_1_m42spect3[97]; + static const double Colorlab_L22_1_m42spect4[97]; + static const double Colorlab_L27_m1_m47spect[97]; + static const double Colorlab_L27_m1_m47spect2[97]; + static const double Colorlab_L40_30_m30spect[97]; + static const double Colorlab_L40_30_m30spect2[97]; + static const double Colorlab_L40_20_m35spect[97]; + static const double Colorlab_L40_20_m35spect2[97]; + static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z, const color_match_type &color_match); static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z, const color_match_type &color_match); static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z, const color_match_type &color_match); @@ -398,6 +638,9 @@ public: static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match); static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match); static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz, const color_match_type &color_match); + static void spectrum_to_whitepoint_xyz_daylight (double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match); + static void spectrum_to_whitepoint_xyz_blackbody (double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match); + static void whitepoint (double tempw, double &xx, double &yy, double &zz,const color_match_type &color_match); }; } diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index c7bcfc910..82c72a53b 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8675,7 +8675,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { "Olympus E-M5MarkII", 0, 0, { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, - { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } },//D65 +// { 9033,-3597, 26,-2351, 9700, 3111, -181, 807, 5838} },//stDA { "Olympus PEN-F", 0, 0, { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, { "Olympus SH-2", 0, 0, diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h index 5b9883421..be685b676 100644 --- a/rtengine/iccmatrices.h +++ b/rtengine/iccmatrices.h @@ -90,6 +90,19 @@ constexpr double ACESp0_xyz[3][3] = { {0.00845768, -0.01403193, 1.21893277} }; +constexpr double xyz_jdcmax[3][3] = {//prim red 0.734702 0.265302 gr 0.021908 0.930288 bl 0.120593 0.001583 + {0.8394088, 0.0163780, 0.1084133}, + {0.3031122, 0.6954651, 0.0014227}, + {-0.000048, 0.0357376, 0.7891671} +}; + +constexpr double jdcmax_xyz[3][3] = { + {1.1984508, -0.0197646, -0.1646037}, + {-0.5223824, 1.4466349, 0.0691553}, + {0.0236634, -0.0655113, 1.2640260} +}; + + constexpr double xyz_ACESp1[3][3] = { {0.689697, 0.149944, 0.124559}, {0.284448, 0.671758 , 0.043794}, diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 06d5a4b0c..20fc07234 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -196,9 +196,9 @@ cmsHPROFILE createXYZProfile() return rtengine::ICCStore::createFromMatrix(mat, false, "XYZ"); } -const double(*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best, xyz_rec2020, xyz_ACESp0, xyz_ACESp1};// -const double(*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz, rec2020_xyz, ACESp0_xyz, ACESp1_xyz};// -const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB", "Rec2020", "ACESp0", "ACESp1"};// +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"};// //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/iimage.h b/rtengine/iimage.h index 68f739f1a..426b0c4c0 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -111,7 +111,7 @@ public: { rm = gm = bm = 1.0; } - virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) + 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) { rm = gm = bm = 1.0; } diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 1f4c2179a..eba600ecf 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -117,10 +117,10 @@ 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(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, 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 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 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(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 &studgood, 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; + 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; virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) = 0; virtual double getDefGain () const diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6e3ebc48c..192ae9ceb 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1,6 +1,6 @@ /* * This file is part of RawTherapee. - * + * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify @@ -305,9 +305,11 @@ void ImProcCoordinator::backupParams() if (!params) { return; } + if (!paramsBackup) { paramsBackup.reset(new ProcParams()); } + *paramsBackup = *params; } @@ -316,6 +318,7 @@ void ImProcCoordinator::restoreParams() if (!paramsBackup || !params) { return; } + *params = *paramsBackup; } @@ -330,11 +333,10 @@ DetailedCrop* ImProcCoordinator::createCrop(::EditDataProvider *editDataProvider void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) { // TODO Locallab printf - MyMutex::MyLock processingLock(mProcessing); bool highDetailNeeded = options.prevdemo == PD_Sidecar ? true : (todo & M_HIGHQUAL); - // printf("metwb=%s \n", params->wb.method.c_str()); + // printf("metwb=%s \n", params->wb.method.c_str()); // Check if any detail crops need high detail. If not, take a fast path short cut if (!highDetailNeeded) { @@ -357,7 +359,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ColorManagementParams cmp = params->icm; LCurveParams lcur = params->labCurve; bool spotsDone = false; - + if (!highDetailNeeded) { // if below 100% magnification, take a fast path if (rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::NONE) && rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)) { @@ -410,11 +412,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (imageTypeListener) { imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported()); } - bool iscolor = (params->toneCurve.method == "Color");// || params->toneCurve.method == "Coloropp"); + + bool iscolor = (params->toneCurve.method == "Color");// || params->toneCurve.method == "Coloropp"); + if ((todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) - // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) - // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { || (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified()) || (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) { @@ -469,8 +473,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) - // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) - // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { + // || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + // || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { || (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified()) || (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) { if (highDetailNeeded) { @@ -510,12 +514,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); + if (settings->verbose) { printf("automethod=%s \n", params->wb.method.c_str()); } + if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { MyMutex::MyLock initLock(minit); // Also used in crop window - // imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery + //imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery if (settings->verbose) { @@ -523,7 +529,22 @@ 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 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(); @@ -531,29 +552,223 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) currWB = imgsrc->getWB(); lastAwbauto = ""; //reinitialize auto } else if (autowb) { - if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { - double rm, gm, bm; - double tempitc = 5000.f; - double greenitc = 1.; + 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 tempref = currWBitc.getTemp() * (1. + params->wb.tempBias); + double greenref = currWBitc.getGreen(); - if (settings->verbose && params->wb.method == "autitcgreen") { - printf("tempref=%f greref=%f\n", tempref, greenref); + double tempref0bias0 = currWBitc.getTemp(); + + if (greenref > green_thres && params->wb.itcwb_prim == "srgb") { + forcewbgrey = true; } - imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); + 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) { + 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); + 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); - //printf("tempitc=%f greitc=%f\n", tempitc, greenitc); - currWB.getMultipliers(rm, gm, bm); + autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, params->wb.tempBias); } if (rm != -1.) { + double bias = params->wb.tempBias; if (params->wb.method == "autitcgreen") { @@ -572,30 +787,54 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lastAwbauto = ""; autoWB.useDefaults(params->wb.equal, params->wb.observer); } - - } currWB = autoWB; } + double rw = 1.; double gw = 1.; double bw = 1.; - if (params->wb.enabled) { currWB = currWB.convertObserver(params->wb.observer); params->wb.temperature = static_cast(currWB.getTemp()); params->wb.green = currWB.getGreen(); + currWB.getMultipliers(rw, gw, bw); imgsrc->wbMul2Camera(rw, gw, bw); - // printf("ra=%f ga=%f ba=%f\n", rw, gw, bw); + // params->wb.itcwb_sampling = false; + /* + printf("ra=%f ga=%f ba=%f\n", rw, gw, bw); + //recalculate temp and green with wb multipliers. + imgsrc->wbCamera2Mul(rw, gw, bw); + ColorTemp ct(rw, gw, bw, 1.0, currWB.getObserver()); + //allows to calculate temp and green with multipliers in case of we want in GUI + float tem = ct.getTemp(); + float gre = ct.getGreen(); + printf("tem=%f gre=%f \n", (double) tem, (double) gre); + */ } + int met = 0; + if (awbListener) { if (params->wb.method == "autitcgreen") { - awbListener->WBChanged(params->wb.temperature, params->wb.green, rw, gw, bw, studgood); + 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); + + } else { + minchrom = LIM(minchrom, 0.f, 0.9f); + delta = LIM(delta, 0.f, 0.9f); + minhist = std::max(minhist, 100.f); + 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); + } } else { - awbListener->WBChanged(params->wb.temperature, params->wb.green, rw, gw, bw, -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); } } @@ -725,10 +964,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } } + if (spotprev) { spotprev->copyData(orig_prev); } - + if ((todo & M_HDR) && (params->fattal.enabled || params->dehaze.enabled)) { if (fattal_11_dcrop_cache) { delete fattal_11_dcrop_cache; @@ -762,12 +1002,12 @@ 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) { - 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 ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled) { const int W = oprevi->getWidth(); @@ -852,7 +1092,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) centx = new float[sizespot]; float *centy = nullptr; centy = new float[sizespot]; - + for (int sp = 0; sp < sizespot; sp++) { log[sp] = params->locallab.spots.at(sp).explog; cie[sp] = params->locallab.spots.at(sp).expcie; @@ -900,7 +1140,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } 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]); + // printf("sp=%i sg=%f sab=%f\n", sp, sourceg[sp], sourceab[sp]); params->locallab.spots.at(sp).blackEv = blackev[sp]; params->locallab.spots.at(sp).whiteEv = whiteev[sp]; params->locallab.spots.at(sp).blackEvjz = blackev[sp]; @@ -910,6 +1150,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->locallab.spots.at(sp).sourceGraycie = sourceg[sp]; params->locallab.spots.at(sp).sourceabscie = sourceab[sp]; float jz1 = defSpot.jz100; + if (locallListener) { locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], sourceab[sp], targetg[sp], autocomput[sp], autocie[sp], jz1); } @@ -938,7 +1179,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((todo & (M_AUTOEXP | M_RGBCURVE | M_CROP)) && params->locallab.enabled && !params->locallab.spots.empty()) { - + ipf.rgb2lab(*oprevi, *oprevl, params->icm.workingProfile); nprevl->CopyFrom(oprevl); @@ -1010,6 +1251,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); @@ -1053,7 +1295,7 @@ 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); @@ -1130,10 +1372,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float yend = 1.f; float xsta = 0.f; float xend = 1.f; + if (istm || isreti) { locx = params->locallab.spots.at(sp).loc.at(0) / 2000.0; locy = params->locallab.spots.at(sp).loc.at(2) / 2000.0; - locxl= params->locallab.spots.at(sp).loc.at(1) / 2000.0; + locxl = params->locallab.spots.at(sp).loc.at(1) / 2000.0; locyt = params->locallab.spots.at(sp).loc.at(3) / 2000.0; centx = params->locallab.spots.at(sp).centerX / 2000.0 + 0.5; centy = params->locallab.spots.at(sp).centerY / 2000.0 + 0.5; @@ -1141,20 +1384,22 @@ 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); + // printf("xsta=%f xend=%f ysta=%f yend=%f \n", xsta, xend, ysta, yend); } + int ww = nprevl->W; int hh = nprevl->H; int xxs = xsta * ww; int xxe = xend * ww; int yys = ysta * hh; int yye = yend * hh; - + if (istm) { //calculate mean and sigma on full image for RT-spot use by normalize_mean_dt - ipf.mean_sig (nprevl->L, meantme, stdtme, xxs, xxe, yys, yye); + ipf.mean_sig(nprevl->L, meantme, stdtme, xxs, xxe, yys, yye); } + if (isreti) { //calculate mean and sigma on full image for RT-spot use by normalize_mean_dt - ipf.mean_sig (nprevl->L, meanretie, stdretie,xxs, xxe, yys, yye) ; + ipf.mean_sig(nprevl->L, meanretie, stdretie, xxs, xxe, yys, yye) ; } double huerblu = huerefblurs[sp] = huerefblu; @@ -1172,7 +1417,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) huerefp[sp] = huer; chromarefp[sp] = chromar; lumarefp[sp] = lumar; - + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lumar, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, sca); @@ -1204,7 +1449,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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; @@ -1244,7 +1489,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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, @@ -1269,12 +1514,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) fabrefp[sp] = fab; + if (istm) { //calculate mean and sigma on full image for use by normalize_mean_dt float meanf = 0.f; float stdf = 0.f; - ipf.mean_sig (savenormtm->L, meanf, stdf, xxs, xxe, yys, yye); - - //using 2 unused variables noiselumc and softradiustm + ipf.mean_sig(savenormtm->L, meanf, stdf, xxs, xxe, yys, yye); + + //using 2 unused variables noiselumc and softradiustm params->locallab.spots.at(sp).noiselumc = (int) meanf; params->locallab.spots.at(sp).softradiustm = stdf ; } @@ -1282,8 +1528,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (isreti) { //calculate mean and sigma on full image for use by normalize_mean_dt float meanf = 0.f; float stdf = 0.f; - ipf.mean_sig (savenormreti->L, meanf, stdf,xxs, xxe, yys, yye ); - //using 2 unused variables sensihs and sensiv + ipf.mean_sig(savenormreti->L, meanf, stdf, xxs, xxe, yys, yye); + //using 2 unused variables sensihs and sensiv params->locallab.spots.at(sp).sensihs = (int) meanf; params->locallab.spots.at(sp).sensiv = (int) stdf; } @@ -1305,12 +1551,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) retiMinMax.Tmin = Tmin; retiMinMax.Tmax = Tmax; locallretiminmax.push_back(retiMinMax); + // 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); } else { ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg, locwavCurveden, locwavdenutili); } + // Update Locallab reference values according to recurs parameter if (params->locallab.spots.at(sp).recurs) { /* @@ -1327,19 +1575,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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); - } + // 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); + } } + delete [] huerefp; delete [] chromarefp; delete [] lumarefp; @@ -1355,9 +1605,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //************************************************************* // end locallab //************************************************************* - + } - + if ((todo & M_RGBCURVE) || (todo & M_CROP)) { //complexCurve also calculated pre-curves histogram depending on crop CurveFactory::complexCurve(params->toneCurve.expcomp, params->toneCurve.black / 65535.0, @@ -1522,16 +1772,18 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) nprevl->CopyFrom(oprevl); histCCurve.clear(); histLCurve.clear(); + if (params->colorToning.enabled && params->colorToning.method == "LabGrid") { - ipf.colorToningLabGrid(nprevl, 0, nprevl->W, 0, nprevl->H, false); + ipf.colorToningLabGrid(nprevl, 0, nprevl->W, 0, nprevl->H, false); } - ipf.shadowsHighlights(nprevl, params->sh.enabled, params->sh.lab,params->sh.highlights ,params->sh.shadows, params->sh.radius, scale, params->sh.htonalwidth, params->sh.stonalwidth); + ipf.shadowsHighlights(nprevl, params->sh.enabled, params->sh.lab, params->sh.highlights, params->sh.shadows, params->sh.radius, scale, params->sh.htonalwidth, params->sh.stonalwidth); if (params->localContrast.enabled) { - // Alberto's local contrast + // Alberto's local contrast ipf.localContrast(nprevl, nprevl->L, params->localContrast, false, scale); } + ipf.chromiLuminanceCurve(nullptr, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve); ipf.vibrance(nprevl, params->vibrance, params->toneCurve.hrenabled, params->icm.workingProfile); ipf.labColorCorrectionRegions(nprevl); @@ -1560,11 +1812,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bool proedge = WaveParams.expedge; bool profin = WaveParams.expfinal; bool proton = WaveParams.exptoning; - bool pronois = WaveParams.expnoise; + bool pronois = WaveParams.expnoise; if (WaveParams.showmask) { - // WaveParams.showmask = false; - // WaveParams.expclari = true; + // WaveParams.showmask = false; + // WaveParams.expclari = true; } if (WaveParams.softrad > 0.f) { @@ -1584,7 +1836,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expedge = false; WaveParams.expfinal = false; WaveParams.exptoning = false; - WaveParams.expnoise = false; + WaveParams.expnoise = false; } ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); @@ -1597,7 +1849,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expfinal = profin; WaveParams.exptoning = proton; WaveParams.expnoise = pronois; - + if (WaveParams.softrad > 0.f) { array2D ble(pW, pH); @@ -1627,7 +1879,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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; @@ -1653,11 +1905,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Color::XYZ2Lab(X, Y, Z, L, a, b); nprevl->L[ir][jr] = L; } - - delete tmpImage; + + delete tmpImage; } - + } if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { @@ -1666,7 +1918,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float mL0; float mC0; float background = 0.f; - int show = 0; + int show = 0; @@ -1686,15 +1938,17 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) background = 0.f; show = 0; } - float indic = 1.f; - if (WaveParams.showmask){ - mL0 = mC0 = -1.f; - indic = -1.f; - mL = fabs(mL); - mC = fabs(mC); - show = 1; - } + float indic = 1.f; + + if (WaveParams.showmask) { + mL0 = mC0 = -1.f; + indic = -1.f; + mL = fabs(mL); + mC = fabs(mC); + show = 1; + } + #ifdef _OPENMP #pragma omp parallel for #endif @@ -1708,43 +1962,43 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete unshar; unshar = NULL; - - -/* - if (WaveParams.softrad > 0.f) { - array2D ble(pW, pH); - array2D guid(pW, pH); -#ifdef _OPENMP - #pragma omp parallel for -#endif - for (int ir = 0; ir < pH; ir++) - for (int jr = 0; jr < pW; jr++) { - ble[ir][jr] = (nprevl->L[ir][jr] - provradius->L[ir][jr]) / 32768.f; - guid[ir][jr] = provradius->L[ir][jr] / 32768.f; - } - double epsilmax = 0.001; - double epsilmin = 0.0001; - double aepsil = (epsilmax - epsilmin) / 90.f; - double bepsil = epsilmax - 100.f * aepsil; - double epsil = aepsil * WaveParams.softrad + bepsil; - float blur = 10.f / scale * (0.001f + 0.8f * WaveParams.softrad); - // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); - rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + /* + if (WaveParams.softrad > 0.f) { + array2D ble(pW, pH); + array2D guid(pW, pH); + #ifdef _OPENMP + #pragma omp parallel for + #endif + + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + ble[ir][jr] = (nprevl->L[ir][jr] - provradius->L[ir][jr]) / 32768.f; + guid[ir][jr] = provradius->L[ir][jr] / 32768.f; + } + double epsilmax = 0.001; + double epsilmin = 0.0001; + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * WaveParams.softrad + bepsil; + + float blur = 10.f / scale * (0.001f + 0.8f * WaveParams.softrad); + // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); -#ifdef _OPENMP - #pragma omp parallel for -#endif + #ifdef _OPENMP + #pragma omp parallel for + #endif - for (int ir = 0; ir < pH; ir++) - for (int jr = 0; jr < pW; jr++) { - nprevl->L[ir][jr] = provradius->L[ir][jr] + 32768.f * ble[ir][jr]; - } - } -*/ + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + nprevl->L[ir][jr] = provradius->L[ir][jr] + 32768.f * ble[ir][jr]; + } + } + */ if (WaveParams.softrad > 0.f) { delete provradius; @@ -1754,7 +2008,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } - + } ipf.softLight(nprevl, params->softlight); @@ -1764,6 +2018,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const int GH = nprevl->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(nprevl); @@ -1786,24 +2041,27 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, dummy, false, true, true); ipf.rgb2lab(*tmpImage1, *nprevl, params->icm.workingProfile); + //nprevl and provis if (provis) { ipf.preserv(nprevl, provis.get(), GW, GH); } + if (params->icm.fbw) { #ifdef _OPENMP #pragma omp parallel for #endif + for (int x = 0; x < GH; x++) for (int y = 0; y < GW; y++) { nprevl->a[x][y] = 0.f; nprevl->b[x][y] = 0.f; } } - + tmpImage1.reset(); - if (prim == 12) {//pass red gre blue xy in function of area dats Ciexy + if (prim == 13) {//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; @@ -1825,7 +2083,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) greyy = rtengine::LIM(greyy, 0.5f, 1.f); if (primListener) { - primListener->primChanged (redxx, redyy, bluxx, bluyy, grexx, greyy); + primListener->primChanged(redxx, redyy, bluxx, bluyy, grexx, greyy); } } else {//all other cases - pass Cie xy to update graph Ciexy float r_x = params->icm.redx; @@ -1839,50 +2097,59 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float wy = 0.33f; switch (illum) { - case 1://D41 - wx = 0.37798f; - wy = 0.38123f; - break; - case 2://D50 - wx = 0.3457f; - wy = 0.3585f; - break; - case 3://D55 - wx = 0.3324f; - wy = 0.3474f; - break; - case 4://D60 - wx = 0.3217f; - wy = 0.3377f; - break; - case 5://D65 - wx = 0.3127f; - wy = 0.3290f; - break; - case 6://D80 - wx = 0.2937f; - wy = 0.3092f; - break; - case 7://D120 - wx = 0.2697f; - wy = 0.2808f; - break; - case 8://stdA - wx = 0.4476f; - wy = 0.4074f; - break; - case 9://2000K - wx = 0.5266f; - wy = 0.4133f; - break; - case 10://1500K - wx = 0.5857f; - wy = 0.3932f; - break; + case 1://D41 + wx = 0.37798f; + wy = 0.38123f; + break; + + case 2://D50 + wx = 0.3457f; + wy = 0.3585f; + break; + + case 3://D55 + wx = 0.3324f; + wy = 0.3474f; + break; + + case 4://D60 + wx = 0.3217f; + wy = 0.3377f; + break; + + case 5://D65 + wx = 0.3127f; + wy = 0.3290f; + break; + + case 6://D80 + wx = 0.2937f; + wy = 0.3092f; + break; + + case 7://D120 + wx = 0.2697f; + wy = 0.2808f; + break; + + case 8://stdA + wx = 0.4476f; + wy = 0.4074f; + break; + + case 9://2000K + wx = 0.5266f; + wy = 0.4133f; + break; + + case 10://1500K + wx = 0.5857f; + wy = 0.3932f; + break; } 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); } } } @@ -1936,9 +2203,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) adap = pow(2.0, E_V - 3.0); // cd / m2 // end calculation adaptation scene luminosity } - if(params->colorappearance.catmethod == "symg") {//force absolute luminance scene to 400 in symmetric - adap = 400.; - } + + if (params->colorappearance.catmethod == "symg") { //force abolute luminance scenescene to 400 in symmetric + adap = 400.; + } + float d, dj, yb; bool execsharp = false; @@ -1960,13 +2229,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) CAMBrightCurveQ.dirty = true; ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, scale, execsharp, d, dj, yb, 1); - //call listener + + //call listener if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) { - if(params->colorappearance.catmethod == "symg") {//force chromatic adaptation to 90 in symmetric - d = 0.9; - dj = 0.9; - } - acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); + if (params->colorappearance.catmethod == "symg") { //force chromatic adaptation to 90 in symmetric + d = 0.9; + dj = 0.9; + } + + acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); } if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled) { @@ -1974,47 +2245,50 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) { - if(params->colorappearance.catmethod == "symg") {//force yb scene to 18 in symmetric - yb = 18; - } + if (params->colorappearance.catmethod == "symg") { //force yb scene to 18 in symmetric + yb = 18; + } acListener->ybCamChanged((int) yb); //real value Yb scene } - double tempsym = 5003.; - int wmodel = 0;//wmodel allows - arbitrary - choice of illuminant and temp with choice - if (params->colorappearance.wbmodel == "RawT") { - wmodel = 0; - } else if (params->colorappearance.wbmodel == "RawTCAT02") { - wmodel = 1; - } else if (params->colorappearance.wbmodel == "free") { - wmodel = 2;//force white balance in symmetric - } - - if(params->colorappearance.catmethod == "symg" && wmodel == 2) { - tempsym = params->wb.temperature;//force white balance in symmetric - } else { - if (params->colorappearance.illum == "iA") {//otherwise force illuminant source - tempsym = 2856.; - } else if (params->colorappearance.illum == "i41") { - tempsym = 4100.; - } else if (params->colorappearance.illum == "i50") { - tempsym = 5003.; - } else if (params->colorappearance.illum == "i55") { - tempsym = 5503.; - } else if (params->colorappearance.illum == "i60") { - tempsym = 6000. ; - } else if (params->colorappearance.illum == "i65") { - tempsym = 6504.; - } else if (params->colorappearance.illum == "i75") { - tempsym = 7504.; - } else if (params->colorappearance.illum == "ifree") { - tempsym = params->wb.temperature;//force white balance in symmetric - } - } - if (params->colorappearance.enabled && params->colorappearance.autotempout) { - acListener->wbCamChanged(tempsym, 1.f); //real temp and tint = 1. + + double tempsym = 5003.; + int wmodel = 0;//wmodel allows - arbitrary - choice of illuminant and temp with choice + + if (params->colorappearance.wbmodel == "RawT") { + wmodel = 0; + } else if (params->colorappearance.wbmodel == "RawTCAT02") { + wmodel = 1; + } else if (params->colorappearance.wbmodel == "free") { + wmodel = 2;//force white balance in symmetric } - + + if (params->colorappearance.catmethod == "symg" && wmodel == 2) { + tempsym = params->wb.temperature;//force white balance in symmetric + } else { + if (params->colorappearance.illum == "iA") {//otherwise force illuminant source + tempsym = 2856.; + } else if (params->colorappearance.illum == "i41") { + tempsym = 4100.; + } else if (params->colorappearance.illum == "i50") { + tempsym = 5003.; + } else if (params->colorappearance.illum == "i55") { + tempsym = 5503.; + } else if (params->colorappearance.illum == "i60") { + tempsym = 6000. ; + } else if (params->colorappearance.illum == "i65") { + tempsym = 6504.; + } else if (params->colorappearance.illum == "i75") { + tempsym = 7504.; + } else if (params->colorappearance.illum == "ifree") { + tempsym = params->wb.temperature;//force white balance in symmetric + } + } + + if (params->colorappearance.enabled && params->colorappearance.autotempout) { + acListener->wbCamChanged(tempsym, 1.f); //real temp and tint = 1. + } + } else { // CIECAM is disabled, we free up its image buffer to save some space if (ncie) { @@ -2033,7 +2307,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } - // if (todo & (M_AUTOEXP | M_RGBCURVE)) { + // if (todo & (M_AUTOEXP | M_RGBCURVE)) { // Update the monitor color transform if necessary if ((todo & M_MONITOR) || (lastOutputProfile != params->icm.outputProfile) || lastOutputIntent != params->icm.outputIntent || lastOutputBPC != params->icm.outputBPC) { @@ -2083,19 +2357,24 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } hist_lrgb_dirty = vectorscope_hc_dirty = vectorscope_hs_dirty = waveform_dirty = true; + if (hListener) { if (hListener->updateHistogram()) { updateLRGBHistograms(); } + if (hListener->updateVectorscopeHC()) { updateVectorscopeHC(); } + if (hListener->updateVectorscopeHS()) { updateVectorscopeHS(); } + if (hListener->updateWaveform()) { updateWaveforms(); } + notifyHistogramChanged(); } } @@ -2106,14 +2385,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } -void ImProcCoordinator::setTweakOperator (TweakOperator *tOperator) +void ImProcCoordinator::setTweakOperator(TweakOperator *tOperator) { if (tOperator) { tweakOperator = tOperator; } } -void ImProcCoordinator::unsetTweakOperator (TweakOperator *tOperator) +void ImProcCoordinator::unsetTweakOperator(TweakOperator *tOperator) { if (tOperator && tOperator == tweakOperator) { tweakOperator = nullptr; @@ -2127,6 +2406,7 @@ void ImProcCoordinator::freeAll() if (spotprev && spotprev != oprevi) { delete spotprev; } + spotprev = nullptr; if (orig_prev != oprevi) { @@ -2161,7 +2441,7 @@ void ImProcCoordinator::freeAll() allocated = false; } -void ImProcCoordinator::allocCache (Imagefloat* &imgfloat) +void ImProcCoordinator::allocCache(Imagefloat* &imgfloat) { if (imgfloat == nullptr) { imgfloat = new Imagefloat(pW, pH); @@ -2188,8 +2468,8 @@ void ImProcCoordinator::setScale(int prevscale) do { prevscale--; - PreviewProps pp (0, 0, fw, fh, prevscale); - imgsrc->getSize (pp, nW, nH); + PreviewProps pp(0, 0, fw, fh, prevscale); + imgsrc->getSize(pp, nW, nH); } while (nH < 400 && prevscale > 1 && (nW * nH < 1000000)); // actually hardcoded values, perhaps a better choice is possible if (nW != pW || nH != pH) { @@ -2348,15 +2628,18 @@ bool ImProcCoordinator::updateVectorscopeHC() #ifdef _OPENMP #pragma omp for nowait #endif + for (int i = y1; i < y2; ++i) { for (int j = x1, ofs_lab = (i - y1) * (x2 - x1); j < x2; ++j, ++ofs_lab) { const int col = norm_factor * a[ofs_lab] + size / 2 + 0.5f; const int row = norm_factor * b[ofs_lab] + size / 2 + 0.5f; + if (col >= 0 && col < size && row >= 0 && row < size) { vectorscopeThr[row][col]++; } } } + #ifdef _OPENMP #pragma omp critical #endif @@ -2391,8 +2674,10 @@ bool ImProcCoordinator::updateVectorscopeHS() #ifdef _OPENMP #pragma omp for nowait #endif + for (int i = y1; i < y2; ++i) { int ofs = (i * pW + x1) * 3; + for (int j = x1; j < x2; ++j) { const float red = 257.f * workimg->data[ofs++]; const float green = 257.f * workimg->data[ofs++]; @@ -2402,11 +2687,13 @@ bool ImProcCoordinator::updateVectorscopeHS() const auto sincosval = xsincosf(2.f * RT_PI_F * h); const int col = s * sincosval.y * (size / 2) + size / 2; const int row = s * sincosval.x * (size / 2) + size / 2; + if (col >= 0 && col < size && row >= 0 && row < size) { vectorscopeThr[row][col]++; } } } + #ifdef _OPENMP #pragma omp critical #endif @@ -2454,6 +2741,7 @@ bool ImProcCoordinator::updateWaveforms() waveformLuma.fill(0); constexpr float luma_factor = 255.f / 32768.f; + for (int i = y1; i < y2; i++) { int ofs = (i * pW + x1) * 3; float* L_row = nprevl->L[i] + x1; @@ -2479,13 +2767,24 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, Sta // Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window double rm, gm, bm; params->wb.method = "autold";//same result as before multiple Auto WB - - // imgsrc->getAutoWBMultipliers(rm, gm, bm); + + // imgsrc->getAutoWBMultipliers(rm, gm, bm); double tempitc = 5000.; double greenitc = 1.; + int dread = 0; + int bia = 0; + float temp0 = 5000.f; float studgood = 1000.f; + int nocam = 0; + int kcam = 0; + float minchrom = 1000.f; + float delta = 0.f; + int kmin = 20; + float minhist = 10000000.f; + float maxhist = -1000.f; double tempref, greenref; - imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); + bool extra = false; + 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 (rm != -1) { autoWB.update(rm, gm, bm, equal, observer, tempBias); @@ -2804,6 +3103,7 @@ void ImProcCoordinator::process() || params->rgbCurves != nextParams->rgbCurves || params->colorToning != nextParams->colorToning || params->vibrance != nextParams->vibrance + // || params->wb != nextParams->wb //isPanningRelatedChange(nextParams->wb) || params->wb.isPanningRelatedChange(nextParams->wb) || params->colorappearance != nextParams->colorappearance || params->epd != nextParams->epd @@ -2919,7 +3219,9 @@ void ImProcCoordinator::requestUpdateWaveform() if (!hListener) { return; } + bool updated = updateWaveforms(); + if (updated) { notifyHistogramChanged(); } @@ -2930,7 +3232,9 @@ void ImProcCoordinator::requestUpdateHistogram() if (!hListener) { return; } + bool updated = updateLRGBHistograms(); + if (updated) { notifyHistogramChanged(); } @@ -2941,6 +3245,7 @@ void ImProcCoordinator::requestUpdateHistogramRaw() if (!hListener) { return; } + // Don't need to actually update histogram because it is always // up-to-date. if (hist_raw_dirty) { @@ -2954,7 +3259,9 @@ void ImProcCoordinator::requestUpdateVectorscopeHC() if (!hListener) { return; } + bool updated = updateVectorscopeHC(); + if (updated) { notifyHistogramChanged(); } @@ -2965,7 +3272,9 @@ void ImProcCoordinator::requestUpdateVectorscopeHS() if (!hListener) { return; } + bool updated = updateVectorscopeHS(); + if (updated) { notifyHistogramChanged(); } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 50c14ef9e..7e4e3bb06 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -74,6 +74,7 @@ protected: ImageSource* imgsrc; ColorTemp currWB; + ColorTemp currWBcust; ColorTemp autoWB; ColorTemp currWBloc; ColorTemp autoWBloc; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 2c36a0d31..ea11e40bd 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -440,7 +440,7 @@ enum class BlurType { void Sigma(const float* HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg, int numThreads); void calckoe(const float* WavCoeffs_LL, float gradw, float tloww, float *koeLi, int level, int W_L, int H_L, float edd, float &maxkoeLi, float **tmC, bool multiThread = false); - void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); + static void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi); void RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index dd02b8f0f..7620068a4 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -434,7 +434,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") { + 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 (settings->verbose) { printf("Profile=%s\n", profile.c_str()); } @@ -509,7 +509,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, float greyy = params->icm.grey; float epsil = 0.0001f; - if (prim == 12) {//convert datas area to xy + if (prim == 13) {//convert datas area to xy float redgraphx = params->icm.labgridcieALow; float redgraphy = params->icm.labgridcieBLow; float blugraphx = params->icm.labgridcieAHigh; @@ -597,6 +597,12 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } case ColorManagementParams::Primaries::ACES_P0: { + profile = "ACESp0"; + break; + } + + case ColorManagementParams::Primaries::JDC_MAX: { + profile = "JDCmax"; break; } @@ -754,6 +760,17 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, 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 == "ACESp1") { p[0] = 0.713; // ACES P1 primaries p[1] = 0.293; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a421be9b3..5176a8539 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1387,16 +1387,12 @@ WBParams::WBParams() : equal(1.0), tempBias(0.0), observer(ColorTemp::DEFAULT_OBSERVER), - itcwb_thres(34), - itcwb_precis(3), - itcwb_size(3), - itcwb_delta(2), - itcwb_fgreen(5), - itcwb_rgreen(1), - itcwb_nopurple(true), - itcwb_sorted(false), - itcwb_forceextra(false), - itcwb_sampling(false) + itcwb_green(0.),//slider + itcwb_rgreen(1),//keep for settings + itcwb_nopurple(false),//keep for settings + itcwb_alg(false),//checkbox + itcwb_prim("beta"),//combobox + itcwb_sampling(false)//keep for 5.9 and for settings { } @@ -1418,6 +1414,10 @@ bool WBParams::isPanningRelatedChange(const WBParams& other) const && equal == other.equal && tempBias == other.tempBias && observer == other.observer + && itcwb_green == other.itcwb_green + && itcwb_prim == other.itcwb_prim + && itcwb_alg == other.itcwb_alg + ) ) ); @@ -1433,15 +1433,11 @@ bool WBParams::operator ==(const WBParams& other) const && equal == other.equal && tempBias == other.tempBias && observer == other.observer - && itcwb_thres == other.itcwb_thres - && itcwb_precis == other.itcwb_precis - && itcwb_size == other.itcwb_size - && itcwb_delta == other.itcwb_delta - && itcwb_fgreen == other.itcwb_fgreen + && itcwb_green == other.itcwb_green && itcwb_rgreen == other.itcwb_rgreen && itcwb_nopurple == other.itcwb_nopurple - && itcwb_sorted == other.itcwb_sorted - && itcwb_forceextra == other.itcwb_forceextra + && itcwb_alg == other.itcwb_alg + && itcwb_prim == other.itcwb_prim && itcwb_sampling == other.itcwb_sampling; } @@ -6216,15 +6212,11 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wb.equal, "White Balance", "Equal", wb.equal, keyFile); saveToKeyfile(!pedited || pedited->wb.tempBias, "White Balance", "TemperatureBias", wb.tempBias, keyFile); saveToKeyfile(!pedited || pedited->wb.observer, "White Balance", "StandardObserver", Glib::ustring(wb.observer == StandardObserver::TWO_DEGREES ? "TWO_DEGREES" : "TEN_DEGREES"), keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_thres, "White Balance", "Itcwb_thres", wb.itcwb_thres, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_precis, "White Balance", "Itcwb_precis", wb.itcwb_precis, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_size, "White Balance", "Itcwb_size", wb.itcwb_size, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_delta, "White Balance", "Itcwb_delta", wb.itcwb_delta, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_fgreen, "White Balance", "Itcwb_findgreen", wb.itcwb_fgreen, keyFile); + saveToKeyfile(!pedited || pedited->wb.itcwb_green, "White Balance", "Itcwb_green", wb.itcwb_green, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_rgreen, "White Balance", "Itcwb_rangegreen", wb.itcwb_rgreen, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_nopurple, "White Balance", "Itcwb_nopurple", wb.itcwb_nopurple, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_sorted, "White Balance", "Itcwb_sorted", wb.itcwb_sorted, keyFile); - saveToKeyfile(!pedited || pedited->wb.itcwb_forceextra, "White Balance", "Itcwb_forceextra", wb.itcwb_forceextra, keyFile); + 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); // Colorappearance @@ -7293,6 +7285,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo {ColorManagementParams::Primaries::ACES_P1, "aces"}, {ColorManagementParams::Primaries::WIDE_GAMUT, "wid"}, {ColorManagementParams::Primaries::ACES_P0, "ac0"}, + {ColorManagementParams::Primaries::JDC_MAX, "jdcmax"}, {ColorManagementParams::Primaries::BRUCE_RGB, "bru"}, {ColorManagementParams::Primaries::BETA_RGB, "bet"}, {ColorManagementParams::Primaries::BEST_RGB, "bst"}, @@ -8194,15 +8187,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } else if (standard_observer == "TWO_DEGREES") { wb.observer = StandardObserver::TWO_DEGREES; } - assignFromKeyfile(keyFile, "White Balance", "Itcwb_thres", pedited, wb.itcwb_thres, pedited->wb.itcwb_thres); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_precis", pedited, wb.itcwb_precis, pedited->wb.itcwb_precis); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_size", pedited, wb.itcwb_size, pedited->wb.itcwb_size); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_delta", pedited, wb.itcwb_delta, pedited->wb.itcwb_delta); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_findgreen", pedited, wb.itcwb_fgreen, pedited->wb.itcwb_fgreen); + 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_sorted", pedited, wb.itcwb_sorted, pedited->wb.itcwb_sorted); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_forceextra", pedited, wb.itcwb_forceextra, pedited->wb.itcwb_forceextra); + 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); if (ppVersion <= 349) { // 5.9 and earlier. wb.itcwb_sampling = true; if (pedited) { @@ -9630,6 +9619,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) {"aces", ColorManagementParams::Primaries::ACES_P1}, {"wid", ColorManagementParams::Primaries::WIDE_GAMUT}, {"ac0", ColorManagementParams::Primaries::ACES_P0}, + {"jdcmax", ColorManagementParams::Primaries::JDC_MAX}, {"bru", ColorManagementParams::Primaries::BRUCE_RGB}, {"bet", ColorManagementParams::Primaries::BETA_RGB}, {"bst", ColorManagementParams::Primaries::BEST_RGB}, diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6be2be54c..b2edaf3fb 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -643,15 +643,11 @@ struct WBParams { double equal; double tempBias; StandardObserver observer; - int itcwb_thres; - int itcwb_precis; - int itcwb_size; - int itcwb_delta; - int itcwb_fgreen; + double itcwb_green; int itcwb_rgreen; bool itcwb_nopurple; - bool itcwb_sorted; - bool itcwb_forceextra; + bool itcwb_alg; + Glib::ustring itcwb_prim; bool itcwb_sampling; WBParams(); @@ -1940,6 +1936,7 @@ struct ColorManagementParams { ACES_P1, WIDE_GAMUT, ACES_P0, + JDC_MAX, BRUCE_RGB, BETA_RGB, BEST_RGB, diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index a1ace9ffa..8d68988e0 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -43,7 +43,6 @@ #include "rt_math.h" #include "rtengine.h" #include "rtlensfun.h" - #include "../rtgui/options.h" #define BENCHMARK @@ -58,9 +57,9 @@ namespace { -void rotateLine (const float* const line, rtengine::PlanarPtr &channel, const int tran, const int i, const int w, const int h) +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) { + switch (tran & TR_ROT) { case TR_R180: for (int j = 0; j < w; j++) { channel(h - 1 - i, w - 1 - j) = line[j]; @@ -90,15 +89,15 @@ void rotateLine (const float* const line, rtengine::PlanarPtr &channel, c } } -void transLineStandard (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight) +void transLineStandard(const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight) { // conventional CCD coarse rotation - rotateLine (red, image->r, tran, i, imwidth, imheight); - rotateLine (green, image->g, tran, i, imwidth, imheight); - rotateLine (blue, image->b, tran, i, imwidth, imheight); + rotateLine(red, image->r, tran, i, imwidth, imheight); + rotateLine(green, image->g, tran, i, imwidth, imheight); + rotateLine(blue, image->b, tran, i, imwidth, imheight); } -void transLineFuji (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imheight, const int fw) +void transLineFuji(const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imheight, const int fw) { // Fuji SuperCCD rotation + coarse rotation @@ -107,7 +106,7 @@ void transLineFuji (const float* const red, const float* const green, const floa int h = (imheight - fw) * 2 + 1; int end = min(h + fw - i, w - fw + i); - switch(tran & TR_ROT) { + switch (tran & TR_ROT) { case TR_R180: for (int j = start; j < end; j++) { int y = i + j - fw; @@ -165,14 +164,14 @@ void transLineFuji (const float* const red, const float* const green, const floa } } -void transLineD1x (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight, const bool oddHeight, const bool clip) +void transLineD1x(const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight, const bool oddHeight, const bool clip) { // Nikon D1X has an uncommon sensor with 4028 x 1324 sensels. // Vertical sensel size is 2x horizontal sensel size // We have to do vertical interpolation for the 'missing' rows // We do that in combination with coarse rotation - switch(tran & TR_ROT) { + switch (tran & TR_ROT) { case TR_R180: // rotate 180 degree for (int j = 0; j < imwidth; j++) { image->r(2 * (imheight - 1 - i), imwidth - 1 - j) = red[j]; @@ -370,9 +369,9 @@ void transLineD1x (const float* const red, const float* const green, const float case TR_NONE: // no coarse rotation default: - rotateLine (red, image->r, tran, 2 * i, imwidth, imheight); - rotateLine (green, image->g, tran, 2 * i, imwidth, imheight); - rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight); + rotateLine(red, image->r, tran, 2 * i, imwidth, imheight); + rotateLine(green, image->g, tran, 2 * i, imwidth, imheight); + rotateLine(blue, image->b, tran, 2 * i, imwidth, imheight); if (i == 1 || i == 2) { // linear interpolation for (int j = 0; j < imwidth; j++) { @@ -426,7 +425,7 @@ void transLineD1x (const float* const red, const float* const green, const float namespace rtengine { -RawImageSource::RawImageSource () +RawImageSource::RawImageSource() : ImageSource() , W(0), H(0) , plistener(nullptr) @@ -476,7 +475,7 @@ RawImageSource::RawImageSource () //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -RawImageSource::~RawImageSource () +RawImageSource::~RawImageSource() { delete idata; @@ -493,11 +492,11 @@ RawImageSource::~RawImageSource () } if (camProfile) { - cmsCloseProfile (camProfile); + cmsCloseProfile(camProfile); } if (embProfile) { - cmsCloseProfile (embProfile); + cmsCloseProfile(embProfile); } } @@ -506,7 +505,7 @@ unsigned RawImageSource::FC(int row, int col) const return ri->FC(row, col); } -eSensorType RawImageSource::getSensorType () const +eSensorType RawImageSource::getSensorType() const { return ri != nullptr ? ri->getSensorType() : ST_NONE; } @@ -523,7 +522,7 @@ int RawImageSource::getRotateDegree() const //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::transformRect (const PreviewProps &pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) +void RawImageSource::transformRect(const PreviewProps &pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) { int pp_x = pp.getX() + border; int pp_y = pp.getY() + border; @@ -674,7 +673,7 @@ void RawImageSource::wbCamera2Mul(double &rm, double &gm, double &bm) double r = ri->get_pre_mul(0) / rm; double g = ri->get_pre_mul(1) / gm; double b = ri->get_pre_mul(2) / bm; - + if (imatrices) { double rr = imatrices->rgb_cam[0][0] * r + imatrices->rgb_cam[0][1] * g + imatrices->rgb_cam[0][2] * b; double gg = imatrices->rgb_cam[1][0] * r + imatrices->rgb_cam[1][1] * g + imatrices->rgb_cam[1][2] * b; @@ -692,7 +691,7 @@ void RawImageSource::wbCamera2Mul(double &rm, double &gm, double &bm) -void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, std::array& out_scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const +void RawImageSource::getWBMults(const ColorTemp &ctemp, const RAWParams &raw, std::array& out_scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const { // compute channel multipliers double r, g, b; @@ -704,7 +703,7 @@ void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, s gm = ri->get_pre_mul(1); bm = ri->get_pre_mul(2); } else { - ctemp.getMultipliers (r, g, b); + ctemp.getMultipliers(r, g, b); rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; @@ -715,9 +714,10 @@ void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, s float new_scale_mul[4]; bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) - || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); float c_white[4]; + for (int i = 0; i < 4; ++i) { c_white[i] = (ri->get_white(i) - cblacksom[i]) / static_cast(raw.expos) + cblacksom[i]; } @@ -741,10 +741,11 @@ void RawImageSource::getWBMults (const ColorTemp &ctemp, const RAWParams &raw, s autoGainComp = camInitialGain / initialGain; } -void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) -{// added int opposed to force getimage to use inpaint-opposed if enable, only once +void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) +{ + // added int opposed to force getimage to use inpaint-opposed if enable, only once MyMutex::MyLock lock(getImageMutex); - tran = defTransform (tran); + tran = defTransform(tran); // compute channel multipliers double r, g, b; @@ -756,9 +757,9 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima gm = ri->get_pre_mul(1); bm = ri->get_pre_mul(2); } else { - // ctemp.getMultipliers (r, g, b); - r = g = b = 1; - wbCamera2Mul(r, g, b); + // ctemp.getMultipliers (r, g, b); + r = g = b = 1; + wbCamera2Mul(r, g, b); rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; @@ -802,7 +803,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima defGain = 0.0; // compute image area to render in order to provide the requested part of the image int sx1, sy1, imwidth, imheight, fw, d1xHeightOdd = 0; - transformRect (pp, tran, sx1, sy1, imwidth, imheight, fw); + transformRect(pp, tran, sx1, sy1, imwidth, imheight, fw); // check possible overflows int maximwidth, maximheight; @@ -846,20 +847,24 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima bool iscolor = (hrp.method == "Color" || hrp.method == "Coloropp"); const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG; bool doHr = (hrp.hrenabled && !iscolor); + if (hrp.hrenabled && iscolor) { if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited the number to 1 rgbSourceModified = false; } + if (!rgbSourceModified) { - if(hrp.method == "Color") { + if (hrp.method == "Color") { if (settings->verbose) { - printf ("Applying Highlight Recovery: Color propagation.\n"); + printf("Applying Highlight Recovery: Color propagation.\n"); } - HLRecovery_inpaint (red, green, blue, hrp.hlbl); - } else if(hrp.method == "Coloropp" && ctemp.getTemp() >= 0) { + + HLRecovery_inpaint(red, green, blue, hrp.hlbl); + } else if (hrp.method == "Coloropp" && ctemp.getTemp() >= 0) { float s[3] = { rm, gm, bm }; highlight_recovery_opposed(s, ctemp, hrp.hlth); } + rgbSourceModified = true; } } @@ -874,6 +879,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima gm *= g; bm *= b; } + hlmax[0] = clmax[0] * rm; hlmax[1] = clmax[1] * gm; hlmax[2] = clmax[2] * bm; @@ -887,8 +893,8 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima rm /= area; gm /= area; bm /= area; - - + + #ifdef _OPENMP #pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) { @@ -973,15 +979,15 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima //process all highlight recovery other than "Color" if (doHr) { - hlRecovery (hrp.method, line_red, line_grn, line_blue, imwidth, hlmax); + hlRecovery(hrp.method, line_red, line_grn, line_blue, imwidth, hlmax); } if (d1x) { - transLineD1x (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd, doClip); + transLineD1x(line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd, doClip); } else if (fuji) { - transLineFuji (line_red, line_grn, line_blue, ix, image, tran, imheight, fw); + transLineFuji(line_red, line_grn, line_blue, ix, image, tran, imheight, fw); } else { - transLineStandard (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight); + transLineStandard(line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight); } } @@ -1040,22 +1046,22 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima // Flip if needed if (tran & TR_HFLIP) { - hflip (image); + hflip(image); } if (tran & TR_VFLIP) { - vflip (image); + vflip(image); } // Colour correction (only when running on full resolution) if (pp.getSkip() == 1) { - switch(ri->getSensorType()) { + switch (ri->getSensorType()) { case ST_BAYER: - processFalseColorCorrection (image, raw.bayersensor.ccSteps); + processFalseColorCorrection(image, raw.bayersensor.ccSteps); break; case ST_FUJI_XTRANS: - processFalseColorCorrection (image, raw.xtranssensor.ccSteps); + processFalseColorCorrection(image, raw.xtranssensor.ccSteps); break; case ST_FOVEON: @@ -1079,6 +1085,7 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA if (settings->verbose) { printf("Can't load DCP profile '%s'!\n", cmp.inputProfile.c_str()); } + return nullptr; } @@ -1089,13 +1096,13 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) { double pre_mul[3] = { ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2) }; - colorSpaceConversion (image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); + colorSpaceConversion(image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); } -void RawImageSource::getFullSize (int& w, int& h, int tr) +void RawImageSource::getFullSize(int& w, int& h, int tr) { - tr = defTransform (tr); + tr = defTransform(tr); if (fuji) { w = ri->get_FujiWidth() * 2 + 1; @@ -1120,7 +1127,7 @@ void RawImageSource::getFullSize (int& w, int& h, int tr) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getSize (const PreviewProps &pp, int& w, int& h) +void RawImageSource::getSize(const PreviewProps &pp, int& w, int& h) { w = pp.getWidth() / pp.getSkip() + (pp.getWidth() % pp.getSkip() > 0); h = pp.getHeight() / pp.getSkip() + (pp.getHeight() % pp.getSkip() > 0); @@ -1128,14 +1135,14 @@ void RawImageSource::getSize (const PreviewProps &pp, int& w, int& h) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::hflip (Imagefloat* image) +void RawImageSource::hflip(Imagefloat* image) { image->hflip(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::vflip (Imagefloat* image) +void RawImageSource::vflip(Imagefloat* image) { image->vflip(); } @@ -1143,7 +1150,7 @@ void RawImageSource::vflip (Imagefloat* image) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) +int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) { MyTime t1, t2; @@ -1151,15 +1158,17 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) fileName = fname; if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_DECODING"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_DECODING"); + plistener->setProgress(0.0); } + ri = new RawImage(fname); - int errCode = ri->loadRaw (false, 0, false); + int errCode = ri->loadRaw(false, 0, false); if (errCode) { return errCode; } + numFrames = firstFrameOnly ? (numFrames < 7 ? 1 : ri->getFrameCount()) : ri->getFrameCount(); errCode = 0; @@ -1172,6 +1181,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } else { numFrames = 6; } + #ifdef _OPENMP #pragma omp parallel #endif @@ -1180,15 +1190,17 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) #ifdef _OPENMP #pragma omp for nowait #endif + for (unsigned int i = 0; i < numFrames; ++i) { if (i == 0) { riFrames[i] = ri; - errCodeThr = riFrames[i]->loadRaw (true, i + 1, true, plistener, 0.8); + errCodeThr = riFrames[i]->loadRaw(true, i + 1, true, plistener, 0.8); } else { riFrames[i] = new RawImage(fname); - errCodeThr = riFrames[i]->loadRaw (true, i + 1); + errCodeThr = riFrames[i]->loadRaw(true, i + 1); } } + #ifdef _OPENMP #pragma omp critical #endif @@ -1205,15 +1217,18 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) #ifdef _OPENMP #pragma omp for nowait #endif - for (unsigned int i = 0; i < numFrames; ++i) { + + for (unsigned int i = 0; i < numFrames; ++i) + { if (i == 0) { riFrames[i] = ri; - errCodeThr = riFrames[i]->loadRaw (true, i, true, plistener, 0.8); + errCodeThr = riFrames[i]->loadRaw(true, i, true, plistener, 0.8); } else { riFrames[i] = new RawImage(fname); - errCodeThr = riFrames[i]->loadRaw (true, i); + errCodeThr = riFrames[i]->loadRaw(true, i); } } + #ifdef _OPENMP #pragma omp critical #endif @@ -1223,7 +1238,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } } else { riFrames[0] = ri; - errCode = riFrames[0]->loadRaw (true, 0, true, plistener, 0.8); + errCode = riFrames[0]->loadRaw(true, 0, true, plistener, 0.8); } if (!errCode) { @@ -1241,7 +1256,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } if (plistener) { - plistener->setProgress (0.9); + plistener->setProgress(0.9); } /***** Copy once constant data extracted from raw *******/ @@ -1256,7 +1271,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) // compute inverse of the color transformation matrix // first arg is matrix, second arg is inverse - inverse33 (imatrices.rgb_cam, imatrices.cam_rgb); + inverse33(imatrices.rgb_cam, imatrices.cam_rgb); d1x = ! ri->get_model().compare("D1X"); @@ -1269,11 +1284,11 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } if (ri->get_profile()) { - embProfile = cmsOpenProfileFromMem (ri->get_profile(), ri->get_profileLen()); + embProfile = cmsOpenProfileFromMem(ri->get_profile(), ri->get_profileLen()); } // create profile - memset (imatrices.xyz_cam, 0, sizeof(imatrices.xyz_cam)); + memset(imatrices.xyz_cam, 0, sizeof(imatrices.xyz_cam)); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) @@ -1281,8 +1296,8 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) imatrices.xyz_cam[i][j] += xyz_sRGB[i][k] * imatrices.rgb_cam[k][j]; } - camProfile = ICCStore::getInstance()->createFromMatrix (imatrices.xyz_cam, false, "Camera"); - inverse33 (imatrices.xyz_cam, imatrices.cam_xyz); + camProfile = ICCStore::getInstance()->createFromMatrix(imatrices.xyz_cam, false, "Camera"); + inverse33(imatrices.xyz_cam, imatrices.cam_xyz); // First we get the "as shot" ("Camera") white balance and store it float pre_mul[4]; @@ -1296,7 +1311,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) double cam_r = imatrices.rgb_cam[0][0] * camwb_red + imatrices.rgb_cam[0][1] * camwb_green + imatrices.rgb_cam[0][2] * camwb_blue; double cam_g = imatrices.rgb_cam[1][0] * camwb_red + imatrices.rgb_cam[1][1] * camwb_green + imatrices.rgb_cam[1][2] * camwb_blue; double cam_b = imatrices.rgb_cam[2][0] * camwb_red + imatrices.rgb_cam[2][1] * camwb_green + imatrices.rgb_cam[2][2] * camwb_blue; - camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1., ColorTemp::DEFAULT_OBSERVER); // as shot WB + camera_wb = ColorTemp(cam_r, cam_g, cam_b, 1., ColorTemp::DEFAULT_OBSERVER); // as shot WB if (settings->verbose) { printf("Raw As Shot White balance: temp %f, tint %f\n", camera_wb.getTemp(), camera_wb.getGreen()); @@ -1332,15 +1347,15 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]); }*/ - for (unsigned int i = 0;i < numFrames; ++i) { + for (unsigned int i = 0; i < numFrames; ++i) { riFrames[i]->set_prefilters(); } // Load complete Exif information - std::unique_ptr rml(new RawMetaDataLocation (ri->get_exifBase(), ri->get_ciffBase(), ri->get_ciffLen())); - idata = new FramesData (fname, std::move(rml)); - idata->setDCRawFrameCount (numFrames); + std::unique_ptr rml(new RawMetaDataLocation(ri->get_exifBase(), ri->get_ciffBase(), ri->get_ciffLen())); + idata = new FramesData(fname, std::move(rml)); + idata->setDCRawFrameCount(numFrames); green(W, H); red(W, H); @@ -1348,7 +1363,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) //hpmap = allocArray(W, H); if (plistener) { - plistener->setProgress (1.0); + plistener->setProgress(1.0); } plistener = nullptr; // This must be reset, because only load() is called through progressConnector @@ -1363,7 +1378,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise) +void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise) { // BENCHFUN MyTime t1, t2; @@ -1373,7 +1388,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le // Recalculate the scaling coefficients, using auto WB if selected in the Preprocess WB param. // Auto WB gives us better demosaicing and CA auto-correct performance for strange white balance settings (such as UniWB) float dummy_cblk[4] = { 0.f }; // Avoid overwriting c_black, see issue #5676 - ri->get_colorsCoeff( ref_pre_mul, scale_mul, dummy_cblk, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); + ri->get_colorsCoeff(ref_pre_mul, scale_mul, dummy_cblk, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1]; @@ -1383,7 +1398,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le const double ref_r = imatrices.rgb_cam[0][0] * refwb_red + imatrices.rgb_cam[0][1] * refwb_green + imatrices.rgb_cam[0][2] * refwb_blue; const double ref_g = imatrices.rgb_cam[1][0] * refwb_red + imatrices.rgb_cam[1][1] * refwb_green + imatrices.rgb_cam[1][2] * refwb_blue; const double ref_b = imatrices.rgb_cam[2][0] * refwb_red + imatrices.rgb_cam[2][1] * refwb_green + imatrices.rgb_cam[2][2] * refwb_blue; - const ColorTemp ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1., ColorTemp::DEFAULT_OBSERVER); + const ColorTemp ReferenceWB = ColorTemp(ref_r, ref_g, ref_b, 1., ColorTemp::DEFAULT_OBSERVER); if (settings->verbose) { printf("Raw Reference white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green); @@ -1438,14 +1453,16 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (numFrames == 4) { int bufferNumber = 0; - for (unsigned int i=0; i<4; ++i) { - if (i==currFrame) { + + for (unsigned int i = 0; i < 4; ++i) { + if (i == currFrame) { copyOriginalPixels(raw, ri, rid, rif, rawData); rawDataFrames[i] = &rawData; } else { if (!rawDataBuffer[bufferNumber]) { rawDataBuffer[bufferNumber] = new array2D; } + rawDataFrames[i] = rawDataBuffer[bufferNumber]; ++bufferNumber; copyOriginalPixels(raw, riFrames[i], rid, rif, *rawDataFrames[i]); @@ -1455,6 +1472,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (!rawDataBuffer[0]) { rawDataBuffer[0] = new array2D; } + rawDataFrames[1] = rawDataBuffer[0]; copyOriginalPixels(raw, riFrames[1], rid, rif, *rawDataFrames[1]); copyOriginalPixels(raw, ri, rid, rif, rawData); @@ -1467,6 +1485,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } else { copyOriginalPixels(raw, ri, rid, rif, rawData); } + //FLATFIELD end if (raw.ff_FromMetaData && isGainMapSupported()) { @@ -1510,7 +1529,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } if (numFrames == 4) { - for (int i=0; i<4; ++i) { + for (int i = 0; i < 4; ++i) { scaleColors(0, 0, W, H, raw, *rawDataFrames[i]); } } else { @@ -1520,6 +1539,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le // Correct vignetting of lens profile if (!hasFlatField && lensProf.useVign && lensProf.lcMode != LensProfParams::LcMode::NONE) { std::unique_ptr pmap; + if (lensProf.useLensfun()) { pmap = LFDatabase::getInstance()->findModifier(lensProf, idata, W, H, coarse, -1); } else { @@ -1532,6 +1552,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (pmap) { LensCorrection &map = *pmap; + if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) { if (numFrames == 4) { for (int i = 0; i < 4; ++i) { @@ -1550,8 +1571,8 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (ri->getSensorType() == ST_BAYER && (raw.hotPixelFilter > 0 || raw.deadPixelFilter > 0)) { if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_HOTDEADPIXELFILTER"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_HOTDEADPIXELFILTER"); + plistener->setProgress(0.0); } if (!bitmapBads) { @@ -1572,16 +1593,17 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (!bitmapBads) { bitmapBads.reset(new PixelsMap(W, H)); } - + int n = f.mark(rawData, *bitmapBads); totBP += n; if (n > 0) { if (settings->verbose) { - printf("Marked %d hot pixels from PDAF lines\n", n); + printf("Marked %d hot pixels from PDAF lines\n", n); } - auto &thresh = f.greenEqThreshold(); + auto &thresh = f.greenEqThreshold(); + if (numFrames == 4) { for (int i = 0; i < 4; ++i) { green_equilibrate(thresh, *rawDataFrames[i]); @@ -1594,17 +1616,17 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le // check if green equilibration is needed. If yes, compute G channel pre-compensation factors const auto globalGreenEq = - [&]() -> bool - { - CameraConstantsStore *ccs = CameraConstantsStore::getInstance(); - const CameraConst *cc = ccs->get(ri->get_maker().c_str(), ri->get_model().c_str()); - return cc && cc->get_globalGreenEquilibration(); - }; - + [&]() -> bool { + CameraConstantsStore *ccs = CameraConstantsStore::getInstance(); + const CameraConst *cc = ccs->get(ri->get_maker().c_str(), ri->get_model().c_str()); + return cc && cc->get_globalGreenEquilibration(); + }; + if (ri->getSensorType() == ST_BAYER && (raw.bayersensor.greenthresh || (globalGreenEq() && raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::VNG4)))) { if (settings->verbose) { printf("Performing global green equilibration...\n"); } + // global correction if (numFrames == 4) { for (int i = 0; i < 4; ++i) { @@ -1617,8 +1639,8 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (ri->getSensorType() == ST_BAYER && raw.bayersensor.greenthresh > 0) { if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_GREENEQUIL"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_GREENEQUIL"); + plistener->setProgress(0.0); } GreenEqulibrateThreshold thresh(0.01 * raw.bayersensor.greenthresh); @@ -1651,11 +1673,12 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if (ri->getSensorType() == ST_BAYER && raw.bayersensor.linenoise > 0) { if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_LINEDENOISE"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_LINEDENOISE"); + plistener->setProgress(0.0); } std::unique_ptr line_denoise_rowblender; + if (raw.bayersensor.linenoiseDirection == RAWParams::BayerSensor::LineNoiseDirection::PDAF_LINES) { PDAFLinesFilter f(ri); line_denoise_rowblender = f.lineDenoiseRowBlender(); @@ -1668,15 +1691,18 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if ((raw.ca_autocorrect || std::fabs(raw.cared) > 0.001 || std::fabs(raw.cablue) > 0.001) && ri->getSensorType() == ST_BAYER) { // Auto CA correction disabled for X-Trans, for now... if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_RAWCACORR"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_RAWCACORR"); + plistener->setProgress(0.0); } + if (numFrames == 4) { double fitParams[64]; float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure); + for (int i = 1; i < 3; ++i) { CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure); } + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure); } else { CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA, options.measure); @@ -1688,8 +1714,8 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le int aehistcompr; double clip = 0; int brightness, contrast, black, hlcompr, hlcomprthresh; - getAutoExpHistogram (aehist, aehistcompr); - ImProcFunctions::getAutoExp (aehist, aehistcompr, clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); + getAutoExpHistogram(aehist, aehistcompr); + ImProcFunctions::getAutoExp(aehist, aehistcompr, clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); } t2.set(); @@ -1710,13 +1736,13 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c if (ri->getSensorType() == ST_BAYER) { if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::HPHD)) { - hphd_demosaic (); + hphd_demosaic(); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::VNG4)) { - vng4_demosaic (rawData, red, green, blue); + vng4_demosaic(rawData, red, green, blue); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AHD)) { - ahd_demosaic (); + ahd_demosaic(); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE)) { - amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); + amaze_demosaic_RT(0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEBILINEAR) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBBILINEAR) @@ -1725,16 +1751,16 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) { if (!autoContrast) { double threshold = raw.bayersensor.dualDemosaicContrast; - dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, threshold, false); + dual_demosaic_RT(true, raw, W, H, rawData, red, green, blue, threshold, false); } else { - dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true); + dual_demosaic_RT(true, raw, W, H, rawData, red, green, blue, contrastThreshold, true); } } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCB)) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::EAHD)) { - eahd_demosaic (); + eahd_demosaic(); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::IGV)) { igv_interpolate(W, H); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::LMMSE)) { @@ -1758,9 +1784,9 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c } else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) || raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::TWO_PASS)) { if (!autoContrast) { double threshold = raw.xtranssensor.dualDemosaicContrast; - dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, threshold, false); + dual_demosaic_RT(false, raw, W, H, rawData, red, green, blue, threshold, false); } else { - dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true); + dual_demosaic_RT(false, raw, W, H, rawData, red, green, blue, contrastThreshold, true); } } else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) { nodemosaic(true); @@ -1779,12 +1805,14 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c rgbSourceModified = false; + if (cache) { if (!redCache) { redCache = new array2D(W, H); greenCache = new array2D(W, H); blueCache = new array2D(W, H); } + #ifdef _OPENMP #pragma omp parallel sections #endif @@ -1792,22 +1820,27 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c #ifdef _OPENMP #pragma omp section #endif + for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { (*redCache)[i][j] = red[i][j]; } } + #ifdef _OPENMP #pragma omp section #endif + for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { (*greenCache)[i][j] = green[i][j]; } } + #ifdef _OPENMP #pragma omp section #endif + for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { (*blueCache)[i][j] = blue[i][j]; @@ -1822,6 +1855,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c delete blueCache; blueCache = nullptr; } + if (settings->verbose) { if (getSensorType() == ST_BAYER) { printf("Demosaicing Bayer data: %s - %d usec\n", raw.bayersensor.method.c_str(), t2.etime(t1)); @@ -1836,10 +1870,10 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, const RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) { bool useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN"); - conversionBuffer[0] (W - 2 * border, H - 2 * border); - conversionBuffer[1] (W - 2 * border, H - 2 * border); - conversionBuffer[2] (W - 2 * border, H - 2 * border); - conversionBuffer[3] (W - 2 * border, H - 2 * border); + conversionBuffer[0](W - 2 * border, H - 2 * border); + conversionBuffer[1](W - 2 * border, H - 2 * border); + conversionBuffer[2](W - 2 * border, H - 2 * border); + conversionBuffer[3](W - 2 * border, H - 2 * border); LUTf *retinexgamtab = nullptr;//gamma before and after Retinex to restore tones LUTf lutTonereti; @@ -1883,9 +1917,9 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con double x; if (gamm2 < 1.) { - x = Color::igammareti (val, gamm, start, ts, mul , add); + x = Color::igammareti(val, gamm, start, ts, mul, add); } else { - x = Color::gammareti (val, gamm, start, ts, mul , add); + x = Color::gammareti(val, gamm, start, ts, mul, add); } lutTonereti[i] = CLIP(x * 65535.);// CLIP avoid in some case extra values @@ -2024,7 +2058,7 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con } } else { - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (cmp.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(cmp.workingProfile); const float wp[3][3] = { {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, @@ -2106,7 +2140,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara t4.set(); if (settings->verbose) { - printf ("Applying Retinex\n"); + printf("Applying Retinex\n"); } LUTf lutToneireti; @@ -2151,9 +2185,9 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara double x; if (gamm2 < 1.) { - x = Color::gammareti (val, gamm, start, ts, mul , add); + x = Color::gammareti(val, gamm, start, ts, mul, add); } else { - x = Color::igammareti (val, gamm, start, ts, mul , add); + x = Color::igammareti(val, gamm, start, ts, mul, add); } lutToneireti[i] = CLIP(x * 65535.); @@ -2167,7 +2201,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara const int HNew = H - 2 * border; const int WNew = W - 2 * border; - array2D LBuffer (WNew, HNew); + array2D LBuffer(WNew, HNew); float **temp = conversionBuffer[2]; // one less dereference LUTf dLcurve; LUTu hist16RET; @@ -2222,8 +2256,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara int pos = LBuffer[i][j]; hist16RETThr[pos]++; //histogram in Curve } - } - else + } else for (int j = 0; j < W - 2 * border; j++) { LBuffer[i][j] = temp[i][j]; } @@ -2300,7 +2333,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara } } else { - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (cmp.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(cmp.workingProfile); double wip[3][3] = { {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, @@ -2495,6 +2528,7 @@ void RawImageSource::flush() if (rawData) { rawData(0, 0); } + if (green) { green(0, 0); } @@ -2522,16 +2556,16 @@ void RawImageSource::flush() void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) { - // if (hrp.hrenabled && hrp.method == "Color") { - // if (!rgbSourceModified) { - // if (settings->verbose) { - // printf ("Applying Highlight Recovery: Color propagation...\n"); - // } +// if (hrp.hrenabled && hrp.method == "Color") { +// if (!rgbSourceModified) { +// if (settings->verbose) { +// printf ("Applying Highlight Recovery: Color propagation...\n"); +// } +// +// HLRecovery_inpaint (red, green, blue, hrp.hlbl); // - // HLRecovery_inpaint (red, green, blue, hrp.hlbl); -// // rgbSourceModified = true; - // } +// } // } } @@ -2557,16 +2591,19 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, con #ifdef _OPENMP #pragma omp parallel for #endif + for (int row = 0; row < H; row++) { const int c0 = FC(row, 0); const float black0 = black[(c0 == 1 && !(row & 1)) ? 3 : c0]; const int c1 = FC(row, 1); const float black1 = black[(c1 == 1 && !(row & 1)) ? 3 : c1]; int col; + for (col = 0; col < W - 1; col += 2) { rawData[row][col] = max(src->data[row][col] + black0 - riDark->data[row][col], 0.0f); rawData[row][col + 1] = max(src->data[row][col + 1] + black1 - riDark->data[row][col + 1], 0.0f); } + if (col < W) { rawData[row][col] = max(src->data[row][col] + black0 - riDark->data[row][col], 0.0f); } @@ -2607,6 +2644,7 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, con } } } + if (riFlatFile && W == riFlatFile->get_width() && H == riFlatFile->get_height()) { processFlatField(raw, riFlatFile, rawData, black); } // flatfield @@ -2810,7 +2848,7 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::defTransform (int tran) +int RawImageSource::defTransform(int tran) { int deg = ri->get_rotateDegree(); @@ -2849,7 +2887,7 @@ int RawImageSource::defTransform (int tran) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Thread called part -void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D &rbconv_Y, array2D &rbconv_I, array2D &rbconv_Q, array2D &rbout_I, array2D &rbout_Q, const int row_from, const int row_to) +void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2D &rbconv_Y, array2D &rbconv_I, array2D &rbconv_Q, array2D &rbout_I, array2D &rbout_Q, const int row_from, const int row_to) { const int W = im->getWidth(); @@ -2871,8 +2909,8 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D int px = (row_from - 1) % 3, cx = row_from % 3, nx = 0; - convert_row_to_YIQ (im->r(row_from - 1), im->g(row_from - 1), im->b(row_from - 1), rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); - convert_row_to_YIQ (im->r(row_from), im->g(row_from), im->b(row_from), rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); + convert_row_to_YIQ(im->r(row_from - 1), im->g(row_from - 1), im->b(row_from - 1), rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); + convert_row_to_YIQ(im->r(row_from), im->g(row_from), im->b(row_from), rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); for (int j = 0; j < W; j++) { rbout_I[px][j] = rbconv_I[px][j]; @@ -2885,11 +2923,11 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D cx = i % 3; nx = (i + 1) % 3; - convert_row_to_YIQ (im->r(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); + convert_row_to_YIQ(im->r(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); #ifdef __SSE2__ - pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0) , pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); - pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0) , pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); + pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0), pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); + pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0), pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); // fill first element in rbout_I and rbout_Q rbout_I[cx][0] = rbconv_I[cx][0]; @@ -2962,7 +3000,7 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // blur i-1th row if (i > row_from) { - convert_to_RGB (im->r(i - 1, 0), im->g(i - 1, 0), im->b(i - 1, 0), rbconv_Y[px][0], rbout_I[px][0], rbout_Q[px][0]); + convert_to_RGB(im->r(i - 1, 0), im->g(i - 1, 0), im->b(i - 1, 0), rbconv_Y[px][0], rbout_I[px][0], rbout_Q[px][0]); #ifdef _OPENMP #pragma omp simd @@ -2971,15 +3009,15 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D for (int j = 1; j < W - 1; j++) { float I = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbout_I[nx][j - 1] + rbout_I[nx][j] + rbout_I[nx][j + 1]) * onebynine; float Q = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbout_Q[nx][j - 1] + rbout_Q[nx][j] + rbout_Q[nx][j + 1]) * onebynine; - convert_to_RGB (im->r(i - 1, j), im->g(i - 1, j), im->b(i - 1, j), rbconv_Y[px][j], I, Q); + convert_to_RGB(im->r(i - 1, j), im->g(i - 1, j), im->b(i - 1, j), rbconv_Y[px][j], I, Q); } - convert_to_RGB (im->r(i - 1, W - 1), im->g(i - 1, W - 1), im->b(i - 1, W - 1), rbconv_Y[px][W - 1], rbout_I[px][W - 1], rbout_Q[px][W - 1]); + convert_to_RGB(im->r(i - 1, W - 1), im->g(i - 1, W - 1), im->b(i - 1, W - 1), rbconv_Y[px][W - 1], rbout_I[px][W - 1], rbout_Q[px][W - 1]); } } // blur last 3 row and finalize H-1th row - convert_to_RGB (im->r(row_to - 1, 0), im->g(row_to - 1, 0), im->b(row_to - 1, 0), rbconv_Y[cx][0], rbout_I[cx][0], rbout_Q[cx][0]); + convert_to_RGB(im->r(row_to - 1, 0), im->g(row_to - 1, 0), im->b(row_to - 1, 0), rbconv_Y[cx][0], rbout_I[cx][0], rbout_Q[cx][0]); #ifdef _OPENMP #pragma omp simd #endif @@ -2987,16 +3025,16 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D for (int j = 1; j < W - 1; j++) { float I = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbconv_I[nx][j - 1] + rbconv_I[nx][j] + rbconv_I[nx][j + 1]) * onebynine; float Q = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbconv_Q[nx][j - 1] + rbconv_Q[nx][j] + rbconv_Q[nx][j + 1]) * onebynine; - convert_to_RGB (im->r(row_to - 1, j), im->g(row_to - 1, j), im->b(row_to - 1, j), rbconv_Y[cx][j], I, Q); + convert_to_RGB(im->r(row_to - 1, j), im->g(row_to - 1, j), im->b(row_to - 1, j), rbconv_Y[cx][j], I, Q); } - convert_to_RGB (im->r(row_to - 1, W - 1), im->g(row_to - 1, W - 1), im->b(row_to - 1, W - 1), rbconv_Y[cx][W - 1], rbout_I[cx][W - 1], rbout_Q[cx][W - 1]); + convert_to_RGB(im->r(row_to - 1, W - 1), im->g(row_to - 1, W - 1), im->b(row_to - 1, W - 1), rbconv_Y[cx][W - 1], rbout_I[cx][W - 1], rbout_Q[cx][W - 1]); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // correction_YIQ_LQ -void RawImageSource::processFalseColorCorrection (Imagefloat* im, const int steps) +void RawImageSource::processFalseColorCorrection(Imagefloat* im, const int steps) { if (im->getHeight() < 4 || steps < 1) { @@ -3006,7 +3044,7 @@ void RawImageSource::processFalseColorCorrection (Imagefloat* im, const int ste #ifdef _OPENMP #pragma omp parallel { - multi_array2D buffer (W, 3); + multi_array2D buffer(W, 3); int tid = omp_get_thread_num(); int nthreads = omp_get_num_threads(); int blk = (im->getHeight() - 2) / nthreads; @@ -3014,19 +3052,19 @@ void RawImageSource::processFalseColorCorrection (Imagefloat* im, const int ste for (int t = 0; t < steps; t++) { if (tid < nthreads - 1) { - processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, 1 + (tid + 1)*blk); + processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, 1 + (tid + 1)*blk); } else { - processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, im->getHeight() - 1); + processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, im->getHeight() - 1); } #pragma omp barrier } } #else - multi_array2D buffer (W, 3); + multi_array2D buffer(W, 3); for (int t = 0; t < steps; t++) { - processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 , im->getHeight() - 1); + processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1, im->getHeight() - 1); } #endif @@ -3100,7 +3138,7 @@ 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 embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) { // MyTime t1, t2, t3; @@ -3134,7 +3172,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen // in this case we avoid using the slllllooooooowwww lcms // Calculate matrix for direct conversion raw>working space - TMatrix work = ICCStore::getInstance()->workingSpaceInverseMatrix (cmp.workingProfile); + TMatrix work = ICCStore::getInstance()->workingSpaceInverseMatrix(cmp.workingProfile); double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; for (int i = 0; i < 3; i++) @@ -3235,6 +3273,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen TMatrix toxyz = ICCStore::getInstance()->workingSpaceMatrix(cmp.workingProfile); TMatrix torgb = ICCStore::getInstance()->workingSpaceInverseMatrix("ProPhoto"); float rgb[3] = {0.f, 0.f, 0.f}; + for (int i = 0; i < 2 && !working_space_is_prophoto; ++i) { rgb[i] = 1.f; float x, y, z; @@ -3246,17 +3285,20 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen if (rgb[j] < 0.f || rgb[j] > 1.f) { working_space_is_prophoto = true; prophoto = ICCStore::getInstance()->workingSpace(cmp.workingProfile); + if (settings->verbose) { std::cout << "colorSpaceConversion_: converting directly to " << cmp.workingProfile << " instead of passing through ProPhoto" << std::endl; } + break; } + rgb[j] = 0.f; } } } - - lcmsMutex->lock (); + + lcmsMutex->lock(); switch (camera_icc_type) { case CAMERA_ICC_TYPE_PHASE_ONE: @@ -3265,7 +3307,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen transform_via_pcs_lab = true; separate_pcs_lab_highlights = true; // We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert. - hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, nullptr, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + hTransform = cmsCreateTransform(in, TYPE_RGB_FLT, nullptr, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -3283,24 +3325,24 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen case CAMERA_ICC_TYPE_NIKON: case CAMERA_ICC_TYPE_GENERIC: default: - hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety + hTransform = cmsCreateTransform(in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety break; } - lcmsMutex->unlock (); + lcmsMutex->unlock(); if (hTransform == nullptr) { // Fallback: create transform from camera profile. Should not happen normally. - lcmsMutex->lock (); - hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); - lcmsMutex->unlock (); + lcmsMutex->lock(); + hTransform = cmsCreateTransform(camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock(); } TMatrix toxyz = {}, torgb = {}; if (!working_space_is_prophoto) { - toxyz = ICCStore::getInstance()->workingSpaceMatrix ("ProPhoto"); - torgb = ICCStore::getInstance()->workingSpaceInverseMatrix (cmp.workingProfile); //sRGB .. Adobe...Wide... + toxyz = ICCStore::getInstance()->workingSpaceMatrix("ProPhoto"); + torgb = ICCStore::getInstance()->workingSpaceInverseMatrix(cmp.workingProfile); //sRGB .. Adobe...Wide... } #ifdef _OPENMP @@ -3389,10 +3431,10 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagemen } // Run icc transform - cmsDoTransform (hTransform, buffer.data, buffer.data, im->getWidth()); + cmsDoTransform(hTransform, buffer.data, buffer.data, im->getWidth()); if (separate_pcs_lab_highlights) { - cmsDoTransform (hTransform, hl_buffer.data, hl_buffer.data, im->getWidth()); + cmsDoTransform(hTransform, hl_buffer.data, hl_buffer.data, im->getWidth()); } // Apply post-processing @@ -3518,7 +3560,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed } else if (inProfile != "(camera)" && !inProfile.empty()) { Glib::ustring normalName = inProfile; - if (!inProfile.compare (0, 5, "file:")) { + if (!inProfile.compare(0, 5, "file:")) { normalName = inProfile.substr(5); } @@ -3527,7 +3569,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed } if (*dcpProf == nullptr) { - in = ICCStore::getInstance()->getProfile (inProfile); + in = ICCStore::getInstance()->getProfile(inProfile); } } @@ -3558,6 +3600,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi const float satthresh = 0.5; float clip[3]; + for (int c = 0; c < ColorCount; ++c) { clip[c] = rtengine::min(maxave, hlmax[c]); } @@ -3601,8 +3644,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi for (int c = 0; c < ColorCount; ++c) { lab[i][c] = 0; - for (int j = 0; j < ColorCount; j++) - { + for (int j = 0; j < ColorCount; j++) { lab[i][c] += trans[c][j] * cam[i][j]; } } @@ -3625,11 +3667,11 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi for (int c = 0; c < ColorCount; ++c) { cam[0][c] = 0; - for (int j = 0; j < ColorCount; j++) - { + for (int j = 0; j < ColorCount; j++) { cam[0][c] += itrans[c][j] * lab[0][j]; } } + for (int c = 0; c < ColorCount; ++c) { rgb[c] = cam[0][c] / ColorCount; } @@ -3669,7 +3711,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi } } -void RawImageSource::HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval) +void RawImageSource::HLRecovery_Luminance(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval) { for (int i = 0; i < width; i++) { @@ -3686,7 +3728,7 @@ void RawImageSource::HLRecovery_Luminance (float* rin, float* gin, float* bin, f double Ho = 2 * bo - ro - go; if (r != g && g != b) { - double ratio = std::sqrt ((Co * Co + Ho * Ho) / (C * C + H * H)); + double ratio = std::sqrt((Co * Co + Ho * Ho) / (C * C + H * H)); C *= ratio; H *= ratio; } @@ -3707,8 +3749,8 @@ void RawImageSource::HLRecovery_Luminance (float* rin, float* gin, float* bin, f //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, - int width, float maxval, double xyz_cam[3][3], double cam_xyz[3][3]) +void RawImageSource::HLRecovery_CIELab(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, + int width, float maxval, double xyz_cam[3][3], double cam_xyz[3][3]) { //static bool crTableReady = false; @@ -3764,16 +3806,15 @@ void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, floa //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::hlRecovery (const std::string &method, float* red, float* green, float* blue, int width, float* hlmax) +void RawImageSource::hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax) { -// BENCHFUN +// BENCHFUN if (method == "Luminance") { - HLRecovery_Luminance (red, green, blue, red, green, blue, width, 65535.0); + HLRecovery_Luminance(red, green, blue, red, green, blue, width, 65535.0); } else if (method == "CIELab blending") { - HLRecovery_CIELab (red, green, blue, red, green, blue, width, 65535.0, imatrices.xyz_cam, imatrices.cam_xyz); - } - else if (method == "Blend") { // derived from Dcraw + HLRecovery_CIELab(red, green, blue, red, green, blue, width, 65535.0, imatrices.xyz_cam, imatrices.cam_xyz); + } else if (method == "Blend") { // derived from Dcraw HLRecovery_blend(red, green, blue, width, 65535.0, hlmax); } @@ -3781,7 +3822,7 @@ void RawImageSource::hlRecovery (const std::string &method, float* red, float* g //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) +void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) { // BENCHFUN histcompr = 3; @@ -3802,7 +3843,7 @@ void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) for (int i = border; i < H - border; i++) { int start, end; - getRowStartEnd (i, start, end); + getRowStartEnd(i, start, end); if (ri->getSensorType() == ST_BAYER) { // precalculate factors to avoid expensive per pixel calculations @@ -3863,7 +3904,7 @@ void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) } // Histogram MUST be 256 in size; gamma is applied, blackpoint and gain also -void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) +void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { // BENCHFUN histRedRaw.clear(); @@ -3930,7 +3971,7 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU for (int i = border; i < H - border; i++) { int start, end; - getRowStartEnd (i, start, end); + getRowStartEnd(i, start, end); if (ri->getSensorType() == ST_BAYER) { int j; @@ -3983,11 +4024,10 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU } // end of parallel region const auto getidx = - [&](int c, int i) -> int - { - float f = mult[c] * std::max(0.f, i - cblacksom[c]); - return f > 0.f ? (f < 1.f ? 1 : std::min(int(f), 255)) : 0; - }; + [&](int c, int i) -> int { + float f = mult[c] * std::max(0.f, i - cblacksom[c]); + return f > 0.f ? (f < 1.f ? 1 : std::min(int(f), 255)) : 0; + }; for (int i = 0; i < histoSize; i++) { int idx = getidx(0, i); @@ -4010,12 +4050,10 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU if (ri->getSensorType() == ST_BAYER) // since there are twice as many greens, correct for it for (int i = 0; i < 256; i++) { histGreenRaw[i] >>= 1; - } - else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it + } else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it for (int i = 0; i < 256; i++) { histGreenRaw[i] = (histGreenRaw[i] * 2) / 5; - } - else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal + } else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal histGreenRaw += histRedRaw; histBlueRaw += histRedRaw; } @@ -4024,7 +4062,7 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getRowStartEnd (int x, int &start, int &end) +void RawImageSource::getRowStartEnd(int x, int &start, int &end) { if (fuji) { int fw = ri->get_FujiWidth(); @@ -4057,9 +4095,12 @@ static void histoxyY_low(int bfhitc, int bfwitc, const array2D & xc, cons #ifdef _OPENMP #pragma omp for schedule(dynamic, 4) nowait #endif - for (int y = 0; y < bfhitc ; y++) { + + for (int y = 0; y < bfhitc ; y++) + { for (int x = 0; x < bfwitc ; x++) { int nh = -1; + if (xc[y][x] < 0.12f && xc[y][x] > 0.03f && yc[y][x] > 0.1f) { // near Prophoto if (yc[y][x] < 0.2f) { nh = 0; @@ -4482,6 +4523,7 @@ static void histoxyY_low(int bfhitc, int bfwitc, const array2D & xc, cons } else if (xc[y][x] < 0.75f && yc[y][x] > 0.1f) { nh = 191; } + if (nh >= 0) { histxythr[nh]++; xxxthr[nh] += xc[y][x]; @@ -4490,6 +4532,7 @@ static void histoxyY_low(int bfhitc, int bfwitc, const array2D & xc, cons } } } + #ifdef _OPENMP #pragma omp critical #endif @@ -4503,16 +4546,21 @@ static void histoxyY_low(int bfhitc, int bfwitc, const array2D & xc, cons } +//enable display cells +//int cellxy[80][90] ; -static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy, bool purp) +static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy, bool purpe) { // calculate histogram x y in a range of 236 colors // this "choice" are guided by generally colors who are in nature skin, sky, etc. in those cases "steps" are small // of course we can change to be more precise // purp enable or not purple color in xyY - approximation... +//enable display cells +// int totalpixels = 0; + #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel // disabled if enable display cells #endif { LUTu histxythr(histxy.getSize()); @@ -4523,9 +4571,21 @@ static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const ar yyythr.clear(); LUTf YYYthr(YYY.getSize()); YYYthr.clear(); - // bool purp = false; + bool purp = true; + float Ypurp = 0.5f; + float Ypurpmax = 1.f; + //enable display cells + /* + // clear + for (int i = 0; i < 80; ++i) { + for (int j = 0 ; j < 90; ++j) { + cellxy[i][j] = 0; + } + } + */ #ifdef _OPENMP - #pragma omp for schedule(dynamic, 4) nowait + #pragma omp for schedule(dynamic, 4) nowait //disable if enable display cells + #endif for (int y = 0; y < bfhitc ; y++) @@ -4533,6 +4593,12 @@ static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const ar for (int x = 0; x < bfwitc ; x++) { int nh = -1; + if (!purpe) { + purp = (Yc[y][x] < Ypurp);//cut values with Y > Ypurp + } else { + purp = (Yc[y][x] < Ypurpmax);// + } + if (xc[y][x] < 0.12f && xc[y][x] > 0.03f && yc[y][x] > 0.1f) { // near Prophoto if (yc[y][x] < 0.2f) { nh = 0; @@ -5051,11 +5117,23 @@ static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const ar yyythr[nh] += yc[y][x]; YYYthr[nh] += Yc[y][x]; } + +//enable display cells + /* + // update + int x1 = (int)(100.0 * (xc[y][x])); + int y1 = (int)(100.0 * (yc[y][x])); + + if (x1 >= 0 && x1 < 80 && y1 >= 0 && y1 < 90) { + cellxy[x1][y1]++; + totalpixels++; + } + */ } } #ifdef _OPENMP - #pragma omp critical + #pragma omp critical //disable if enable display cells #endif { histxy += histxythr; @@ -5119,10 +5197,10 @@ float static studentXY(const array2D & YYcurr, const array2D & ref -void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar, const ToneCurveParams &hrp) +void RawImageSource::ItcWB(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, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar, const ToneCurveParams &hrp) { /* - Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com, update 2 - 2023 + Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com, update 6 - 2023 Copyright (c) Ingo Weyrich 3 - 2020 (heckflosse67@gmx.de) This algorithm try to find temperature correlation between 20 to 80 colors between 201 spectral color and about 20 to 55 color found in the image between 236, I just found the idea in the web "correlate with chroma" instead of RGB grey point,but I don't use any algo found on the web. @@ -5130,17 +5208,17 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double I have test many many algorithms to find the first one that work :) Probably (sure) there are improvement to do... - I have create a table temperature with temp and white point with 118 values between 2000K and 12000K we can obviously change these values, more...with different steps + I have create a table temperature with temp and white point with 191 values between 2000K and 15000K we can obviously change these values, more...with different steps I have create a table for tint (green)with 134 values between 0.4 to 4. - I have create or recuparate and transformed 201 spectral colors from Colorchecker24, others color and my 468 colors target, or from web flowers, etc. with a step of 5nm, I think it is large enough. - I think this value of 201 is now complete: I tested correlation with 60, 90, 100, 120, 155...better student increase with number of color, but now it seems stabilized + I have create or recuparate and transformed 406 spectral colors from Colorchecker24, others color and my 468 colors target, or from web flowers, etc. with a step of 5nm, I think it is large enough. + I think this value of 265 is now complete: I tested correlation with 60, 90, 100, 120, 155...better student increase with number of color, but now it seems stabilized Of course we can increase this number :) 1) for the current raw file we create a table for each temp of RGB multipliers 2) then, I choose the "camera temp" to initialize calculation (why not) - 3) for this temp, I calculated XYZ values for the 201 spectral data - 4) then I create for the image an "histogram", but for xyY (CIE 1931 color space or CIE 1964 (default)) - 5) for each pixel (in fact to accelerate only 1/5 for and 1/5 for y), I determine for each couple xy, the number of occurrences, can be change by Itcwb_precis to 3 or 9 + 3) for this temp, I calculated XYZ values for the 406 spectral data + 4) then I create for the image an "histogram", but for xyY (CIE 1931 color space or CIE 1964) + 5) for each pixel (in fact to accelerate only 1/3 for and 1/3 for y), I determine for each couple xy, the number of occurrences 6) I sort this result in ascending order 7) in option we can sort in another manner to take into account chroma : chromax = x - white point x, chromay = y - white point y 8) then I compare this result, with spectral data found above in 3) with deltaE (limited to chroma) @@ -5155,13 +5233,13 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double 17) after we pass this value to improccoordinator 18) in a second part if camera green is out, I used an "extra" algorithm - 19) we make vary green between 2 limits (settings in option) - 20) between these green limits, we make slightly vary temp (settings in options) and recalculated RGB multipliers + 19) we make vary green between 2 limits + 20) between these green limits, we make slightly vary temp and recalculated RGB multipliers 21) with this multipliers for the RGB color find in histogram we recalculate xyY 22) we re-adjust references color for these xyY from 20) 23) then find all Student correlation for each couple green / temp 24) sort these Student values, and choose the minimum - 25) then for the 5 better couple "temp / green" choose the one where green is nearest from 1. + 25) then for the 3 better couple "temp / green" choose the one where green is nearest from 1. Some variables or function are not used, keep in case of I have test with cat02 but result are not stable enough ! why ??, therefore cat02 neutralized @@ -5173,916 +5251,2139 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double You must avoid when illuminant is non standard (fluorescent, LED...) and also, when the subject is lost in the image (some target to generate profiles). You can change parameters in White Balance - Frame adapted to Itcwb - Itcwb_thres : 34 by default ==> number of color used in final algorithm - between 10 and max 55 - Itcwb_sorted : true by default, can improve algorithm if true, ==> sort value in something near chroma order, instead of histogram number - Itcwb_greenrange : 0 amplitude of green variation - between 0 to 2 - Itcwb_greendelta : 1 - delta temp in green iterate loop for "extra" - between 0 to 4 - Itcwb_forceextra : false by default - Use all Ciexy diagram instead of sRGB - //Itcwb_sizereference : repalce by int maxnb 3 by default, can be set to 5 ==> size of reference color compare to size of histogram real color - itcwb_delta : 1 by default can be set between 0 to 5 ==> delta temp to build histogram xy - if camera temp is not probably good - //itcwb_precis : replace by int precision = 3 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file - itcwb_nopurple : true default - allow to bypass highlight recovery and inpait opposed when need flowers and not purple due to highlights... - itcwb_fgreen : 5 by default - between 3 to 6 - find the compromise student / green to reach green near of 1 - - In file options. - use standard observer 10°, false = standard observer 2° + Itcwb_rgreen : 1 amplitude of green variation - between 0 to 2 + Itcwb_prim : sRGB, Beta rgb (default), XYZcam, JDCmax = Use near Ciexy diagram instead of sRGB + itcwb_delta : 4 by default can be set between 0 to 5 ==> delta temp to build histogram xy - if camera temp is not probably good + 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(); - Glib::ustring profuse; - profuse = "sRGB";//or "Adobe RGB" - if( wbpar.itcwb_forceextra && wbpar.itcwb_sampling == false) {//Adobe RGB - profuse = "ACESp0";//cover all CIE xy diagram - } - - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(profuse); //ACESp0 or sRGB - const float wp[3][3] = { - {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, - {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, - {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + bool itciterate = true; + bool lastitc = true; + + typedef struct Wboptim {//store config Itcwb + float stud; + float minc; + double titc; + double gritc; + double tempre; + double greenre; + int drea; + int kmi; + float minhis; + float maxhis; + double avg_r; + double avg_g; + double avg_b; + float delt; + + } Wboptim; + + Wboptim optitc[2] = { + {0.f, 0.f, 5000., 1., 5000., 1., 1, 1, 10.f, 100.f, 1., 1., 1., 0.f}, + {0.f, 0.f, 5000., 1., 5000., 1., 1, 1, 10.f, 100.f, 1., 1., 1., 0.f} }; + int nbitc = 0; + int choiceitc = 0; + bool oldsampling = wbpar.itcwb_sampling; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(profuse);//ACESp0 or sRGB - //inverse matrix user select - const float wip[3][3] = { - {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, - {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, - {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} - }; + while (itciterate) {//loop to find best mix minchrom and studgood and deltaE patch + Glib::ustring profuse; + profuse = "JDCmax"; - const int bfwitc = bfw; - const int bfhitc = bfh; + int limx = 0.05f; + int limy = 0.04f; - typedef struct WbGreen { - double green; - float snedecor;//1. actually but put in case of confiance interval - } WbGreen; - //green (tint) values between 0.4 to 4.0 - constexpr WbGreen gree[134] = {//symmetric coefficient between 0.717 and 1.40 - {0.400, 1.f}, - {0.420, 1.f}, - {0.440, 1.f}, - {0.460, 1.f}, - {0.480, 1.f}, - {0.500, 1.f}, - {0.520, 1.f}, - {0.540, 1.f}, - {0.550, 1.f}, - {0.560, 1.f}, - {0.570, 1.f}, - {0.580, 1.f}, - {0.590, 1.f}, - {0.600, 1.f}, - {0.610, 1.f}, - {0.620, 1.f},//extended range - {0.630, 1.f}, - {0.640, 1.f}, - {0.650, 1.f}, - {0.660, 1.f}, - {0.670, 1.f}, - {0.680, 1.f}, - {0.690, 1.f}, - {0.700, 1.f}, - {0.714, 1.f},//usual 2 range - {0.727, 1.f}, - {0.741, 1.f}, - {0.755, 1.f}, - {0.769, 1.f}, - {0.784, 1.f}, - {0.800, 1.f}, - {0.806, 1.f}, - {0.813, 1.f}, - {0.820, 1.f},//usual range - {0.826, 1.f}, - {0.833, 1.f}, - {0.840, 1.f}, - {0.847, 1.f}, - {0.855, 1.f}, - {0.862, 1.f}, - {0.870, 1.f}, - {0.877, 1.f}, - {0.885, 1.f}, - {0.893, 1.f}, - {0.901, 1.f}, - {0.909, 1.f}, - {0.917, 1.f}, - {0.926, 1.f}, - {0.935, 1.f}, - {0.943, 1.f}, - {0.952, 1.f}, - {0.962, 1.f}, - {0.971, 1.f}, - {0.980, 1.f}, - {0.990, 1.f}, - {1.000, 1.f},//55 reference - {1.010, 1.f}, - {1.020, 1.f}, - {1.030, 1.f}, - {1.040, 1.f}, - {1.050, 1.f}, - {1.060, 1.f}, - {1.070, 1.f}, - {1.080, 1.f}, - {1.090, 1.f}, - {1.100, 1.f}, - {1.110, 1.f}, - {1.120, 1.f}, - {1.130, 1.f}, - {1.140, 1.f}, - {1.150, 1.f}, - {1.160, 1.f}, - {1.170, 1.f}, - {1.180, 1.f}, - {1.190, 1.f}, - {1.200, 1.f}, - {1.210, 1.f}, - {1.220, 1.f}, - {1.230, 1.f}, - {1.240, 1.f}, - {1.250, 1.f},// usual range - {1.275, 1.f}, - {1.300, 1.f}, - {1.325, 1.f}, - {1.350, 1.f}, - {1.375, 1.f}, - {1.400, 1.f},//usual 2 range - {1.425, 1.f}, - {1.450, 1.f}, - {1.475, 1.f}, - {1.500, 1.f}, - {1.525, 1.f}, - {1.550, 1.f}, - {1.575, 1.f},//extended range - {1.600, 1.f}, - {1.633, 1.f}, - {1.666, 1.f}, - {1.700, 1.f}, - {1.733, 1.f}, - {1.766, 1.f}, - {1.800, 1.f}, - {1.833, 1.f}, - {1.866, 1.f}, - {1.900, 1.f}, - {1.933, 1.f}, - {1.966, 1.f}, - {2.000, 1.f}, - {2.033, 1.f}, - {2.066, 1.f}, - {2.100, 1.f}, - {2.133, 1.f}, - {2.166, 1.f}, - {2.200, 1.f}, - {2.250, 1.f}, - {2.300, 1.f}, - {2.350, 1.f}, - {2.400, 1.f}, - {2.450, 1.f}, - {2.500, 1.f}, - {2.550, 1.f}, - {2.600, 1.f}, - {2.650, 1.f}, - {2.700, 1.f}, - {2.750, 1.f}, - {2.800, 1.f}, - {2.850, 1.f}, - {2.900, 1.f}, - {2.950, 1.f}, - {3.000, 1.f}, - {3.200, 1.f}, - {3.400, 1.f}, - {3.600, 1.f}, - {3.800, 1.f}, - {4.000, 1.f} - }; - const int N_g = sizeof(gree) / sizeof(gree[0]); //number of green - - typedef struct RangeGreen { - int begin; - int end; - } RangeGreen; - - constexpr RangeGreen Rangestandard = {33, 80};//usual green range - constexpr RangeGreen Rangestandard2 = {24, 86};//usual 2 green range - constexpr RangeGreen Rangeextended = {15, 93}; - const RangeGreen Rangemax = {0, N_g}; - - RangeGreen Rangegreenused; - - if (wbpar.itcwb_rgreen == 0) { - Rangegreenused = Rangestandard; - } else if (wbpar.itcwb_rgreen == 1) { - Rangegreenused = Rangestandard2; - } else if (wbpar.itcwb_rgreen == 2) { - Rangegreenused = Rangeextended; - } else { - Rangegreenused = Rangemax; - } - if(wbpar.itcwb_sampling == true) { - Rangegreenused = Rangestandard2; - } - typedef struct WbTxyz { - double Tem; - double XX; - double ZZ; - } WbTxyz; - //we can change step to increase precision if need - also in Colortemp.cc with same changes - //I don't know how to pass this structure to Colortemp ! - // X and Z values calculate for each temp between 2000K to 12000K, so no result after 12000K ! - //of course we can change the step between each temp if need - constexpr WbTxyz Txyz[118] = {//temperature Xwb Zwb 118 values x wb and y wb are calculated after, Xwb and Ywb calculated with a spreadsheet - {2001., 1.273842, 0.145295}, - {2101., 1.244008, 0.167533}, - {2201., 1.217338, 0.190697}, - {2301., 1.193444, 0.214632}, - {2401., 1.171996, 0.239195}, - {2501., 1.152883, 0.264539}, - {2605., 1.134667, 0.290722}, - {2655., 1.126659, 0.303556}, - {2705., 1.119049, 0.316446}, - {2755., 1.111814, 0.329381}, - {2803., 1.105381, 0.342193}, - {2856., 1.098258, 0.355599}, - {2910., 1.091550, 0.369645}, - {2960., 1.085649, 0.382655}, - {3003., 1.080982, 0.394258}, - {3050., 1.075727, 0.406057}, - {3103., 1.070277, 0.419815}, - {3153., 1.065384, 0.432769}, - {3203., 1.060906, 0.446161}, - {3250., 1.056535, 0.457806}, - {3303., 1.052034, 0.471422}, - {3353., 1.047990, 0.484218}, - {3400., 1.044547, 0.496719}, - {3450., 1.040667, 0.508891}, - {3500., 1.037145, 0.521523}, - {3550., 1.033783, 0.534090}, - {3600., 1.030574, 0.546590}, - {3650., 1.027510, 0.559020}, - {3699., 1.024834, 0.571722}, - {3801., 1.019072, 0.596102}, - {3851., 1.016527, 0.608221}, - {3902., 1.014244, 0.621136}, - {3952., 1.011729, 0.632447}, - {4002., 0.996153, 0.609518}, - {4052., 0.993720, 0.620805}, - {4102., 0.993908, 0.631520}, - {4152., 0.989179, 0.643262}, - {4202., 0.989283, 0.653999}, - {4252., 0.985039, 0.665536}, - {4302., 0.985067, 0.676288}, - {4352., 0.981271, 0.687599}, - {4402., 0.981228, 0.698349}, - {4452., 0.977843, 0.709425}, - {4502., 0.977736, 0.720159}, - {4552., 0.974728, 0.730993}, - {4602., 0.974562, 0.741698}, - {4652., 0.971899, 0.752284}, - {4702., 0.971681, 0.762949}, - {4752., 0.969335, 0.773285}, - {4802., 0.969069, 0.783899}, - {4827., 0.967570, 0.788836}, - {4852., 0.967011, 0.793982}, - {4877., 0.966465, 0.799108}, - {4902., 0.965933, 0.804214}, - {4927., 0.965414, 0.809229}, - {4952., 0.964908, 0.814366}, - {4977., 0.964415, 0.819412}, - {5002., 0.963934, 0.824438},//57 reference - {5027., 0.963465, 0.829444}, - {5052., 0.963008, 0.834429}, - {5077., 0.962563, 0.839395}, - {5102., 0.962129, 0.844339}, - {5127., 0.961706, 0.849263}, - {5152., 0.961294, 0.854166}, - {5177., 0.960893, 0.859049}, - {5202., 0.960501, 0.863911}, - {5252., 0.959749, 0.873572}, - {5302., 0.959313, 0.883815}, - {5352., 0.958361, 0.892644}, - {5402., 0.957903, 0.902793}, - {5452., 0.957116, 0.911379}, - {5502., 0.956639, 0.921431}, - {5552., 0.956002, 0.929779}, - {5602., 0.955509, 0.939728}, - {5652., 0.955008, 0.947842}, - {5702., 0.954502, 0.957685}, - {5752., 0.954124, 0.965569}, - {5802., 0.953608, 0.975303}, - {5852., 0.953342, 0.982963}, - {5902., 0.952818, 0.992584}, - {5952., 0.952652, 1.000025}, - {6002., 0.952122, 1.009532}, - {6052., 0.952047, 1.016759}, - {6102., 0.951514, 1.026149}, - {6152., 0.951520, 1.033168}, - {6202., 0.950985, 1.042439}, - {6252., 0.951064, 1.049256}, - {6302., 0.950530, 1.058406}, - {6352., 0.950674, 1.065027}, - {6402., 0.950143, 1.074055}, - {6452., 0.950345, 1.080484}, - {6502., 0.950201, 1.088097}, - {6552., 0.950070, 1.095633}, - {6602., 0.949952, 1.103094}, - {6652., 0.949846, 1.110479}, - {6702., 0.949752, 1.119138}, - {6752., 0.949668, 1.125027}, - {6802., 0.949596, 1.132190}, - {6902., 0.949033, 1.147691}, - {7002., 0.949402, 1.160129}, - {7152., 0.949348, 1.180429}, - {7301., 0.948896, 1.201432}, - {7451., 0.949434, 1.219076}, - {7601., 0.949099, 1.239061}, - {7751., 0.949729, 1.255559}, - {7901., 0.949498, 1.274460}, - {8151., 0.950361, 1.300912}, - {8301., 0.950253, 1.318464}, - {8451., 0.950966, 1.332651}, - {8601., 0.950941, 1.349261}, - {8801., 0.951772, 1.367421}, - {9001., 0.951969, 1.387639}, - {9201., 0.952784, 1.404422}, - {9401., 0.953081, 1.423213}, - {9901., 0.954537, 1.464134}, - {10501., 0.956321, 1.508623}, - {11001., 0.957747, 1.541281}, - {12001., 0.960440, 1.601019} - }; - const int N_t = sizeof(Txyz) / sizeof(Txyz[0]); //number of temperature White point - constexpr int Nc = 201 + 1;//201 number of reference spectral colors, I think it is enough to retrieve good values - array2D Tx(N_t, Nc); - array2D Ty(N_t, Nc); - array2D Tz(N_t, Nc); - array2D Ta(N_t, Nc); - array2D Tb(N_t, Nc); - array2D TL(N_t, Nc); - double TX[Nc]; - double TY[Nc]; - double TZ[Nc]; - std::vector good_spectral(Nc, false); - - float rmm[N_t]; - float gmm[N_t]; - float bmm[N_t]; - - int siza = 237; //192 until 01/2023 size of histogram - if(wbpar.itcwb_sampling == true) { - siza = 192;//old sampling 5.9 and before... - } - // tempref and greenref are camera wb values. - // I used them by default to select good spectral values !! but they are changed after - tempref = rtengine::min(tempref, 12000.0); - - int repref = 0; - - for (int tt = 0; tt < N_t; tt++) { - if (Txyz[tt].Tem > tempref) { - repref = tt;//show the select temp - break; - } - } - - //calculate R G B multiplier in function illuminant and temperature - const bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) - || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); - for (int tt = 0; tt < N_t; ++tt) { - double r, g, b; - float rm, gm, bm; - ColorTemp WBiter = ColorTemp(Txyz[tt].Tem, greenitc, 1.f, "Custom", wbpar.observer); - WBiter.getMultipliers(r, g, b); - - rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; - gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; - bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; - - const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; - float new_scale_mul[4]; - const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); - - rm = new_scale_mul[0] / scale_mul[0] * gain; - gm = new_scale_mul[1] / scale_mul[1] * gain; - bm = new_scale_mul[2] / scale_mul[2] * gain; - rmm[tt] = rm / gm; - gmm[tt] = 1.f; - bmm[tt] = bm / gm; - //return rmm, gmm, bmm in function of temp - } - - struct hiss { - int histnum; - int index; - bool operator()(const hiss& lhis, const hiss& rhis) - { - return lhis.histnum < rhis.histnum; + if (wbpar.itcwb_prim == "srgb") { + profuse = "sRGB"; + limx = 0.12f; + limy = 0.06f; + } else if (wbpar.itcwb_prim == "beta") { + profuse = "Beta RGB"; + limx = 0.1f; + limy = 0.05f; + } else if (wbpar.itcwb_prim == "XYZcam") { + profuse = "XYZcam"; + limx = 0.05f; + limy = 0.04f; + } else if (wbpar.itcwb_prim == "jdcmax") { + profuse = "JDCmax"; + limx = 0.05f; + limy = 0.04f; } - } ; - //intermediate structure - struct chrom { - float chroxy_number; - float chroxy; - float chrox; - float chroy; - float Y; - int index; - int interest; - bool operator()(const chrom& lchro, const chrom& rchro) - { - return lchro.chroxy_number < rchro.chroxy_number; + if (oldsampling) { + profuse = "sRGB"; } - } ; + float wb[3][3], iwb[3][3]; + double wb2[3][3]; - LUTu histxy(siza); //number of values for each pair xy + if (profuse == "XYZcam") {//thanks to Reffort - histxy.clear(); + // get a copy of the camera matrices + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + wb[r][c] = imatrices.xyz_cam[r][c]; + wb2[r][c] = imatrices.xyz_cam[r][c]; + iwb[r][c] = imatrices.cam_xyz[r][c]; + } + } + } else if ((cmp.inputProfile == "(camera)")) {//when no input profile found or if user select Camera standard + if (settings->verbose) { + printf("Use Camera Dcraw-Matrix and modify rgbloc\n"); + } - LUTf xxx(siza);//for color references calculated ==> max in images "like histogram" + //improvment with new values for redloc, greenloc, blueloc when Camera Dcraw is used + TMatrix iwork = ICCStore::getInstance()->workingSpaceInverseMatrix(profuse); + TMatrix workn = ICCStore::getInstance()->workingSpaceMatrix(profuse); + double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - xxx.clear(); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { + mat[i][j] += iwork[i][k] * imatrices.xyz_cam[k][j]; // rgb_xyz * imatrices.xyz_cam + } - LUTf yyy(siza); - - yyy.clear(); - - LUTf YYY(siza);//not used directly, but necessary to keep good range - - YYY.clear(); - - bool separated = true; - - int w = -1; - - array2D reff_spect_yy_camera(N_t, 2 * Nc + 2); - - array2D reff_spect_xx_camera(N_t, 2 * Nc + 2); - - //here we select the good spectral color inside the 113 values - //call tempxy to calculate for 201 color references Temp and XYZ with cat02 - - ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar); //calculate chroma xy (xyY) for Z known colors on under 200 illuminants - - //find the good spectral values - //calculate xy reference spectral for tempref - for (int j = 0; j < Nc ; j++) { - reff_spect_xx_camera[j][repref] = TX[j] / (TX[j] + TY[j] + TZ[j]); // x from xyY - reff_spect_yy_camera[j][repref] = TY[j] / (TX[j] + TY[j] + TZ[j]); // y from xyY - } - - array2D xc(bfwitc, bfhitc); - array2D yc(bfwitc, bfhitc); - array2D Yc(bfwitc, bfhitc); - - const int deltarepref = 1; //settings->itcwb_delta; - - for (int nn = 0, drep = -deltarepref; nn <= 2; ++nn, drep += deltarepref) { - //three loop to refine color if temp camera is probably not very good - const int rep = rtengine::LIM(repref + drep, 0, N_t); - - //initialize calculation of xy current for tempref #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int y = 0; y < bfh ; ++y) { - for (int x = 0; x < bfw ; ++x) { - const float RR = rmm[rep] * redloc[y][x]; - const float GG = gmm[rep] * greenloc[y][x]; - const float BB = bmm[rep] * blueloc[y][x]; - Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wp);//use sRGB or ACESp0 + for (int y = 0; y < bfh; y++) + for (int x = 0; x < bfw; x++) { + + float newred = mat[0][0] * redloc[y][x] + mat[0][1] * greenloc[y][x] + mat[0][2] * blueloc[y][x]; + float newgreen = mat[1][0] * redloc[y][x] + mat[1][1] * greenloc[y][x] + mat[1][2] * blueloc[y][x]; + float newblue = mat[2][0] * redloc[y][x] + mat[2][1] * greenloc[y][x] + mat[2][2] * blueloc[y][x]; + + redloc[y][x] = newred;//new values for redloc + greenloc[y][x] = newgreen; + blueloc[y][x] = newblue; + + } + + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + wb[r][c] = workn[r][c]; + wb2[r][c] = workn[r][c]; + iwb[r][c] = iwork[r][c]; + } } - } - //histogram xy depend of temp...but in most cases D45 ..D65.. - //calculate for this image the mean values for each family of color, near histogram x y (number) - //xy vary from x 0..0.77 y 0..0.82 - //neutral values are near x=0.34 0.33 0.315 0.37 y =0.35 0.36 0.34 - //skin are about x 0.45 0.49 y 0.4 0.47 - //blue sky x=0.25 y=0.28 and x=0.29 y=0.32 - // step about 0.02 x 0.32 0.34 y= 0.34 0.36 skin -- sky x 0.24 0.30 y 0.28 0.32 - //big step about 0.2 - - bool purp = true;//if inpaint-opposed or something else enable purp - - // if (hrp.hrenabled && hrp.method == "Coloropp" && settings->itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) - if (hrp.hrenabled && hrp.method == "Coloropp" && wbpar.itcwb_nopurple == true) {//we disabled (user) with settings if image are naturally with purple (flowers...) - purp = false; - } - if(wbpar.itcwb_sampling == false) { - //printf("Use high sampling\n"); - histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB - //return histogram x and y for each temp and in a range of 235 colors (siza) } else { - //printf("Use low sampling - 5.9\n"); - histoxyY_low(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy);//low scaling - } - } - // free some memory - xc.free(); - yc.free(); - Yc.free(); - //calculate x y Y - const int sizcurrref = siza;//choice of number of correlate colors in image - array2D histcurrref(N_t, sizcurrref); - array2D xx_curref(N_t, sizcurrref); - array2D yy_curref(N_t, sizcurrref); - array2D YY_curref(N_t, sizcurrref); - array2D xx_curref_reduc(N_t, sizcurrref); - array2D yy_curref_reduc(N_t, sizcurrref); - array2D YY_curref_reduc(N_t, sizcurrref); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(profuse); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(profuse); - hiss Wbhis[siza]; - - for (int nh = 0; nh < siza; nh++) { - Wbhis[nh].histnum = histxy[nh]; - Wbhis[nh].index = nh; - } - - //sort in ascending order - std::sort(Wbhis, Wbhis + siza, Wbhis[0]); - - int n1 = 0; - int n4 = 0; - int n15 = 0; - int n30 = 0; - - //part to improve - //determined the number of colors who be used after - for (int nh = 0; nh < siza; nh++) { - if (Wbhis[nh].histnum < 30) { - n30++; //keep only existing color but avoid to small - - if (Wbhis[nh].histnum < 15) { - n15++; //keep only existing color but avoid to small - - if (Wbhis[nh].histnum < 4) { - n4++; //keep only existing color but avoid to small - - if (Wbhis[nh].histnum < 1) { - n1++; //keep only existing color but avoid to small - } + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + wb[r][c] = wprof[r][c]; + wb2[r][c] = wprof[r][c]; + iwb[r][c] = wiprof[r][c]; } } } - } - - int ntr = n30; - - if (ntr > (siza - 25)) { - ntr = n15; //if to less elements 25 elements mini - } - - if (ntr > (siza - 23)) { - ntr = n4; //if to less elements 25 elements mini - } - - if (ntr > (siza - 20)) { - ntr = n1; //if to less elements 20 elements mini - normally never be used ! - } - - int sizcurr2ref = sizcurrref - ntr; - const int sizcu30 = sizcurrref - n30; - int nbm = 77;//number max of color used = 1.4 * 55 in case all CIExy diagram - if(profuse == "sRGB" || wbpar.itcwb_sampling == true) { - nbm = 55; - } - const int sizcu4 = rtengine::min(sizcu30, nbm);//size of chroma values - - if (settings->verbose) { - printf("ntr=%i sizcurr2ref=%i sizcu30=%i sizcu4=%i\n", ntr, sizcurr2ref, sizcu30, sizcu4); - } - - chrom wbchro[sizcu4]; - const float swpr = Txyz[repref].XX + Txyz[repref].ZZ + 1.f; - const float xwpr = Txyz[repref].XX / swpr;//white point for tt in xy coordinates - const float ywpr = 1.f / swpr; - - for (int i = 0; i < sizcu4; ++i) { //take the max values - histcurrref[i][repref] = Wbhis[siza - (i + 1)].histnum; - xx_curref[i][repref] = xxx[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; - yy_curref[i][repref] = yyy[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; - YY_curref[i][repref] = YYY[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; - } - - float estimchrom = 0.f; - - //estimate chromaticity for references - for (int nh = 0; nh < sizcu4; ++nh) { - const float chxy = std::sqrt(SQR(xx_curref[nh][repref] - xwpr) + SQR(yy_curref[nh][repref] - ywpr)); - wbchro[nh].chroxy_number = chxy * std::sqrt(histcurrref[nh][repref]); - wbchro[nh].chroxy = std::sqrt(chxy); - wbchro[nh].chrox = xx_curref[nh][repref]; - wbchro[nh].chroy = yy_curref[nh][repref]; - wbchro[nh].Y = YY_curref[nh][repref]; - wbchro[nh].index = nh; - estimchrom += chxy; - } - - estimchrom /= sizcu4; - - if (settings->verbose) { - printf("estimchrom=%f\n", estimchrom); - } - bool issorted = wbpar.itcwb_sorted; - - if(wbpar.itcwb_sampling == true) { - issorted = false; - } - - - if (issorted) { //sort in ascending with chroma values - std::sort(wbchro, wbchro + sizcu4, wbchro[0]); - } - - int maxval = rtengine::LIM(wbpar.itcwb_thres, 10, 55);//max values of color to find correlation - if(wbpar.itcwb_sampling == true) { - maxval = 34; - } - - sizcurr2ref = rtengine::min(sizcurr2ref, maxval); //keep about the biggest values, - - for (int i = 0; i < sizcurr2ref; ++i) { - //is condition chroxy necessary ? - if (wbchro[sizcu4 - (i + 1)].chrox > 0.1f && wbchro[sizcu4 - (i + 1)].chroy > 0.1f && wbchro[sizcu4 - (i + 1)].chroxy > 0.0f) { //suppress value too far from reference spectral - w++; - xx_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chrox; - yy_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroy; - YY_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].Y; - } - } - - //calculate deltaE xx to find best values of spectrals data - limited to chroma values - // int maxnb = rtengine::LIM(settings->itcwb_sizereference, 1, 5); - // int maxnb = rtengine::LIM(wbpar.itcwb_size, 1, 5); - int maxnb = 3; - //wbpar.itcwb_size to verify if this setting is useful...diificulties with High gamut and limited patch spectral colors. - - if (wbpar.itcwb_thres > 55) {//normally never used - maxnb = 201 / wbpar.itcwb_thres; - } - - for (int nb = 1; nb <= maxnb; ++nb) { //max 5 iterations for Itcwb_thres=33, after trial 3 is good in most cases but in some cases 5 - for (int i = 0; i < w; ++i) { - float mindeltaE = 100000.f;//we can change this value... - int kN = 0; - - for (int j = 0; j < Nc ; j++) { - if (!good_spectral[j]) { - const float deltaE = SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[j][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[j][repref]); - - if (deltaE < mindeltaE) { - mindeltaE = deltaE; - kN = j; - } - } - } - - good_spectral[kN] = true;//good spectral are spectral color that match color histogram xy - } - } - - // reuse some buffers - array2D& R_curref_reduc = xx_curref_reduc; - array2D& G_curref_reduc = yy_curref_reduc; - array2D& B_curref_reduc = YY_curref_reduc; - - //reconvert to RGB for "reduction" - for (int i = 0; i < w; i++) { - const float X = 65535.f * xx_curref_reduc[i][repref] * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; - const float Y = 65535.f * YY_curref_reduc[i][repref]; - const float Z = 65535.f * (1.f - xx_curref_reduc[i][repref] - yy_curref_reduc[i][repref]) * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; - float r, g, b; - Color::xyz2rgb(X, Y, Z, r, g, b, wip); - R_curref_reduc[i][repref] = r / rmm[repref]; - G_curref_reduc[i][repref] = g / gmm[repref]; - B_curref_reduc[i][repref] = b / bmm[repref]; - - } - -//end first part - - //Now begin real calculations - separated = false; - //recalculate histogram with good values and not estimated - ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar); //calculate chroma xy (xyY) for Z known colors on under 90 illuminants - //calculate x y Y - int sizcurr = siza;//choice of number of correlate colors in image - array2D xxyycurr_reduc(N_t, 2 * sizcurr); - array2D reff_spect_xxyy(N_t, 2 * Nc + 2); - array2D reff_spect_xxyy_prov(N_t, 2 * Nc + 2); - - float minstud = 100000.f; - int goodref = 1; - -//calculate x y z for each pixel with multiplier rmm gmm bmm - - for (int tt = 0; tt < N_t; ++tt) {//N_t - for (int i = 0; i < w; ++i) { - float unused; - - const float RR = rmm[tt] * R_curref_reduc[i][repref]; - const float GG = gmm[tt] * G_curref_reduc[i][repref]; - const float BB = bmm[tt] * B_curref_reduc[i][repref]; - Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wp); - } - - for (int j = 0; j < Nc ; ++j) { - reff_spect_xxyy_prov[2 * j][tt] = Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // x from xyY - reff_spect_xxyy_prov[2 * j + 1][tt] = Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // y from xyY - } - - int kk = -1; - - for (int i = 0; i < Nc ; ++i) { - if (good_spectral[i]) { - kk++; - //we calculate now absolute chroma for each spectral color - reff_spect_xxyy[2 * kk][tt] = reff_spect_xxyy_prov[2 * i][tt]; - reff_spect_xxyy[2 * kk + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; - } - } - - const float abstud = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * kk, tt)); - - if (abstud < minstud) { // find the minimum Student - minstud = abstud; - goodref = tt; - } - } - - if (extra) {//always used if extra = true because I made this choice, brings better results - struct Tempgreen { - float student; - int tempref; - int greenref; - bool operator()(const Tempgreen& ltg, const Tempgreen& rtg) - { - return ltg.student < rtg.student; - } - }; - Tempgreen Tgstud[N_g]; - - for (int i = 0; i < N_g; ++i) {//init variables with - Tgstud[i].student = 1000.f;//max value to initialize - Tgstud[i].tempref = 57;//5002K position in the list - Tgstud[i].greenref = 55;// 1.f position in the list - } - - int dgoodref = rtengine::LIM(wbpar.itcwb_delta,1, 4); - if(wbpar.itcwb_sampling == true) { - dgoodref = 2; - } - const int scantempbeg = rtengine::max(goodref - (dgoodref + 1), 1); - const int scantempend = rtengine::min(goodref + dgoodref, N_t - 1); - - for (int gr = Rangegreenused.begin; gr < Rangegreenused.end; ++gr) { - float minstudgr = 100000.f; - int goodrefgr = 1; - - for (int tt = scantempbeg; tt < scantempend; ++tt) { - double r, g, b; - ColorTemp WBiter(Txyz[tt].Tem, gree[gr].green, 1.f, "Custom", wbpar.observer); - WBiter.getMultipliers(r, g, b); - float rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; - float gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; - float bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; - //recalculate Multipliers now with good range of temp and green - - const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; - float new_scale_mul[4]; - const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); - - rm = new_scale_mul[0] / scale_mul[0] * gain; - gm = new_scale_mul[1] / scale_mul[1] * gain; - bm = new_scale_mul[2] / scale_mul[2] * gain; - rmm[tt] = rm / gm; - gmm[tt] = 1.f; - bmm[tt] = bm / gm; - } - - - for (int tt = scantempbeg; tt < scantempend; ++tt) {//N_t - for (int i = 0; i < w; ++i) { - float unused; - - const float RR = rmm[tt] * R_curref_reduc[i][repref]; - const float GG = gmm[tt] * G_curref_reduc[i][repref]; - const float BB = bmm[tt] * B_curref_reduc[i][repref]; - Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wp); - } - - //recalculate xy spectral now with good range of temp and green - - for (int j = 0; j < Nc ; ++j) { - reff_spect_xxyy_prov[2 * j][tt] = Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // x from xyY - reff_spect_xxyy_prov[2 * j + 1][tt] = Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // y from xyY - } - - int kkg = -1; - - for (int i = 0; i < Nc ; ++i) { - if (good_spectral[i]) { - kkg++; - reff_spect_xxyy[2 * kkg][tt] = reff_spect_xxyy_prov[2 * i][tt]; - reff_spect_xxyy[2 * kkg + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; - } - } - - //now we have good spectral data - //calculate student correlation - const float abstudgr = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * kkg, tt)); - - if (abstudgr < minstudgr) { // find the minimum Student - minstudgr = abstudgr; - goodrefgr = tt; - } - - //found the values - Tgstud[gr].tempref = goodrefgr; - Tgstud[gr].greenref = gr; - Tgstud[gr].student = minstudgr; - - } - } - - std::sort(Tgstud, Tgstud + N_g, Tgstud[0]); - - // now search the value of green the nearest of 1 with a good student value, I think it is a good choice, perhaps no... - // I take the 5 first values - // I admit a symetrie in green coefiicient for rgb multiplier...probably not exactly true - // perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% - int greengood = 55; - - int maxkgood = wbpar.itcwb_fgreen;//we can change ...to test 3, 4, 5. High values perhaps less good student, but it is a compromise... - maxkgood = rtengine::LIM(maxkgood, 3, 6); - if(wbpar.itcwb_sampling == true) { - maxkgood = 3; // force to 3 with old low sampling - } - - int mingood = std::min(std::fabs(Tgstud[0].greenref - 55), std::fabs(Tgstud[1].greenref - 55)); - - for (int k = 2; k < maxkgood; ++k) { - mingood = std::min(std::fabs(mingood), std::fabs(Tgstud[k].greenref - 55)); - } - - for (int k = 0; k < maxkgood ; ++k) { - if (mingood == fabs(Tgstud[k].greenref - 55)) { - greengood = Tgstud[k].greenref ; - goodref = Tgstud[k].tempref; - studgood = Tgstud[k].student;; - } - } if (settings->verbose) { - printf("Student_0=%f Student_k= %f\n", Tgstud[0].student, Tgstud[maxkgood - 1].student); - printf("mingood=%i greeng=%i goodref=%i stud=%f\n", mingood, greengood, goodref, (double) studgood); + printf("Sampling=%s \n", profuse.c_str()); + printf("wp = %f %f %f\n", wb[0][0], wb[0][1], wb[0][2]); + printf(" %f %f %f\n", wb[1][0], wb[1][1], wb[1][2]); + printf(" %f %f %f\n", wb[2][0], wb[2][1], wb[2][2]); } - tempitc = Txyz[goodref].Tem; - greenitc = gree[greengood].green; + const int bfwitc = bfw; + const int bfhitc = bfh; - if (estimchrom < 0.025f) { - float ac = -2.40f * estimchrom + 0.06f;//small empirical correction, maximum 0.06 if chroma=0 for all image, currently for very low chroma +0.02 - greenitc += ac; + typedef struct WbGreen { + double green; + float snedecor;//1. actually but put in case of confiance interval + } WbGreen; + //green (tint) values between 0.4 to 4.0 + constexpr WbGreen gree[134] = {//symmetric coefficient between 0.717 and 1.40 + {0.400, 1.f}, + {0.420, 1.f}, + {0.440, 1.f}, + {0.460, 1.f}, + {0.480, 1.f}, + {0.500, 1.f}, + {0.520, 1.f}, + {0.540, 1.f}, + {0.550, 1.f}, + {0.560, 1.f}, + {0.570, 1.f}, + {0.580, 1.f}, + {0.590, 1.f}, + {0.600, 1.f}, + {0.610, 1.f}, + {0.620, 1.f},//extended range + {0.630, 1.f}, + {0.640, 1.f}, + {0.650, 1.f}, + {0.660, 1.f}, + {0.670, 1.f}, + {0.680, 1.f}, + {0.690, 1.f}, + {0.700, 1.f}, + {0.714, 1.f},//usual 2 range + {0.727, 1.f}, + {0.741, 1.f}, + {0.755, 1.f}, + {0.769, 1.f}, + {0.784, 1.f}, + {0.800, 1.f}, + {0.806, 1.f}, + {0.813, 1.f}, + {0.820, 1.f},//usual range + {0.826, 1.f}, + {0.833, 1.f}, + {0.840, 1.f}, + {0.847, 1.f}, + {0.855, 1.f}, + {0.862, 1.f}, + {0.870, 1.f}, + {0.877, 1.f}, + {0.885, 1.f}, + {0.893, 1.f}, + {0.901, 1.f}, + {0.909, 1.f}, + {0.917, 1.f}, + {0.926, 1.f}, + {0.935, 1.f}, + {0.943, 1.f},//49 limit low normal + {0.952, 1.f}, + {0.962, 1.f}, + {0.971, 1.f}, + {0.980, 1.f}, + {0.990, 1.f}, + {1.000, 1.f},//55 reference + {1.010, 1.f}, + {1.020, 1.f}, + {1.030, 1.f}, + {1.040, 1.f}, + {1.050, 1.f}, + {1.060, 1.f}, + {1.070, 1.f}, + {1.080, 1.f}, + {1.090, 1.f}, + {1.100, 1.f}, + {1.110, 1.f}, + {1.120, 1.f}, + {1.130, 1.f}, + {1.140, 1.f}, + {1.150, 1.f}, + {1.160, 1.f}, + {1.170, 1.f}, + {1.180, 1.f}, + {1.190, 1.f}, + {1.200, 1.f}, + {1.210, 1.f}, + {1.220, 1.f}, + {1.230, 1.f}, + {1.240, 1.f}, + {1.250, 1.f},// usual range + {1.275, 1.f}, + {1.300, 1.f}, + {1.325, 1.f}, + {1.350, 1.f}, + {1.375, 1.f}, + {1.400, 1.f},//usual 2 range + {1.425, 1.f}, + {1.450, 1.f}, + {1.475, 1.f}, + {1.500, 1.f}, + {1.525, 1.f}, + {1.550, 1.f}, + {1.575, 1.f},//extended range + {1.600, 1.f}, + {1.633, 1.f}, + {1.666, 1.f}, + {1.700, 1.f}, + {1.733, 1.f}, + {1.766, 1.f}, + {1.800, 1.f}, + {1.833, 1.f}, + {1.866, 1.f}, + {1.900, 1.f}, + {1.933, 1.f}, + {1.966, 1.f}, + {2.000, 1.f}, + {2.033, 1.f}, + {2.066, 1.f}, + {2.100, 1.f}, + {2.133, 1.f}, + {2.166, 1.f}, + {2.200, 1.f}, + {2.250, 1.f}, + {2.300, 1.f}, + {2.350, 1.f}, + {2.400, 1.f}, + {2.450, 1.f}, + {2.500, 1.f}, + {2.550, 1.f}, + {2.600, 1.f}, + {2.650, 1.f}, + {2.700, 1.f}, + {2.750, 1.f}, + {2.800, 1.f}, + {2.850, 1.f}, + {2.900, 1.f}, + {2.950, 1.f}, + {3.000, 1.f}, + {3.200, 1.f}, + {3.400, 1.f}, + {3.600, 1.f}, + {3.800, 1.f}, + {4.000, 1.f} + }; + const int N_g = sizeof(gree) / sizeof(gree[0]); //number of green + + typedef struct RangeGreen { + int begin; + int end; + } RangeGreen; + + int greenrefo = 55; + double origgreen = greenitc; + + for (int gg = 0; gg < N_g; gg++) { + if (gree[gg].green > origgreen) { + greenrefo = gg;//show the green + break; + } } + + constexpr RangeGreen Rangestandard = {33, 80};//usual green range + constexpr RangeGreen Rangestandard2 = {24, 86};//usual 2 green range + constexpr RangeGreen Rangeextended = {15, 93}; + const RangeGreen Rangemax = {0, N_g}; + + RangeGreen Rangegreenused; + + if (wbpar.itcwb_rgreen == 0) { + Rangegreenused = Rangestandard; + } else if (wbpar.itcwb_rgreen == 1) { + Rangegreenused = Rangestandard2; + } else if (wbpar.itcwb_rgreen == 2) { + Rangegreenused = Rangeextended; + } else { + Rangegreenused = Rangemax; + } + + + if (wbpar.itcwb_rgreen == 0) {//new way to set green + Rangegreenused.begin = std::max(greenrefo - 13, 0); + Rangegreenused.end = std::min(greenrefo + 13, N_g); + } + + if (wbpar.itcwb_rgreen == 1) {//new way to set green + Rangegreenused.begin = std::max(greenrefo - 17, 0); + Rangegreenused.end = std::min(greenrefo + 17, N_g); + } + + if (oldsampling == true) { + Rangegreenused = Rangestandard2; + } + + typedef struct WbTxyz { + double Tem; + double XX; + double ZZ; + } WbTxyz; + //we can change step to increase precision if need - also in Colortemp.cc with same changes + //I don't know how to pass this structure to Colortemp ! + // X and Z values calculate for each temp between 2000K to 15000K, so no result after 15000K ! + //of course we can change the step between each temp if need + + constexpr WbTxyz Txyz[191] = {//temperature Xwb Zwb 191 values x wb and y wb are calculated after, Xwb and Ywb calculated with a spreadsheet + {2001., 1.273842, 0.145295}, + {2051., 1.258802, 0.156066}, + {2101., 1.244008, 0.167533}, + {2151., 1.230570, 0.178778}, + {2201., 1.217338, 0.190697}, + {2251., 1.205305, 0.202338}, + {2301., 1.193444, 0.214632}, + {2351., 1.182648, 0.226598}, + {2401., 1.171996, 0.239195}, + {2451., 1.162290, 0.251421}, + {2501., 1.152883, 0.264539}, + {2551., 1.143965, 0.276682}, + {2605., 1.134667, 0.290722}, + {2655., 1.126659, 0.303556}, + {2705., 1.119049, 0.316446}, + {2755., 1.111814, 0.329381}, + {2790., 1.106961, 0.338455}, + {2803., 1.105381, 0.342193}, + {2825., 1.102275, 0.347542}, + {2856., 1.098258, 0.355599}, + {2880., 1.095233, 0.361840}, + {2910., 1.091550, 0.369645}, + {2930., 1.089155, 0.374849}, + {2960., 1.085649, 0.382655}, + {2980., 1.083369, 0.387858}, + {3003., 1.080982, 0.394258}, + {3025., 1.078397, 0.399561}, + {3050., 1.075727, 0.406057}, + {3075., 1.073122, 0.412550}, + {3103., 1.070277, 0.419815}, + {3128., 1.067801, 0.426296}, + {3153., 1.065384, 0.432769}, + {3175., 1.063305, 0.438459}, + {3203., 1.060906, 0.446161}, + {3225., 1.058738, 0.451367}, + {3250., 1.056535, 0.457806}, + {3280., 1.053960, 0.465519}, + {3303., 1.052034, 0.471422}, + {3353., 1.047990, 0.484218}, + {3400., 1.044547, 0.496719}, + {3450., 1.040667, 0.508891}, + {3500., 1.037145, 0.521523}, + {3550., 1.033783, 0.534090}, + {3600., 1.030574, 0.546590}, + {3650., 1.027510, 0.559020}, + {3699., 1.024834, 0.571722}, + {3801., 1.019072, 0.596102}, + {3851., 1.016527, 0.608221}, + {3902., 1.014244, 0.621136}, + {3952., 1.011729, 0.632447}, + {4002., 0.996153, 0.609518}, + {4052., 0.993720, 0.620805}, + {4102., 0.993908, 0.631520}, + {4152., 0.989179, 0.643262}, + {4202., 0.989283, 0.653999}, + {4252., 0.985039, 0.665536}, + {4302., 0.985067, 0.676288}, + {4352., 0.981271, 0.687599}, + {4402., 0.981228, 0.698349}, + {4452., 0.977843, 0.709425}, + {4502., 0.977736, 0.720159}, + {4552., 0.974728, 0.730993}, + {4602., 0.974562, 0.741698}, + {4652., 0.971899, 0.752284}, + {4702., 0.971681, 0.762949}, + {4752., 0.969335, 0.773285}, + {4802., 0.969069, 0.783899}, + {4827., 0.967570, 0.788836}, + {4852., 0.967011, 0.793982}, + {4877., 0.966465, 0.799108}, + {4902., 0.965933, 0.804214}, + {4914., 0.965682, 0.806658}, + {4927., 0.965414, 0.809229}, + {4940., 0.965149, 0.811937}, + {4952., 0.964908, 0.814366}, + {4965., 0.964650, 0.816993}, + {4977., 0.964415, 0.819412}, + {4990., 0.964163, 0.822028}, + {5002., 0.963934, 0.824438},//80 + {5015., 0.963689, 0.827044}, + {5027., 0.963465, 0.829444}, + {5040., 0.963226, 0.832039}, + {5051., 0.963008, 0.834429}, + {5065., 0.963226, 0.832039}, + {5077., 0.962563, 0.839395}, + {5090., 0.962336, 0.841968}, + {5102., 0.962129, 0.844339}, + {5115., 0.961907, 0.846902}, + {5127., 0.961706, 0.849263}, + {5140., 0.961490, 0.851815}, + {5151., 0.961294, 0.854166}, + {5177., 0.960893, 0.859049}, + {5202., 0.960501, 0.863911}, + {5253., 0.959749, 0.873572}, + {5302., 0.959313, 0.883815}, + {5351., 0.958361, 0.892644}, + {5402., 0.957903, 0.902793}, + {5452., 0.957116, 0.911379}, + {5502., 0.956639, 0.921431}, + {5553., 0.956002, 0.929779}, + {5602., 0.955509, 0.939728}, + {5652., 0.955008, 0.947842}, + {5702., 0.954502, 0.957685}, + {5752., 0.954124, 0.965569}, + {5802., 0.953608, 0.975303}, + {5852., 0.953342, 0.982963}, + {5902., 0.952818, 0.992584}, + {5952., 0.952652, 1.000025}, + {6002., 0.952122, 1.009532}, + {6052., 0.952047, 1.016759}, + {6102., 0.951514, 1.026149}, + {6152., 0.951520, 1.033168}, + {6202., 0.950985, 1.042439}, + {6252., 0.951064, 1.049256}, + {6302., 0.950530, 1.058406}, + {6352., 0.950674, 1.065027}, + {6380., 0.950576, 1.069386}, + {6402., 0.950143, 1.074055}, + {6425., 0.950428, 1.076341}, + {6452., 0.950345, 1.080484}, + {6475., 0.950277, 1.083996}, + {6502., 0.950201, 1.088097}, + {6525., 0.950139, 1.091573}, + {6552., 0.950070, 1.095633}, + {6575., 0.950014, 1.099075}, + {6602., 0.949952, 1.103094}, + {6625., 0.949902, 1.106501}, + {6652., 0.949846, 1.110479}, + {6675., 0.949801, 1.113852}, + {6702., 0.949752, 1.119138}, + {6725., 0.949712, 1.121128}, + {6752., 0.949668, 1.125027}, + {6802., 0.949596, 1.132190}, + {6852., 0.949533, 1.139281}, + {6902., 0.949033, 1.147691}, + {6952., 0.949437, 1.153246}, + {7002., 0.949402, 1.160129}, + {7052., 0.949376, 1.166966}, + {7102., 0.949358, 1.173732}, + {7152., 0.949348, 1.180429}, + {7202., 0.949346, 1.187058}, + {7252., 0.949350, 1.193619}, + {7301., 0.948896, 1.201432}, + {7352., 0.949380, 1.206541}, + {7402., 0.949405, 1.212904}, + {7451., 0.949434, 1.219076}, + {7501., 0.949471, 1.225312}, + {7551., 0.949512, 1.231485}, + {7601., 0.949099, 1.239061}, + {7675., 0.949638, 1.246525}, + {7751., 0.949729, 1.255559}, + {7825., 0.949828, 1.264225}, + {7901., 0.949498, 1.274460}, + {7952., 0.950018, 1.278800}, + {8025., 0.950137, 1.287013}, + {8095., 0.950259, 1.294777}, + {8151., 0.950361, 1.300912}, + {8225., 0.950501, 1.308915}, + {8301., 0.950253, 1.318464}, + {8375., 0.950804, 1.324786}, + {8451., 0.950966, 1.332651}, + {8525., 0.951129, 1.340199}, + {8601., 0.950941, 1.349261}, + {8701., 0.951533, 1.357724}, + {8801., 0.951772, 1.367421}, + {8901., 0.952018, 1.376935}, + {9001., 0.951969, 1.387639}, + {9201., 0.952784, 1.404422}, + {9401., 0.953081, 1.423213},//since 5 2023 I increased the number of temp references above 12000K + {9651., 0.953993, 1.442883}, + {9901., 0.954537, 1.464134}, + {10201., 0.955520, 1.485825}, + {10501., 0.956321, 1.508623}, + {10751., 0.957057, 1.524806}, + {11001., 0.957747, 1.541281}, + {11251., 0.958436, 1.557207}, + {11501., 0.959112, 1.572366}, + {11751., 0.959784, 1.587037}, + {12001., 0.960440, 1.601019},//since 5 2023 I increased the number of temp refrences above 12000K + {12251., 0.961090, 1.614566}, + {12501., 0.963963, 1.627492}, + {12751., 0.962350, 1.640031}, + {13001., 0.962962, 1.652055}, + {13251., 0.963561, 1.663638}, + {13501., 0.964147, 1.674804}, + {13751., 0.964720, 1.685571}, + {14001., 0.965279, 1.695919}, + {14251., 0.965827, 1.705950}, + {14501., 0.966363, 1.715637}, + {14751., 0.966886, 1.724998}, + {15001., 0.967397, 1.734047} + }; + //compatibility 5.9 + constexpr WbTxyz Txyzs[118] = {//temperature Xwb Zwb 118 values - same table as in Rawimagesource.cc x wb and y wb are calculated after + {2001., 1.273842, 0.145295}, + {2101., 1.244008, 0.167533}, + {2201., 1.217338, 0.190697}, + {2301., 1.193444, 0.214632}, + {2401., 1.171996, 0.239195}, + {2501., 1.152883, 0.264539}, + {2605., 1.134667, 0.290722}, + {2655., 1.126659, 0.303556}, + {2705., 1.119049, 0.316446}, + {2755., 1.111814, 0.329381}, + {2803., 1.105381, 0.342193}, + {2856., 1.098258, 0.355599}, + {2910., 1.091550, 0.369645}, + {2960., 1.085649, 0.382655}, + {3003., 1.080982, 0.394258}, + {3050., 1.075727, 0.406057}, + {3103., 1.070277, 0.419815}, + {3153., 1.065384, 0.432769}, + {3203., 1.060906, 0.446161}, + {3250., 1.056535, 0.457806}, + {3303., 1.052034, 0.471422}, + {3353., 1.047990, 0.484218}, + {3400., 1.044547, 0.496719}, + {3450., 1.040667, 0.508891}, + {3500., 1.037145, 0.521523}, + {3550., 1.033783, 0.534090}, + {3600., 1.030574, 0.546590}, + {3650., 1.027510, 0.559020}, + {3699., 1.024834, 0.571722}, + {3801., 1.019072, 0.596102}, + {3851., 1.016527, 0.608221}, + {3902., 1.014244, 0.621136}, + {3952., 1.011729, 0.632447}, + {4002., 0.996153, 0.609518}, + {4052., 0.993720, 0.620805}, + {4102., 0.993908, 0.631520}, + {4152., 0.989179, 0.643262}, + {4202., 0.989283, 0.653999}, + {4252., 0.985039, 0.665536}, + {4302., 0.985067, 0.676288}, + {4352., 0.981271, 0.687599}, + {4402., 0.981228, 0.698349}, + {4452., 0.977843, 0.709425}, + {4502., 0.977736, 0.720159}, + {4552., 0.974728, 0.730993}, + {4602., 0.974562, 0.741698}, + {4652., 0.971899, 0.752284}, + {4702., 0.971681, 0.762949}, + {4752., 0.969335, 0.773285}, + {4802., 0.969069, 0.783899}, + {4827., 0.967570, 0.788836}, + {4852., 0.967011, 0.793982}, + {4877., 0.966465, 0.799108}, + {4902., 0.965933, 0.804214}, + {4927., 0.965414, 0.809229}, + {4952., 0.964908, 0.814366}, + {4977., 0.964415, 0.819412}, + {5002., 0.963934, 0.824438}, + {5027., 0.963465, 0.829444}, + {5052., 0.963008, 0.834429}, + {5077., 0.962563, 0.839395}, + {5102., 0.962129, 0.844339}, + {5127., 0.961706, 0.849263}, + {5152., 0.961294, 0.854166}, + {5177., 0.960893, 0.859049}, + {5202., 0.960501, 0.863911}, + {5252., 0.959749, 0.873572}, + {5302., 0.959313, 0.883815}, + {5352., 0.958361, 0.892644}, + {5402., 0.957903, 0.902793}, + {5452., 0.957116, 0.911379}, + {5502., 0.956639, 0.921431}, + {5552., 0.956002, 0.929779}, + {5602., 0.955509, 0.939728}, + {5652., 0.955008, 0.947842}, + {5702., 0.954502, 0.957685}, + {5752., 0.954124, 0.965569}, + {5802., 0.953608, 0.975303}, + {5852., 0.953342, 0.982963}, + {5902., 0.952818, 0.992584}, + {5952., 0.952652, 1.000025}, + {6002., 0.952122, 1.009532}, + {6052., 0.952047, 1.016759}, + {6102., 0.951514, 1.026149}, + {6152., 0.951520, 1.033168}, + {6202., 0.950985, 1.042439}, + {6252., 0.951064, 1.049256}, + {6302., 0.950530, 1.058406}, + {6352., 0.950674, 1.065027}, + {6402., 0.950143, 1.074055}, + {6452., 0.950345, 1.080484}, + {6502., 0.950201, 1.088097}, + {6552., 0.950070, 1.095633}, + {6602., 0.949952, 1.103094}, + {6652., 0.949846, 1.110479}, + {6702., 0.949752, 1.119138}, + {6752., 0.949668, 1.125027}, + {6802., 0.949596, 1.132190}, + {6902., 0.949033, 1.147691}, + {7002., 0.949402, 1.160129}, + {7152., 0.949348, 1.180429}, + {7301., 0.948896, 1.201432}, + {7451., 0.949434, 1.219076}, + {7601., 0.949099, 1.239061}, + {7751., 0.949729, 1.255559}, + {7901., 0.949498, 1.274460}, + {8151., 0.950361, 1.300912}, + {8301., 0.950253, 1.318464}, + {8451., 0.950966, 1.332651}, + {8601., 0.950941, 1.349261}, + {8801., 0.951772, 1.367421}, + {9001., 0.951969, 1.387639}, + {9201., 0.952784, 1.404422}, + {9401., 0.953081, 1.423213}, + {9901., 0.954537, 1.464134}, + {10501., 0.956321, 1.508623}, + {11001., 0.957747, 1.541281}, + {12001., 0.960440, 1.601019} + }; + bool purp = true;//if inpaint-opposed or something else enable purp + + int N_t = sizeof(Txyz) / sizeof(Txyz[0]); //number of temperature White point + + if (oldsampling) { + N_t = sizeof(Txyzs) / sizeof(Txyzs[0]); //number of temperature White point + } + + // constexpr int Nc = 428 + 1; //429 number of reference spectral colors + int Ncr = 429; + + if (wbpar.itcwb_prim == "srgb") { + Ncr = 429; + } else if (wbpar.itcwb_prim == "adob") { + Ncr = 429; + } else if (wbpar.itcwb_prim == "XYZcam") { + Ncr = 429; + } else if (wbpar.itcwb_prim == "jdcmax") { + Ncr = 429; + } + + if (oldsampling) { //low sampling 5.9 with less spectral datas 201 + Ncr = 202; + } + + array2D Tx(N_t, Ncr); + array2D Ty(N_t, Ncr); + array2D Tz(N_t, Ncr); + array2D Ta(N_t, Ncr); + array2D Tb(N_t, Ncr); + array2D TL(N_t, Ncr); + + double TX[Ncr]; + double TY[Ncr]; + double TZ[Ncr]; + + std::vector good_spectral(Ncr, false); + std::vector good_size(Ncr, false); + + double WPX[N_t]; + double WPZ[N_t]; + + float rmm[N_t]; + float gmm[N_t]; + float bmm[N_t]; + + int siza = 237; //192 untill 01/2023 size of histogram + + if (oldsampling == true) { + siza = 192;//old sampling 5.9 and before... + } + + // tempref and greenref are camera wb values. + // I used them by default to select good spectral values !! but they are changed after + tempref = rtengine::min(tempref, 15000.0); + int repref = 0; + + for (int tt = 0; tt < N_t; tt++) { + if (Txyz[tt].Tem > tempref) { + repref = tt;//show the select temp + break; + } + } + + if (oldsampling) { + for (int tt = 0; tt < N_t; tt++) { + if (Txyzs[tt].Tem > tempref) { + repref = tt;//show the select temp + break; + } + } + } + + if (repref >= N_t - 1) { + repref = N_t - 2; + } + + //calculate R G B multiplier in function illuminant and temperature + const bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) + || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + greenitc += wbpar.itcwb_green; + double keepgreen = greenitc; + + for (int tt = 0; tt < N_t; ++tt) { + double r, g, b; + float rm, gm, bm; + + if (!oldsampling) { + ColorTemp(Txyz[tt].Tem, greenitc, 1., "Custom", wbpar.observer).getMultipliers(r, g, b); + } else { + ColorTemp(Txyzs[tt].Tem, greenitc, 1., "Custom", wbpar.observer).getMultipliers(r, g, b);//brings differences with old version 5.9, maybe Observer in 5.9, I did not find a solution + } + + rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; + gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; + bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; + + const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; + float new_scale_mul[4]; + const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); + rm = new_scale_mul[0] / scale_mul[0] * gain; + gm = new_scale_mul[1] / scale_mul[1] * gain; + bm = new_scale_mul[2] / scale_mul[2] * gain; + rmm[tt] = rm / gm; + gmm[tt] = 1.f; + bmm[tt] = bm / gm; + //return rmm, gmm, bmm in function of temp + } + + t2.set(); + + if (settings->verbose) { + printf("First: up calculate multipliers: %d nsec\n", t2.etime(t1)); + } + + struct hiss {//histogram + int histnum; + int index; + bool operator()(const hiss& lhis, const hiss& rhis) + { + return lhis.histnum < rhis.histnum; + } + + } ; + + //intermediate structure + struct chrom {//chroma image + float chroxy_number; + float number; + float hue; + float chroxy; + float chrox; + float chroy; + float Y; + int index; + int interest; + bool operator()(const chrom& lchro, const chrom& rchro) + { + return lchro.chroxy_number < rchro.chroxy_number; + } + + } ; + + struct Temppatch {//patch characterictics + float minchroma; + float delt_E; + float minhi; + float maxhi; + bool operator()(const Temppatch& ltp, const Temppatch& rtp) + { + return ltp.minchroma < rtp.minchroma; + } + }; + + Temppatch Tppat[N_t]; + + LUTu histxy(siza); //number of values for each pair xy + + histxy.clear(); + + LUTf xxx(siza);//for color references calculated ==> max in images "like histogram" + + xxx.clear(); + + LUTf yyy(siza); + + yyy.clear(); + + LUTf YYY(siza);//not used directly, but necessary to keep good range + + YYY.clear(); + + bool separated = true;//true + + int w = -1; + + array2D reff_spect_yy_camera(N_t, 2 * Ncr + 2); + + array2D reff_spect_xx_camera(N_t, 2 * Ncr + 2); + + array2D reff_spect_Y_camera(N_t, 2 * Ncr + 2); + + int ttbeg = 0; + + int ttend = N_t; + + //call tempxy to calculate for 406 or 201 color references Temp and XYZ with cat02 + double wpx = 0.; + + double wpz = 0.; + + ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar, ttbeg, ttend, wpx, wpz, WPX, WPZ); //calculate chroma xy (xyY) for Z known colors on under 200 illuminants + + //find the good spectral values + //calculate xy reference spectral for tempref + for (int j = 0; j < Ncr ; j++) { + float xxx = std::max(TX[j] / (TX[j] + TY[j] + TZ[j]), 0.01); // x from xyY + float yyy = std::max(TY[j] / (TX[j] + TY[j] + TZ[j]), 0.01); // y from xyY + float YY = TY[j]; + reff_spect_xx_camera[j][repref] = xxx; + reff_spect_yy_camera[j][repref] = yyy; + reff_spect_Y_camera[j][repref] = YY; + /* + //display spectral datas + float xr = reff_spect_xx_camera[j][repref]; + float yr = reff_spect_yy_camera[j][repref]; + float Yr = reff_spect_Y_camera[j][repref]; + float X_r = (65535.f * (xr * Yr)) / yr; + float Z_r = (65535.f * (1.f - xr - yr) * Yr) / yr; + float Y_r = 65535.f * Yr; + float Lr, ar, br; + Color::XYZ2Lab(X_r, Y_r, Z_r, Lr, ar, br);//it make sense, because known spectral color + + + printf("Nc=%i repref=%i xxx=%f yyy=%f YY=%f Lr=%f a=%f b=%f\n", j, repref, (double) xxx, (double) yyy, (double) YY, (double) Lr/327.68f, (double) ar/327.68f, (double) br/327.68f); + */ + } + + array2D xc(bfwitc, bfhitc); + array2D yc(bfwitc, bfhitc); + array2D zc(bfwitc, bfhitc); + array2D Yc(bfwitc, bfhitc); + + // int rep = rtengine::LIM(repref + 1, 0, N_t); + + //initialize calculation of xy current for tempref + if (oldsampling == false) { + + //small denoise with median 3x3 strong + float** tmL; + int wid = bfw; + int hei = bfh; + tmL = new float*[hei]; + + for (int i = 0; i < hei; ++i) { + tmL[i] = new float[wid]; + } + + typedef ImProcFunctions::Median Median; + Median medianTypeL = Median::TYPE_3X3_STRONG;//x2 + int pas = 2; + ImProcFunctions::Median_Denoise(redloc, redloc, bfw, bfh, medianTypeL, pas, false, tmL); + ImProcFunctions::Median_Denoise(greenloc, greenloc, bfw, bfh, medianTypeL, pas, false, tmL); + ImProcFunctions::Median_Denoise(blueloc, blueloc, bfw, bfh, medianTypeL, pas, false, tmL); + + for (int i = 0; i < hei; ++i) { + delete[] tmL[i]; + } + + delete[] tmL; + } + + t3.set(); + + if (settings->verbose) { + printf("Second: from first to up median 3x3: %d nsec\n", t3.etime(t2)); + } + + if (oldsampling == false) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int y = 0; y < bfh ; ++y) { + for (int x = 0; x < bfw ; ++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]; + + Color::rgbxyz(RR, GG, BB, xc[y][x], yc[y][x], zc[y][x], wb2);//use sRGB Adobe Rec2020 ACESp0 + float X_r = xc[y][x]; + float Y_r = yc[y][x]; + float Z_r = zc[y][x]; + + if (oldsampling == false) { + Color::gamutmap(X_r, Y_r, Z_r, wb2);//gamut control + } + + const float som = X_r + Y_r + Z_r; + xc[y][x] = X_r / som; + yc[y][x] = Y_r / som; + Yc[y][x] = Y_r / 65535.f; + } + } + + //histogram xy depend of temp...but in most cases D45 ..D65.. + // these values change with temp + //calculate for this image the mean values for each family of color, near histogram x y (number) + //xy vary from x 0..0.77 y 0..0.82 + //neutral values are near x=0.34 0.33 0.315 0.37 y =0.35 0.36 0.34 + //skin are about x 0.45 0.49 y 0.4 0.47 + //blue sky x=0.25 y=0.28 and x=0.29 y=0.32 + // step about 0.02 x 0.32 0.34 y= 0.34 0.36 skin -- sky x 0.24 0.30 y 0.28 0.32 + + + if (wbpar.itcwb_nopurple == true) {//since 21 april - change to filter magenta + purp = false; + } + + histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy, purp);//purp enable, enable purple color in WB + //return histogram x and y for each temp and in a range of 235 colors (siza) + + } else { + const int deltarepref = 1; + + for (int nn = 0, drep = -deltarepref; nn <= 2; ++nn, drep += deltarepref) { + //three loop to refine color if temp camera is probably not very good + const int rep = rtengine::LIM(repref + drep, 0, N_t); + + //initialize calculation of xy current for tempref +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int y = 0; y < bfh ; ++y) { + for (int x = 0; x < bfw ; ++x) { + const float RR = rmm[rep] * redloc[y][x]; + const float GG = gmm[rep] * greenloc[y][x]; + const float BB = bmm[rep] * blueloc[y][x]; + Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wb); + } + } + + + histoxyY_low(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy); + //return histogram x and y for each temp and in a range of 158 colors (siza) + } + + } + +//enable display cells + /* + printf ("xc\tyc\tcount\n") ; + printf ("--\t--\t-----\n") ; + for (int x1 = 0 ; x1 < 80; ++x1) { + for (int y1 = 0; y1 < 90; ++y1) { + if (cellxy[x1][y1] > 0) { + printf ("%d\t%d\t%d\n", x1, y1, cellxy[x1][y1]); + } + } + } + */ + + // free some memory + xc.free(); + yc.free(); + Yc.free(); + //calculate x y Y + const int sizcurrref = siza;//choice of number of correlate colors in image + array2D histcurrref(N_t, sizcurrref); + array2D xx_curref(N_t, sizcurrref); + array2D yy_curref(N_t, sizcurrref); + array2D YY_curref(N_t, sizcurrref); + array2D xx_curref_reduc(N_t, sizcurrref); + array2D yy_curref_reduc(N_t, sizcurrref); + array2D YY_curref_reduc(N_t, sizcurrref); + array2D nn_curref_reduc(N_t, sizcurrref);//new array to improve patch + array2D chronum_curref_reduc(N_t, sizcurrref);//new array to improve patch + array2D hue_curref_reduc(N_t, sizcurrref);//new array to improve patch + array2D chro_curref_reduc(N_t, sizcurrref);//new array to improve patch + array2D estim_hue(N_t, sizcurrref);//new array to improve patch + + hiss Wbhis[siza]; + + for (int nh = 0; nh < siza; nh++) { + Wbhis[nh].histnum = histxy[nh]; + Wbhis[nh].index = nh; + } + + //sort in ascending order + std::sort(Wbhis, Wbhis + siza, Wbhis[0]); + int n1 = 0; + int n4 = 0; + int n15 = 0; + int n30 = 0; + + //part to improve + //determined the number of colors who be used after + int ntot = 0; + + for (int nh = 0; nh < siza; nh++) { + if (Wbhis[nh].histnum > 0) { + ntot++; + } + } + + dread = ntot;//read colors + + for (int nh = 0; nh < siza; nh++) { + if (Wbhis[nh].histnum < 30) { + n30++; //keep only existing color but avoid to small + + if (Wbhis[nh].histnum < 15) { + n15++; //keep only existing color but avoid to small + + if (Wbhis[nh].histnum < 4) { + n4++; //keep only existing color but avoid to small + + if (Wbhis[nh].histnum < 1) { + n1++; //keep only existing color but avoid to small + } + } + } + } + } + + int ntr = n30; + + if (ntr > (siza - 25)) { + ntr = n15; //if to less elements 25 elements mini + } + + if (ntr > (siza - 23)) { + ntr = n4; //if to less elements 25 elements mini + } + + if (ntr > (siza - 20)) { + ntr = n1; //if to less elements 20 elements mini - normally never be used ! + } + + int sizcurr2ref = sizcurrref - ntr; + const int sizcu30 = sizcurrref - n30; + int maxsiz = 70; + maxsiz = LIM(maxsiz, 50, 80); + int nbm = maxsiz; + int sizcu4 = maxsiz; + + if (oldsampling == true) { + nbm = 55; + sizcu4 = rtengine::min(sizcu30, nbm);//size of chroma values + } + + Tppat[repref].maxhi = Wbhis[siza - 1].histnum; + Tppat[repref].minhi = Wbhis[siza - nbm].histnum; + + if (settings->verbose) { + printf("number total datas read=%i\n", ntot); + printf("Others datas - ntr=%i sizcurr2ref=%i sizcu4=%i sizcu30=%i\n", ntr, sizcurr2ref, sizcu4, sizcu30); + printf("Number max of data samples in last patch=%i\n", (int) Tppat[repref].maxhi); + printf("Number of data samples in beginning patch =%i\n", (int) Tppat[repref].minhi); + } + + chrom wbchro[sizcu4]; + float swpr = wpx + wpz + 1.f; + float xwpr = wpx / swpr;//white point for tt in xy coordinates + float ywpr = 1.f / swpr; + + if (oldsampling == true) { + swpr = Txyz[repref].XX + Txyz[repref].ZZ + 1.f; + xwpr = Txyz[repref].XX / swpr;//white point for tt in xy coordinates + ywpr = 1.f / swpr; + } + + if (settings->verbose) { + printf("White Point XYZ x=%f y=%f z=%f\n", wpx, 1., wpz); + printf("White Point xyY x=%f y=%f\n", xwpr, ywpr); + } + + float estimchrom = 0.f; + + if (oldsampling == true) { + for (int i = 0; i < sizcu4; ++i) { //take the max values + histcurrref[i][repref] = Wbhis[siza - (i + 1)].histnum; + xx_curref[i][repref] = xxx[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + yy_curref[i][repref] = yyy[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + YY_curref[i][repref] = YYY[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + } + if (settings->verbose) { + printf("Sizcu4=%i\n", sizcu4); + } + + //estimate chromaticity for references + for (int nh = 0; nh < sizcu4; ++nh) { + const float chxy = std::sqrt(SQR(xx_curref[nh][repref] - xwpr) + SQR(yy_curref[nh][repref] - ywpr)); + wbchro[nh].chroxy_number = chxy * std::sqrt(histcurrref[nh][repref]); + wbchro[nh].chroxy = std::sqrt(chxy); + wbchro[nh].chrox = xx_curref[nh][repref]; + wbchro[nh].chroy = yy_curref[nh][repref]; + wbchro[nh].Y = YY_curref[nh][repref]; + wbchro[nh].index = nh; + estimchrom += chxy; + } + + estimchrom /= sizcu4; + + if (settings->verbose) { + printf("estimchrom=%f\n", estimchrom); + } + + const int maxval = 34; + + sizcurr2ref = rtengine::min(sizcurr2ref, maxval); //keep about the biggest values, + + for (int i = 0; i < sizcurr2ref; ++i) { + //is condition chroxy necessary ? + if (wbchro[sizcu4 - (i + 1)].chrox > 0.1f && wbchro[sizcu4 - (i + 1)].chroy > 0.1f && wbchro[sizcu4 - (i + 1)].chroxy > 0.0f) { //suppress value too far from reference spectral + w++; + xx_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chrox; + yy_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroy; + YY_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].Y; + nn_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].number; + } + } + + //calculate deltaE xx to find best values of spectrals data - limited to chroma values + int maxnb = 3; + + + float dEmean = 0.f; + int ndEmean = 0; + float maxhist = -1000.f; + float minhist = 100000000.f; + + for (int nb = 1; nb <= maxnb; ++nb) { + for (int i = 0; i < w; ++i) { + float mindeltaE = 100000.f; + int kN = 0; + + for (int j = 0; j < Ncr ; j++) { + if (!good_spectral[j]) { + const float deltaE = SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[j][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[j][repref]); + + if (deltaE < mindeltaE) { + mindeltaE = deltaE; + kN = j; + } + } + } + + {//display in console for 5.9 + float spectlimit = settings->itcwb_deltaspec; + float dE = sqrt(SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[kN][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[kN][repref])); + dEmean += dE; + ndEmean++; + + if (nn_curref_reduc[i][repref] < minhist) { + minhist = nn_curref_reduc[i][repref]; + } + + if (nn_curref_reduc[i][repref] > maxhist) { + maxhist = nn_curref_reduc[i][repref]; + } + + if (settings->verbose) { + float xr = reff_spect_xx_camera[kN][repref]; + float yr = reff_spect_yy_camera[kN][repref]; + float Yr = reff_spect_Y_camera[kN][repref]; + float X_r = (65535.f * (xr * Yr)) / yr; + float Z_r = (65535.f * (1.f - xr - yr) * Yr) / yr; + float Y_r = 65535.f * Yr; + float Lr, ar, br; + Color::XYZ2Lab(X_r, Y_r, Z_r, Lr, ar, br);//it make sense, because known spectral color + + if (dE > spectlimit) { + printf("i=%i kn=%i REFLAB for info not used - not relevant Lr=%3.2f ar=%3.2f br=%3.2f \n", i, kN, (double)(Lr / 327.68f), (double)(ar / 327.68f), (double)(br / 327.68f)); + printf("IMAGE: kn=%i hist=%7.0f chro_num=%5.1f hue=%2.2f chro=%2.3f xx=%f yy=%f YY=%f\n", kN, (double) nn_curref_reduc[i][repref], (double) chronum_curref_reduc[i][repref], (double) hue_curref_reduc[i][repref], (double) chro_curref_reduc[i][repref], (double) xx_curref_reduc[i][repref], (double) yy_curref_reduc[i][repref], (double) YY_curref_reduc[i][repref]); + printf("kn=%i REfxy xxr=%f yyr=%f YYr=%f\n", kN, (double) reff_spect_xx_camera[kN][repref], (double) reff_spect_yy_camera[kN][repref], (double) reff_spect_Y_camera[kN][repref]); + printf("kn=%i DELTA delt=%f\n", kN, dE); + printf(".... \n"); + } + } + + } + + good_spectral[kN] = true;//good spectral are spectral color that match color histogram xy + } + } + } else { + + for (int i = 0; i < sizcu4; ++i) { //take the max values + histcurrref[i][repref] = Wbhis[siza - (i + 1)].histnum; + xx_curref[i][repref] = xxx[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + yy_curref[i][repref] = yyy[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + YY_curref[i][repref] = YYY[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + } + + int minsize = 20; + int maxsize = maxsiz; + bool isponderate = true; //to build patch ponderate + + bool isponder = true;//with true moving average + float powponder = settings->itcwb_powponder;//not used today... + powponder = LIM(powponder, 0.01f, 0.2f); + float estimchrom = 0.f; + + for (int j = minsize; j < maxsize; ++j) {//20 empirical minimal value default to ensure a correlation + if (!good_size[j]) { + float countchxynum = 0.f; + estimchrom = 0.f; + float xh = 0.f; + float yh = 0.f; + wbchro[j].hue = 0.f; + wbchro[j].chroxy_number = 0.f; + wbchro[j].number = 0.f; + wbchro[j].chroxy = 0.f; + wbchro[j].chrox = 0.f; + wbchro[j].chroy = 0.f; + wbchro[j].Y = 0.f; + wbchro[j].index = 0; + int ind1 = 1; + int ind2 = -1; + float chxy1 = 0.f; + float chxy2 = 0.f; + float chxynum1 = 0.f; + float chxynum2 = 0.f; + + for (int nh = 0; nh < j; ++nh) { + ind1++; + ind2++; + + if (ind1 < j && !isponderate) { + chxy1 = std::sqrt(SQR(xx_curref[ind1][repref] - xwpr) + SQR(yy_curref[ind1][repref] - ywpr)); + } + + if (ind2 <= 0 && !isponderate) { + chxy2 = std::sqrt(SQR(xx_curref[ind2][repref] - xwpr) + SQR(yy_curref[ind2][repref] - ywpr)); + } + + const float chxy = std::sqrt(SQR(xx_curref[nh][repref] - xwpr) + SQR(yy_curref[nh][repref] - ywpr)); + xh += xx_curref[nh][repref] - xwpr; + yh += yy_curref[nh][repref] - ywpr; + wbchro[nh].hue = fmodf(xatan2f(yy_curref[nh][repref] - ywpr, xx_curref[nh][repref] - xwpr), 2.f * RT_PI_F); + const float chxynum = wbchro[nh].chroxy_number = chxy * pow((double) histcurrref[nh][repref], 0.05);//sqrt was too big no convergence + + //We can replace 0.05 by powponder + if (ind1 < j && isponderate) { //with issorted ponderate chroma + chxynum1 = chxy1 * pow((double) histcurrref[ind1][repref], 0.05);//0.05 to 0.1 allows convergence, near 1.5 betwween max and min value + }//We can replace 0.05 by powponder + + if (ind2 < 0 && isponderate) { + chxynum2 = chxy2 * pow((double) histcurrref[ind2][repref], 0.05);//We can replace 0.05 by powponder + } + + wbchro[nh].number = histcurrref[nh][repref]; + wbchro[nh].chroxy = std::sqrt(chxy); + wbchro[nh].chrox = xx_curref[nh][repref]; + wbchro[nh].chroy = yy_curref[nh][repref]; + wbchro[nh].Y = YY_curref[nh][repref]; + wbchro[nh].index = nh; + + if (!isponderate) { + estimchrom += chxy; + + if (isponder && !isponderate) { + estimchrom += chxy1; + estimchrom += chxy2; + } + } + + if (isponderate) { + estimchrom += chxynum; + + if (isponder) { + estimchrom += chxynum1; + estimchrom += chxynum2; + } + + countchxynum += pow((double)histcurrref[nh][repref], 0.05);//no error, to take into account mean value //We can replace 0.05 by powponder + } + } + + estim_hue[j][repref] = xatan2f(yh, xh); + + if (isponder) { + estimchrom /= (j + 2 * (j - 1)); //extrem not taken + } else { + estimchrom /= j; + } + + if (estimchrom < minchrom) { + minchrom = estimchrom; + Tppat[repref].minchroma = minchrom; + kmin = j; + } + + Tppat[repref].minchroma = minchrom; + } + + good_size[kmin] = true; + } + + sizcu4 = kmin; + + int maxval = maxsiz; + sizcurr2ref = rtengine::min(sizcurr2ref, maxval); //keep about the biggest values, + int index1 = 0; + int index2 = sizcu4; + int indn = index1; + + + for (int i = index1; i < index2; ++i) { + if (wbchro[sizcu4 - (i + 1)].number < 400.f) { //remove too low numbers datas about an area 60*60 pixels or reparted + indn++; + } + } + + Tppat[repref].minhi = (float) rtengine::max((int) wbchro[sizcu4 - (indn + 1)].number, (int) Tppat[repref].minhi); + + if (settings->verbose) { + printf("Index1=%i index2=%i \n", indn, index2); + } + + if (settings->verbose) { + printf("Info2 - patch estimation of wp displacement (before):j=%i repref=%i real=%i Tppat=%f chrom=%f hue=%f\n", kmin, repref, index2 - indn, (double) Tppat[repref].minchroma, (double) minchrom, (double) estim_hue[kmin][repref]); + }; + + float limexclu = 0.96f;//to avoid highlight in some rare cases (sky...) + + + for (int i = indn; i < index2; ++i) { + //improvment to limit high Y values wbchro[sizcu4 - (i + 1)].Y < 0.96 0.96 arbitrary high value, maybe 0.9 or 0.98...or 1.0 + if (wbchro[sizcu4 - (i + 1)].chrox > limx && wbchro[sizcu4 - (i + 1)].chroy > limy && wbchro[sizcu4 - (i + 1)].Y < limexclu) { //remove value too far from reference spectral + w++;// w number of real tests + xx_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chrox; + yy_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroy; + YY_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].Y; + chronum_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroxy_number; + nn_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].number; + hue_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].hue; + chro_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroxy; + } + } + + if (settings->verbose) { + printf("Number of real tests=%i\n", w); + } + + int maxnb = 1; //since 8 april 2023 + + + float dEmean = 0.f; + int ndEmean = 0; + maxhist = -1000.f; + minhist = 100000000.f; + + for (int nb = 1; nb <= maxnb; ++nb) { //1 is good, but 2 3 or 4 help to find more spectral values + for (int i = 0; i < w; ++i) { + float mindeltaE = 100000.f; + int kN = 0; + + for (int j = 0; j < Ncr ; j++) { + if (!good_spectral[j]) { + const float deltaE = SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[j][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[j][repref]); + + if (deltaE < mindeltaE) { + mindeltaE = deltaE; + kN = j; + } + } + } + //display in console + float spectlimit = settings->itcwb_deltaspec; + float dE = sqrt(SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[kN][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[kN][repref])); + dEmean += dE; + ndEmean++; + + if (nn_curref_reduc[i][repref] < minhist) { + minhist = nn_curref_reduc[i][repref]; + } + + if (nn_curref_reduc[i][repref] > maxhist) { + maxhist = nn_curref_reduc[i][repref]; + } + + if (settings->verbose) { + float xr = reff_spect_xx_camera[kN][repref]; + float yr = reff_spect_yy_camera[kN][repref]; + float Yr = reff_spect_Y_camera[kN][repref]; + float X_r = (65535.f * (xr * Yr)) / yr; + float Z_r = (65535.f * (1.f - xr - yr) * Yr) / yr; + float Y_r = 65535.f * Yr; + float Lr, ar, br; + Color::XYZ2Lab(X_r, Y_r, Z_r, Lr, ar, br);//it make sense, because known spectral color + + if (dE > spectlimit) { + printf("i=%i kn=%i REFLAB for info not used - not relevant Lr=%3.2f ar=%3.2f br=%3.2f \n", i, kN, (double)(Lr / 327.68f), (double)(ar / 327.68f), (double)(br / 327.68f)); + printf("IMAGE: kn=%i hist=%7.0f chro_num=%5.1f hue=%2.2f chro=%2.3f xx=%f yy=%f YY=%f\n", kN, (double) nn_curref_reduc[i][repref], (double) chronum_curref_reduc[i][repref], (double) hue_curref_reduc[i][repref], (double) chro_curref_reduc[i][repref], (double) xx_curref_reduc[i][repref], (double) yy_curref_reduc[i][repref], (double) YY_curref_reduc[i][repref]); + printf("kn=%i REfxy xxr=%f yyr=%f YYr=%f\n", kN, (double) reff_spect_xx_camera[kN][repref], (double) reff_spect_yy_camera[kN][repref], (double) reff_spect_Y_camera[kN][repref]); + printf("kn=%i DELTA delt=%f\n", kN, dE); + printf(".... \n"); + } + } + + + good_spectral[kN] = true;//good spectral are spectral color that match color histogram xy + } + + if (ndEmean == 0) { + ndEmean = 2; + } + + Tppat[repref].delt_E = dEmean / ndEmean; + delta = Tppat[repref].delt_E; + Tppat[repref].maxhi = maxhist; + Tppat[repref].minhi = minhist; + + if (settings->verbose && !oldsampling) { + printf("Patch Mean - Repref=%i deltaE=%f minhisto=%6.0f maxhisto=%7.0f \n", repref, (double) dEmean / ndEmean, (double) minhist, (double) maxhist); + } + } + } + + // reuse some buffers + array2D& R_curref_reduc = xx_curref_reduc; + array2D& G_curref_reduc = yy_curref_reduc; + array2D& B_curref_reduc = YY_curref_reduc; + + //reconvert to RGB for "reduction" + for (int i = 0; i < w; i++) { + const float X = 65535.f * xx_curref_reduc[i][repref] * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; + const float Y = 65535.f * YY_curref_reduc[i][repref]; + const float Z = 65535.f * (1.f - xx_curref_reduc[i][repref] - yy_curref_reduc[i][repref]) * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; + float r, g, b; + Color::xyz2rgb(X, Y, Z, r, g, b, iwb); + R_curref_reduc[i][repref] = r / rmm[repref]; + G_curref_reduc[i][repref] = g / gmm[repref]; + B_curref_reduc[i][repref] = b / bmm[repref]; + } + + t4.set(); + + if (settings->verbose) { + printf("Third: from second to find patch: %d nsec\n", t4.etime(t3)); + } + + +//end first part + + //Now begin real calculations + separated = false; + ttbeg = 0; + ttend = N_t; + + ttbeg = std::max(repref - 11, 0);//enough in all cases > dgoodref + ttend = std::min(repref + 11, N_t); + + if (oldsampling == true) { + ttbeg = 0; + ttend = N_t; + } + + //recalculate histogram with good values and not estimated + double wpx1 = 0.; + double wpz1 = 0.; + + ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar, ttbeg, ttend, wpx1, wpz1, WPX, WPZ); //calculate chroma xy (xyY) for Z known colors on under 90 illuminants + //calculate x y Y + int sizcurr = siza;//choice of number of correlate colors in image + array2D xxyycurr_reduc(N_t, 2 * sizcurr); + array2D reff_spect_xxyy(N_t, 2 * Ncr + 2); + array2D reff_spect_xxyy_prov(N_t, 2 * Ncr + 2); + t5.set(); + + if (settings->verbose) { + printf("Fourth: from third recalculate spectral: %d nsec\n", t5.etime(t4)); + } + + float minstud = 100000.f; + int goodref = 1; + +//calculate x y z for each pixel with multiplier rmm gmm bmm + + for (int tt = ttbeg; tt < ttend; ++tt) {//N_t + for (int i = 0; i < w; ++i) { + float unused; + + const float RR = rmm[tt] * R_curref_reduc[i][repref]; + const float GG = gmm[tt] * G_curref_reduc[i][repref]; + const float BB = bmm[tt] * B_curref_reduc[i][repref]; + Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wb); + } + + for (int j = 0; j < Ncr ; ++j) { + reff_spect_xxyy_prov[2 * j][tt] = std::max(Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]), 0.01f); // x from xyY + reff_spect_xxyy_prov[2 * j + 1][tt] = std::max(Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]), 0.01f); // y from xyY + } + + int kk = -1; + + for (int i = 0; i < Ncr ; ++i) { + if (good_spectral[i]) { + kk++; + //we calculate now absolute chroma for each spectral color + reff_spect_xxyy[2 * kk][tt] = reff_spect_xxyy_prov[2 * i][tt]; + reff_spect_xxyy[2 * kk + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; + } + } + + const float abstud = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * (kk + 1), tt)); + + if (abstud < minstud) { // find the minimum Student + minstud = abstud; + goodref = tt; + } + } + + t6.set(); + + if (settings->verbose) { + printf("Fifth: from fourth to find first correlation: %d nsec\n", t6.etime(t5)); + } + + { + //always used if extra = true because I made this choice, brings better results + struct Tempgreen { + float student; + int tempref; + int greenref; + bool operator()(const Tempgreen& ltg, const Tempgreen& rtg) + { + return ltg.student < rtg.student; + } + }; + Tempgreen Tgstud[N_g]; + + for (int i = 0; i < N_g; ++i) {//init variables with + Tgstud[i].student = 1000.f;//max value to initialize + + if (!oldsampling) { + Tgstud[i].tempref = 80;//5002K position in the list + } else { + Tgstud[i].tempref = 57;//5002K position in the list + } + + Tgstud[i].greenref = 55;// 1.f position in the list + } + + int newdelta = 1.8f * 4; // wbpar.itcwb_delta - default = 4; + int dgoodref = rtengine::LIM(newdelta, 1, 10); // 1.8 increase delta temp scan + + if (oldsampling == true) { + dgoodref = 2; + } + + const int scantempbeg = rtengine::max(goodref - (dgoodref + 1), 1); + const int scantempend = rtengine::min(goodref + dgoodref, N_t - 1); + int goodrefgr = 1; + + for (int gr = Rangegreenused.begin; gr < Rangegreenused.end; ++gr) { + float minstudgr = 100000.f; + goodrefgr = 1; + + for (int tt = scantempbeg; tt < scantempend; ++tt) { + double r, g, b; + + if (!oldsampling) { + ColorTemp(Txyz[tt].Tem, gree[gr].green, 1., "Custom", wbpar.observer).getMultipliers(r, g, b); + } else { + ColorTemp(Txyzs[tt].Tem, gree[gr].green, 1., "Custom", wbpar.observer).getMultipliers(r, g, b); + } + + float rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; + float gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; + float bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; + //recalculate Multipliers now with good range of temp and green + + const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; + float new_scale_mul[4]; + const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); + + rm = new_scale_mul[0] / scale_mul[0] * gain; + gm = new_scale_mul[1] / scale_mul[1] * gain; + bm = new_scale_mul[2] / scale_mul[2] * gain; + rmm[tt] = rm / gm; + gmm[tt] = 1.f; + bmm[tt] = bm / gm; + } + + + for (int tt = scantempbeg; tt < scantempend; ++tt) {//N_t + for (int i = 0; i < w; ++i) { + float unused; + + const float RR = rmm[tt] * R_curref_reduc[i][repref]; + const float GG = gmm[tt] * G_curref_reduc[i][repref]; + const float BB = bmm[tt] * B_curref_reduc[i][repref]; + Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wb); + } + + //recalculate xy spectral now with good range of temp and green + + for (int j = 0; j < Ncr ; ++j) { + reff_spect_xxyy_prov[2 * j][tt] = std::max(Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]), 0.01f); // x from xyY + reff_spect_xxyy_prov[2 * j + 1][tt] = std::max(Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]), 0.01f); // y from xyY + } + + int kkg = -1; + + for (int i = 0; i < Ncr ; ++i) { + if (good_spectral[i]) { + kkg++; + reff_spect_xxyy[2 * kkg][tt] = reff_spect_xxyy_prov[2 * i][tt]; + reff_spect_xxyy[2 * kkg + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; + } + } + + //now we have good spectral data + //calculate student correlation + const float abstudgr = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * (kkg + 1), tt)); + + if (abstudgr < minstudgr) { // find the minimum Student + minstudgr = abstudgr; + goodrefgr = tt; + } + + //found the values + Tgstud[gr].tempref = goodrefgr; + Tgstud[gr].greenref = gr; + Tgstud[gr].student = minstudgr; + + } + } + + t7.set(); + + if (settings->verbose) { + printf("Sixth: from fifth to find patch in extra mode: %d nsec\n", t7.etime(t6)); + } + + float estimchromf = 0.f; + float estimhuef = 0.f; + float xhf = 0.f; + float yhf = 0.f; + + const float swprf = WPX[goodrefgr] + WPZ[goodrefgr] + 1.f; + const float xwprf = WPX[goodrefgr] / swpr;//white point for tt in xy coordinates + + const float ywprf = 1.f / swprf; + + for (int nh = 0; nh < w; ++nh) { + const float chxy = std::sqrt(SQR(xxyycurr_reduc[2 * nh][goodrefgr] - xwprf) + SQR(xxyycurr_reduc[2 * nh + 1][goodrefgr] - ywprf)); + xhf += xxyycurr_reduc[2 * nh][goodrefgr] - xwprf; + yhf += xxyycurr_reduc[2 * nh + 1][goodrefgr] - ywprf; + estimchromf += chxy; + } + + estimhuef = xatan2f(yhf, xhf); + estimchromf /= w; + + if (settings->verbose) { + printf("New white point calculated patch for information : xwprf=%f ywprf=%f\n", (double) xwprf, (double) ywprf); + printf("Info - patch estimation of white-point displacement: chrom=%f hue=%f\n", (double) estimchromf, (double) estimhuef); + } + + + std::sort(Tgstud, Tgstud + N_g, Tgstud[0]); + + if (!oldsampling) { + + // now search the value of green the nearest of 1 with a good student value, I think it is a good choice, perhaps no... + // I take the first values + // I admit a symetrie in green coefiicient for rgb multiplier...probably not exactly true + // perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% + int greengood = 55; + + int maxkgood = 3;//default 3 - we can change ...to test 2, 4, 5, 6. High values perhaps less good student, but it is a compromise... + maxkgood = rtengine::LIM(maxkgood, 1, 6);// 2 6 + + if (oldsampling == true) { + maxkgood = 3; // force to 3 with old low sampling + } + + int mingood = std::min(std::fabs(Tgstud[0].greenref - 55), std::fabs(Tgstud[1].greenref - 55)); + + for (int k = 0; k < maxkgood; ++k) { + mingood = std::min(std::fabs(mingood), std::fabs(Tgstud[k].greenref - 55)); + } + + for (int k = 0; k < maxkgood ; ++k) { + if (mingood == fabs(Tgstud[k].greenref - 55)) { + greengood = Tgstud[k].greenref ; + goodref = Tgstud[k].tempref; + studgood = Tgstud[k].student; + } + } + + if (settings->verbose) { + printf("Green comparison=%f\n", keepgreen); + printf("Rangegreen begin=%i Rangegreen end=%i\n", Rangegreenused.begin, Rangegreenused.end); + printf("scantemp begin=%i scantemp end=%i\n", scantempbeg, scantempend); + printf("Student_0=%f Student_k= %f\n", Tgstud[0].student, Tgstud[maxkgood - 1].student); + printf("mingood=%i greeng=%i goodref=%i stud=%f\n", mingood, greengood, goodref, (double) studgood); + } + + tempitc = Txyz[goodref].Tem; + + greenitc = gree[greengood].green; + + int greencam = 55; + + for (int gg = 0; gg < N_g; gg++) { + if (gree[gg].green > keepgreen) { + greencam = gg;//show the green + break; + } + } + + bool greenex = false; + + if ((keepgreen > 0.92 && keepgreen < 1.23)) { + if (abs(greengood - greencam) > 5) { + double ag = 0.; + double gcal = gree[greengood].green; + ag = 0.89 * (gcal - keepgreen); + greenitc = gcal - ag; + greenex = true; + + if (settings->verbose) { + printf("green correction_1=%f \n", ag); + } + } else { + double ag = 0.; + double gcal = gree[greengood].green; + + if (keepgreen > 1.09) { + ag = 0.10 * (gcal - keepgreen) * abs(greengood - greencam); + } else { + ag = 0.16 * (gcal - keepgreen) * abs(greengood - greencam); + } + + greenitc = gcal - ag; + greenex = true; + + if (settings->verbose) { + printf("green correction_0=%f \n", ag); + } + + } + } + + if (((keepgreen >= 0.952 && keepgreen < 1.25) && greengood > 55) && !greenex) { + double ag = 0.; + double gcal = gree[greengood].green;//empirical correction when green suspicious + ag = 0.96 * (gcal - keepgreen); + greenitc = gcal - ag; + greenex = true; + + if (settings->verbose) { + printf("green correction_2=%f \n", ag); + } + } + + if (((greengood > 41 && keepgreen < 0.7) || (greengood > 46 && keepgreen < 0.952)) && !greenex) { + double ag = 0.; + double gcal = gree[greengood].green; + ag = 0.95 * (gcal - keepgreen);//empirical correction when green low - to improve + + if (purp == false) { + ag -= 0.12; + } + + if (settings->verbose) { + printf("green correction_3=%f \n", ag); + } + + greenitc = gcal - ag; + } + } else {//oldsampling + int greengood; + int greengoodprov; + int goodrefprov; + float studprov; + const int goodref0 = Tgstud[0].tempref; + const int greengood0 = Tgstud[0].greenref - 55;//55 green = 1 + const float stud0 = Tgstud[0].student; + const int goodref1 = Tgstud[1].tempref; + const float stud1 = Tgstud[1].student; + const int greengood1 = Tgstud[1].greenref - 55; + const int goodref2 = Tgstud[2].tempref; + const int greengood2 = Tgstud[2].greenref - 55; + const float stud2 = Tgstud[2].student; + + if (std::fabs(greengood2) < std::fabs(greengood1)) { + greengoodprov = greengood2; + goodrefprov = goodref2; + studprov = stud2; + } else { + greengoodprov = greengood1; + goodrefprov = goodref1; + studprov = stud1; + + } + + if (std::fabs(greengoodprov) < std::fabs(greengood0)) { + goodref = goodrefprov; + greengood = greengoodprov + 55; + studgood = studprov; + + } else { + goodref = goodref0; + greengood = greengood0 + 55; + studgood = stud0; + } + + tempitc = Txyz[goodref].Tem; + greenitc = gree[greengood].green; + + if (estimchrom < 0.025f) { + float ac = -2.40f * estimchrom + 0.06f;//small empirical correction, maximum 0.06 if chroma=0 for all image, currently for very low chroma +0.02 + greenitc += ac; + } + + itciterate = false; + + } + } + + avg_rm = 10000.f * rmm[goodref]; + avg_gm = 10000.f * gmm[goodref]; + avg_bm = 10000.f * bmm[goodref]; + + //now we have temp green and student + if (!oldsampling) { + if (lastitc && nocam == 0 && wbpar.itcwb_alg == false) { //try to find if another tempref + if ((tempitc < 4000.f || tempitc > 6000.f) || extra == true) { + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + + nbitc++; + + if (tempitc < 4000.f) {//change the second temp to be near of the first one + if (tempitc < 2800.f && kcam == 1) { + tempitc += 151.f; + } else if (tempitc >= 2800.f && kcam == 1) { + tempitc -= 149.f; + } else { + tempitc += 201.f; + } + } else { + if (tempitc < 8000.f) { + tempitc = 4197.f + 0.1255f * tempitc; + } else { + tempitc = 5200.f * (1.f * (tempitc / 8000.f)); + } + } + + tempref = tempitc * (1. + wbpar.tempBias); + + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + lastitc = false; + + } else if ((tempitc >= 4000.f && tempitc <= 6000.f) || extra == true) { + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + + nbitc++; + + if (tempitc < 5000.f) {//change the second temp to be near of the first one + tempitc += 105.f; + } else { + tempitc -= 105.f; + } + + tempref = tempitc * (1. + wbpar.tempBias); + + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + lastitc = false; + + } + } else if (nocam > 0 && wbpar.itcwb_alg == false) { + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + + nbitc++; + + if (nocam == 1) { //new tempitc empirical values to refine + tempitc -= 199.f; + } else if (nocam == 2) { + tempitc += 201.f; + } else if (nocam == 3) { + tempitc -= 199.f; + } else if (nocam == 4) { + tempitc += 201.f; + } else if (nocam == 5) { + tempitc += 299.f; + } else if (nocam == 6) { + tempitc += 201.f; + } else if (nocam == 7) { + tempitc += 299.f; + } else if (nocam == 8) { + tempitc += 500.f; + } else if (nocam == 9) { + tempitc += 199.f; + } else if (nocam == 10) { + tempitc += 199.f; + } + + nocam = 0; + tempref = tempitc * (1. + wbpar.tempBias); + + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + lastitc = false; + } else { + optitc[nbitc].stud = studgood; + optitc[nbitc].minc = Tppat[repref].minchroma; + optitc[nbitc].titc = tempitc; + optitc[nbitc].gritc = greenitc; + optitc[nbitc].tempre = tempref; + optitc[nbitc].greenre = greenref; + optitc[nbitc].drea = dread; + optitc[nbitc].kmi = kmin; + optitc[nbitc].minhis = Tppat[repref].minhi; + optitc[nbitc].maxhis = Tppat[repref].maxhi; + optitc[nbitc].avg_r = avg_rm; + optitc[nbitc].avg_g = avg_gm; + optitc[nbitc].avg_b = avg_bm; + optitc[nbitc].delt = Tppat[repref].delt_E; + + lastitc = false; + itciterate = false; + } + + + if (optitc[1].minc > 0.f) { + choiceitc = 1; + temp0 = optitc[0].titc; + } else { + choiceitc = 0; + temp0 = 0.f; + } + }//end loop + + if (!oldsampling) { + + if (settings->verbose) { + for (int d = 0; d < 2; d++) { + printf("n=%i nbitc=%i stu=%f minc=%f tempitc=%f greenitc=%f deltaE=%f choiceitc=%i\n", d, nbitc, (double) optitc[d].stud, (double) optitc[d].minc, (double) optitc[d].titc, (double) optitc[d].gritc, (double) optitc[d].delt, choiceitc); + } + } + + if ((nbitc == 1 && choiceitc == 1) && wbpar.itcwb_alg == false && oldsampling == false) { + bia = 2; + + if ((std::max(optitc[1].stud, 0.0004f) * optitc[1].delt < std::max(optitc[0].stud, 0.0004f) * optitc[0].delt) && wbpar.itcwb_alg == false) { + bia = 3; + } else { + bia = 2; + } + + studgood = optitc[choiceitc].stud; + minchrom = optitc[choiceitc].minc; + tempitc = optitc[choiceitc].titc; + greenitc = optitc[choiceitc].gritc; + tempref = optitc[choiceitc].tempre; + greenref = optitc[choiceitc].greenre; + dread = optitc[choiceitc].drea; + kmin = optitc[choiceitc].kmi; + minhist = optitc[choiceitc].minhis; + maxhist = optitc[choiceitc].maxhis; + avg_rm = optitc[choiceitc].avg_r; + avg_gm = optitc[choiceitc].avg_g; + avg_bm = optitc[choiceitc].avg_b; + } else if (!oldsampling) { + studgood = optitc[0].stud; + minchrom = optitc[0].minc; + tempitc = optitc[0].titc; + greenitc = optitc[0].gritc; + tempref = optitc[0].tempre; + greenref = optitc[0].greenre; + dread = optitc[0].drea; + kmin = optitc[0].kmi; + minhist = optitc[0].minhis; + maxhist = optitc[0].maxhis; + avg_rm = optitc[0].avg_r; + avg_gm = optitc[0].avg_g; + avg_bm = optitc[0].avg_b; + } + } } - avg_rm = 10000.f * rmm[goodref]; - avg_gm = 10000.f * gmm[goodref]; - avg_bm = 10000.f * bmm[goodref]; + t8.set(); - if (!extra) { - tempitc = Txyz[goodref].Tem; - } - - //now we have temp green and student if (settings->verbose) { - printf("ITCWB tempitc=%f gritc=%f stud=%f \n", tempitc, greenitc, studgood); + printf("Seventh: from sixth to end: %d nsec\n", t8.etime(t7)); } + } -void RawImageSource::WBauto(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 & studgood, bool & twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams & cmp, const RAWParams & raw, const ToneCurveParams &hrp) +void RawImageSource::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 WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams & cmp, const RAWParams & raw, const ToneCurveParams &hrp) { // BENCHFUN //auto white balance //put green (tint) in reasonable limits for an Daylight illuminant // avoid too bi or too low values if (wbpar.method == "autitcgreen") { - bool extra = true; + // bool extra = true; if (greenref > 0.5 && greenref < 1.3) {// 0.5 and 1.3 arbitraties values greenitc = greenref; } else { greenitc = 1.; - extra = true; + // extra = true; } tempitc = 5000.; - ItcWB(extra, tempref, greenref, tempitc, greenitc, studgood, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, cmp, raw, wbpar, hrp); + ItcWB(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, cmp, raw, wbpar, hrp); } } @@ -6092,7 +7393,9 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int //used by auto WB local to calculate red, green, blue in local region int precision = 3;//must be 3 5 or 9 - if(wbpar.itcwb_sampling == true) { + bool oldsampling = wbpar.itcwb_sampling; + + if (oldsampling == true) { precision = 5; } @@ -6163,7 +7466,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int } } -void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref, double & tempitc, double & greenitc, float &studgood, 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) +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) { // BENCHFUN constexpr double clipHigh = 64000.0; @@ -6356,21 +7659,24 @@ void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref if (wbpar.method == "autitcgreen") { bool twotimes = false; int precision = 3;//must be 3 5 or 9 - if(wbpar.itcwb_sampling == true) { + bool oldsampling = wbpar.itcwb_sampling; + + if (oldsampling == true) { precision = 5; } + // bool extra = true; 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); - WBauto(tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, studgood, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw, hrp); + 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) { - printf("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); + 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)); } if (wbpar.method == "autitcgreen") { @@ -6605,7 +7911,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) blueAWBMul = bm = imatrices.rgb_cam[2][0] * reds + imatrices.rgb_cam[2][1] * greens + imatrices.rgb_cam[2][2] * blues; } -ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) +ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) { int x; @@ -6618,7 +7924,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &red, std::vector 52500 || + if (initialGain * (rawData[yr][3 * xr]) > 52500 || initialGain * (rawData[yg][3 * xg + 1]) > 52500 || initialGain * (rawData[yb][3 * xb + 2]) > 52500) { continue; @@ -6677,7 +7983,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector= 0 && ymin >= 0 && xmax < W && ymax < H) { - reds += (rawData[yr][3 * xr] ); + reds += (rawData[yr][3 * xr]); greens += (rawData[yg][3 * xg + 1]); blues += (rawData[yb][3 * xb + 2]); rn++; @@ -6690,7 +7996,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &red, std::vector &red, std::vector &red, std::vector &red, std::vectorget_rotateDegree(); rotate %= 360; + if (rotate == 90) { - std::swap(xnew,ynew); + std::swap(xnew, ynew); ynew = H - 1 - ynew; } else if (rotate == 180) { xnew = W - 1 - xnew; ynew = H - 1 - ynew; } else if (rotate == 270) { - std::swap(xnew,ynew); + std::swap(xnew, ynew); xnew = W - 1 - xnew; } xnew = LIM(xnew, 0, W - 1); ynew = LIM(ynew, 0, H - 1); - int c = ri->getSensorType() == ST_FUJI_XTRANS ? ri->XTRANSFC(ynew,xnew) : ri->FC(ynew,xnew); + int c = ri->getSensorType() == ST_FUJI_XTRANS ? ri->XTRANSFC(ynew, xnew) : ri->FC(ynew, xnew); int val = round(rawData[ynew][xnew] / scale_mul[c]); + if (c == 0) { - R = val; G = 0; B = 0; + R = val; + G = 0; + B = 0; } else if (c == 2) { - R = 0; G = 0; B = val; + R = 0; + G = 0; + B = val; } else { - R = 0; G = val; B = 0; + R = 0; + G = val; + B = 0; } } -bool RawImageSource::isGainMapSupported() const { +bool RawImageSource::isGainMapSupported() const +{ return ri->isGainMapSupported(); } -void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) { +void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) +{ // now we can apply each gain map to raw_data array2D mvals[2][2]; + for (auto &m : gainMaps) { mvals[m.Top & 1][m.Left & 1](m.MapPointsH, m.MapPointsV, m.MapGain.data()); } // now we assume, col_scale and row scale is the same for all maps - const float col_scale = float(gainMaps[0].MapPointsH-1) / float(W); - const float row_scale = float(gainMaps[0].MapPointsV-1) / float(H); + const float col_scale = float(gainMaps[0].MapPointsH - 1) / float(W); + const float row_scale = float(gainMaps[0].MapPointsV - 1) / float(H); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif + for (std::size_t y = 0; y < static_cast(H); ++y) { - const float rowBlack[2] = {black[FC(y,0)], black[FC(y,1)]}; + const float rowBlack[2] = {black[FC(y, 0)], black[FC(y, 1)]}; const float ys = y * row_scale; float xs = 0.f; + for (std::size_t x = 0; x < static_cast(W); ++x, xs += col_scale) { const float f = getBilinearValue(mvals[y & 1][x & 1], xs, ys); const float b = rowBlack[x & 1]; @@ -7008,7 +8328,7 @@ void RawImageSource::applyDngGainMap(const float black[4], const std::vector &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar, const procparams::ToneCurveParams &hrp); + void ItcWB(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, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar, const procparams::ToneCurveParams &hrp); unsigned FC(int row, int col) const; inline void getRowStartEnd (int x, int &start, int &end); @@ -141,8 +141,8 @@ public: void processFlatField(const procparams::RAWParams &raw, const 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(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 &studgood, 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; - void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; + 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; + 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) 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 getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const override; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 1d7994ace..7ca38f68c 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -484,7 +484,7 @@ class AutoWBListener { public: virtual ~AutoWBListener() = default; - virtual void WBChanged(double temp, double green, double rw, double gw, double bw, float studgood) = 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) = 0; }; class FrameCountListener diff --git a/rtengine/settings.h b/rtengine/settings.h index c920a355d..04f056074 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -8,7 +8,7 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * RawTherapee is distributed in the hope that it will be useful, -itcw * + * * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. @@ -60,6 +60,7 @@ public: Glib::ustring srgb; // filename of sRGB profile (default to the bundled one) Glib::ustring rec2020; // filename of Rec2020 profile (default to the bundled one) Glib::ustring ACESp0; // filename of ACES P0 profile (default to the bundled one) + Glib::ustring JDCmax; // filename of JDCmax profile (default to the bundled one) Glib::ustring ACESp1; // filename of ACES P1 profile (default to the bundled one) Glib::ustring DCIP3; // filename of DCIP3 profile (default to the bundled one) @@ -95,6 +96,9 @@ public: double cbdlsensi; // bool showtooltip; bool itcwb_enable; + double itcwb_deltaspec; + double itcwb_powponder; + //wavelet levels double edghi; double edglo; diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 411b1de32..2375d7cfd 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -311,11 +311,11 @@ void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) } } -void StdImageSource::WBauto(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 &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp) +void StdImageSource::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 WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp) { } -void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) +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.) { rm = redAWBMul; @@ -324,7 +324,7 @@ void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, return; } - img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); + img->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); redAWBMul = rm; greenAWBMul = gm; diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 33a5a3667..866e90b99 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -66,8 +66,8 @@ public: } void getAutoWBMultipliers (double &rm, double &gm, double &bm) override; ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) override; - void WBauto(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 &studgood, 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; - void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, 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) override; + 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; + 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) override; eSensorType getSensorType() const override {return ST_NONE;} bool isMono() const override {return false;} diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 57f12fd7e..5606452e3 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -204,10 +204,13 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu wFrame->add(*wProfVBox); //-----------------gamma TRC working - Gtk::Frame *trcFrame = Gtk::manage(new Gtk::Frame(M("TP_ICM_TRCFRAME"))); - trcFrame->set_label_align(0.025, 0.5); +// Gtk::Frame *trcFrame = Gtk::manage(new Gtk::Frame(M("TP_ICM_TRCFRAME"))); + trcExp = Gtk::manage(new MyExpander(false, 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)); - trcFrame->set_tooltip_text(M("TP_ICM_TRCFRAME_TOOLTIP")); + 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) ); wTRCBox = Gtk::manage(new Gtk::Box()); @@ -268,7 +271,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu fbw->set_active(true); gamut = Gtk::manage(new Gtk::CheckButton((M("TP_ICM_GAMUT")))); gamut->set_active(false); - + trcProfVBox->pack_start(*wprimBox, Gtk::PACK_EXPAND_WIDGET); trcProfVBox->pack_start(*fbw, Gtk::PACK_EXPAND_WIDGET); trcProfVBox->pack_start(*gamut, Gtk::PACK_EXPAND_WIDGET); @@ -292,6 +295,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu wprim->append(M("TP_ICM_WORKING_PRIM_ACE")); 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_BRU")); wprim->append(M("TP_ICM_WORKING_PRIM_BET")); wprim->append(M("TP_ICM_WORKING_PRIM_BST")); @@ -381,11 +385,13 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu aRendIntent->show(); riaHBox->pack_start(*aRendIntent->buttonGroup, Gtk::PACK_EXPAND_PADDING); - trcFrame->add(*trcProfVBox); pack_start(*wFrame, Gtk::PACK_EXPAND_WIDGET); - pack_start(*trcFrame, Gtk::PACK_EXPAND_WIDGET); - pack_start(*redFrame, Gtk::PACK_EXPAND_WIDGET); + trcProfVBox->pack_start(*redFrame, Gtk::PACK_EXPAND_WIDGET); + trcExp->add(*trcProfVBox, false); + trcExp->setLevel (2); + pack_start(*trcExp, Gtk::PACK_EXPAND_WIDGET); + trcExp->set_expanded(false); // ---------------------------- Output profile @@ -493,6 +499,14 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu show_all(); } +void ICMPanel::foldAllButMe (GdkEventButton* event, MyExpander *expander) +{ + if (event->button == 3) { + trcExp->set_expanded (trcExp == expander); + } +} + + void ICMPanel::neutral_pressed () { //find working profile and set the same destination proile if (wProfNames->get_active_text() == "Rec2020") { @@ -509,6 +523,8 @@ void ICMPanel::neutral_pressed () wprim->set_active(toUnderlying(ColorManagementParams::Primaries::WIDE_GAMUT)); } else if (wProfNames->get_active_text() == "ACESp0") { 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() == "BruceRGB") { wprim->set_active(toUnderlying(ColorManagementParams::Primaries::BRUCE_RGB)); } else if (wProfNames->get_active_text() == "Beta RGB") { @@ -788,6 +804,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker wtrcconn_(wtrcconn); ConnectionBlocker willconn_(willconn); ConnectionBlocker wprimconn_(wprimconn); + trcExp->set_expanded(false); if (pp->icm.inputProfile.substr(0, 5) != "file:") { ipDialog->set_filename(" "); @@ -1082,6 +1099,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::Primaries::ACES_P1: case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: + case ColorManagementParams::Primaries::JDC_MAX: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1475,6 +1493,7 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::Primaries::ACES_P1: case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: + case ColorManagementParams::Primaries::JDC_MAX: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1507,7 +1526,7 @@ void ICMPanel::wtrcinChanged() void ICMPanel::willChanged() { - switch (ColorManagementParams::Primaries(wprim->get_active_row_number())) { + switch (ColorManagementParams::Primaries(wprim->get_active_row_number() )) { case ColorManagementParams::Primaries::DEFAULT: case ColorManagementParams::Primaries::SRGB: case ColorManagementParams::Primaries::ADOBE_RGB: @@ -1516,6 +1535,7 @@ void ICMPanel::willChanged() case ColorManagementParams::Primaries::ACES_P1: case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: + case ColorManagementParams::Primaries::JDC_MAX: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1630,6 +1650,17 @@ void ICMPanel::wprimChanged() break; } + case ColorManagementParams::Primaries::JDC_MAX: { + 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::D50)); + break; + } + case ColorManagementParams::Primaries::BRUCE_RGB: { redx->setValue(0.64); redy->setValue(0.33); @@ -1722,6 +1753,14 @@ void ICMPanel::wprimChanged() blux->setValue(0.0001); bluy->setValue(-0.077); will->set_active(toUnderlying(ColorManagementParams::Illuminant::D60)); + } else if (wProfNames->get_active_text() == "JDCmax") { + 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::D50)); } else if (wProfNames->get_active_text() == "BruceRGB") { redx->setValue(0.64); redy->setValue(0.33); @@ -1729,7 +1768,7 @@ void ICMPanel::wprimChanged() grey->setValue(0.65); blux->setValue(0.15); bluy->setValue(0.06); - will->set_active(toUnderlying(ColorManagementParams::Illuminant::D65)); + will->set_active(toUnderlying(ColorManagementParams::Illuminant::D65)); } else if (wProfNames->get_active_text() == "Beta RGB") { redx->setValue(0.6888); redy->setValue(0.3112); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 6c670c5e6..f41e17b7b 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -49,6 +49,7 @@ protected: Gtk::Frame* dcpFrame; Gtk::Frame* coipFrame; Gtk::Frame* redFrame; + MyExpander* trcExp; Adjuster* wGamma; Adjuster* wSlope; @@ -168,6 +169,7 @@ private: Glib::ustring camName; void updateDCP(int dcpIlluminant, Glib::ustring dcp_name); void updateRenderingIntent(const Glib::ustring &profile); + void foldAllButMe (GdkEventButton* event, MyExpander *expander); float nextrx; float nextry; diff --git a/rtgui/options.cc b/rtgui/options.cc index e89fcd647..214dc5c67 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -631,7 +631,8 @@ void Options::setDefaults() rtSettings.fftwsigma = true; //choice between sigma^2 or empirical formula // end locallab rtSettings.itcwb_enable = true; - + rtSettings.itcwb_deltaspec = 0.075; + rtSettings.itcwb_powponder = 0.15;//max 0.2 //wavelet rtSettings.edghi = 3.0;//1.1 and 5. rtSettings.edglo = 0.5;//0.1 and 0.95 @@ -1819,6 +1820,16 @@ void Options::readFromFile(Glib::ustring fname) } + if (keyFile.has_key("Color Management", "Itcwb_deltaspec")) { + rtSettings.itcwb_deltaspec = keyFile.get_double("Color Management", "Itcwb_deltaspec"); + } + + + if (keyFile.has_key("Color Management", "Itcwb_powponder")) { + rtSettings.itcwb_powponder = keyFile.get_double("Color Management", "Itcwb_powponder"); + } + + //if (keyFile.has_key ("Color Management", "Colortoningab")) rtSettings.colortoningab = keyFile.get_double("Color Management", "Colortoningab"); //if (keyFile.has_key ("Color Management", "Decaction")) rtSettings.decaction = keyFile.get_double("Color Management", "Decaction"); @@ -2596,6 +2607,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_double("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); keyFile.set_double("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); keyFile.set_boolean("Color Management", "Itcwb_enable", rtSettings.itcwb_enable); + keyFile.set_double("Color Management", "Itcwb_deltaspec", rtSettings.itcwb_deltaspec); + keyFile.set_double("Color Management", "Itcwb_powponder", rtSettings.itcwb_powponder); //keyFile.set_double ("Color Management", "Colortoningab", rtSettings.colortoningab); //keyFile.set_double ("Color Management", "Decaction", rtSettings.decaction); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index adf462d84..3dc9f210e 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -267,15 +267,11 @@ void ParamsEdited::set(bool v) wb.equal = v; wb.tempBias = v; wb.observer = v; - wb.itcwb_thres = v; - wb.itcwb_precis = v; - wb.itcwb_size = v; - wb.itcwb_delta = v; - wb.itcwb_fgreen = v; + wb.itcwb_green = v; wb.itcwb_rgreen = v; wb.itcwb_nopurple = v; - wb.itcwb_sorted = v; - wb.itcwb_forceextra = v; + wb.itcwb_alg = v; + wb.itcwb_prim = v; wb.itcwb_sampling = v; //colorShift.a = v; //colorShift.b = v; @@ -984,15 +980,11 @@ void ParamsEdited::initFrom(const std::vector& wb.temperature = wb.temperature && p.wb.temperature == other.wb.temperature; wb.tempBias = wb.tempBias && p.wb.tempBias == other.wb.tempBias; wb.observer = wb.observer && p.wb.observer == other.wb.observer; - wb.itcwb_thres = wb.itcwb_thres && p.wb.itcwb_thres == other.wb.itcwb_thres; - wb.itcwb_precis = wb.itcwb_precis && p.wb.itcwb_precis == other.wb.itcwb_precis; - wb.itcwb_size = wb.itcwb_size && p.wb.itcwb_size == other.wb.itcwb_size; - wb.itcwb_delta = wb.itcwb_delta && p.wb.itcwb_delta == other.wb.itcwb_delta; - wb.itcwb_fgreen = wb.itcwb_fgreen && p.wb.itcwb_fgreen == other.wb.itcwb_fgreen; + wb.itcwb_green = wb.itcwb_green && p.wb.itcwb_green == other.wb.itcwb_green; wb.itcwb_rgreen = wb.itcwb_rgreen && p.wb.itcwb_rgreen == other.wb.itcwb_rgreen; wb.itcwb_nopurple = wb.itcwb_nopurple && p.wb.itcwb_nopurple == other.wb.itcwb_nopurple; - wb.itcwb_sorted = wb.itcwb_sorted && p.wb.itcwb_sorted == other.wb.itcwb_sorted; - wb.itcwb_forceextra = wb.itcwb_forceextra && p.wb.itcwb_forceextra == other.wb.itcwb_forceextra; + 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; //colorShift.a = colorShift.a && p.colorShift.a == other.colorShift.a; //colorShift.b = colorShift.b && p.colorShift.b == other.colorShift.b; @@ -2868,24 +2860,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wb.observer = mods.wb.observer; } - if (wb.itcwb_thres) { - toEdit.wb.itcwb_thres = mods.wb.itcwb_thres; - } - - if (wb.itcwb_precis) { - toEdit.wb.itcwb_precis = mods.wb.itcwb_precis; - } - - if (wb.itcwb_size) { - toEdit.wb.itcwb_size = mods.wb.itcwb_size; - } - - if (wb.itcwb_delta) { - toEdit.wb.itcwb_delta = mods.wb.itcwb_delta; - } - - if (wb.itcwb_fgreen) { - toEdit.wb.itcwb_fgreen = mods.wb.itcwb_fgreen; + if (wb.itcwb_green) { + toEdit.wb.itcwb_green = mods.wb.itcwb_green; } if (wb.itcwb_rgreen) { @@ -2896,12 +2872,12 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wb.itcwb_nopurple = mods.wb.itcwb_nopurple; } - if (wb.itcwb_sorted) { - toEdit.wb.itcwb_sorted = mods.wb.itcwb_sorted; + if (wb.itcwb_alg) { + toEdit.wb.itcwb_alg = mods.wb.itcwb_alg; } - if (wb.itcwb_forceextra) { - toEdit.wb.itcwb_forceextra = mods.wb.itcwb_forceextra; + if (wb.itcwb_prim) { + toEdit.wb.itcwb_prim = mods.wb.itcwb_prim; } if (wb.itcwb_sampling) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3c8a70b74..b22da8749 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -249,16 +249,12 @@ struct WBParamsEdited { bool equal; bool observer; bool tempBias; - bool itcwb_thres; - bool itcwb_precis; - bool itcwb_size; - bool itcwb_delta; - bool itcwb_fgreen; bool itcwb_rgreen; bool itcwb_nopurple; - bool itcwb_sorted; - bool itcwb_forceextra; + bool itcwb_alg; + bool itcwb_prim; bool itcwb_sampling; + bool itcwb_green; }; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c9737704e..659e894ce 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -959,6 +959,23 @@ Gtk::Widget* Preferences::getColorManPanel () vbColorMan->pack_start (*fcie, Gtk::PACK_SHRINK); + //------------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); + wbah->pack_start(*mwbaena, Gtk::PACK_SHRINK, 0); + wbaVB->add(*wbah); + + fwbacorr->add (*wbaVB); + vbColorMan->pack_start (*fwbacorr, Gtk::PACK_SHRINK); //------------- swColorMan->add(*vbColorMan); @@ -1829,6 +1846,7 @@ void Preferences::storePreferences() moptions.rtSettings.monitorBPC = monBPC->get_active(); moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active(); moptions.rtSettings.autocielab = mcie->get_active(); + moptions.rtSettings.itcwb_enable = mwbaena->get_active(); #endif @@ -1988,6 +2006,7 @@ void Preferences::fillPreferences() monBPC->set_active(moptions.rtSettings.monitorBPC); mcie->set_active(moptions.rtSettings.autocielab); + mwbaena->set_active(moptions.rtSettings.itcwb_enable); cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 6e31761a4..baa3543ae 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -137,9 +137,11 @@ class Preferences final : Gtk::CheckButton* cbdaubech; Gtk::SpinButton* hlThresh; Gtk::SpinButton* shThresh; -// Gtk::CheckButton* mwbacorr; + Gtk::CheckButton* mwbacorr; // Gtk::CheckButton* mwbaforc; // Gtk::CheckButton* mwbanopurp; + Gtk::CheckButton* mwbaena; +// Gtk::CheckButton* mwbaenacustom; // Gtk::CheckButton* mwbasort; // Gtk::SpinButton* wbacorrnb; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 761f2402a..f5ed63b37 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -247,6 +247,9 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC auto m = ProcEventMapper::getInstance(); EvWBObserver10 = m->newEvent(ALLNORAW, "HISTORY_MSG_WBALANCE_OBSERVER10"); + EvWBitcwbprim = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_PRIM"); + EvWBitcwbalg = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_OBS"); + EvWBitcwgreen = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_GREEN"); //Add the model columns to the Combo (which is a kind of view), @@ -342,6 +345,10 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC StudLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); StudLabel->set_tooltip_text(M("TP_WBALANCE_STUDLABEL_TOOLTIP")); + PatchLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + PatchLabel->set_tooltip_text(M("TP_WBALANCE_PATCHLABEL_TOOLTIP")); + PatchlevelLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + PatchlevelLabel->set_tooltip_text(M("TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP")); mulLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); mulLabel->set_tooltip_text(M("TP_WBALANCE_MULLABEL_TOOLTIP")); @@ -350,7 +357,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, CENTERTEMP, itempL, itempR, &wbSlider2Temp, &wbTemp2Slider)); green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0, igreenL, igreenR)); equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0, iblueredL, iblueredR)); - tempBias = Gtk::manage (new Adjuster(M("TP_WBALANCE_TEMPBIAS"), -0.5, 0.5, 0.01, 0.0, itempbiasL, itempbiasR)); + tempBias = Gtk::manage (new Adjuster(M("TP_WBALANCE_TEMPBIAS"), -1.1, 1.1, 0.005, 0.0, itempbiasL, itempbiasR)); observer10 = Gtk::manage(new CheckBox(M("TP_WBALANCE_OBSERVER10"), multiImage)); cache_customTemp (0); @@ -364,6 +371,32 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC equal->show (); tempBias->show (); observer10->show(); + itcwbFrame = Gtk::manage(new Gtk::Frame(M("TP_WBALANCE_ITCWB_FRA"))); + + itcwbFrame->set_label_align(0.025, 0.5); + itcwbFrame->set_tooltip_markup (M("PREFERENCES_WBACORR_TOOLTIP")); + + ToolParamBlock* const itcwbBox = Gtk::manage(new ToolParamBlock()); + + + itcwb_green = Gtk::manage (new Adjuster (M("TP_WBALANCE_ITCWGREEN"), -0.35, 0.35, 0.005, 0.)); + itcwb_green ->set_tooltip_markup (M("TP_WBALANCE_ITCWGREEN_TOOLTIP")); + + itcwb_alg = Gtk::manage (new Gtk::CheckButton (M("TP_WBALANCE_ITCWB_ALG"))); + itcwb_alg ->set_tooltip_markup (M("TP_WBALANCE_ITCWALG_TOOLTIP")); + itcwb_alg ->set_active (false); + + + + itcwb_prim = Gtk::manage (new MyComboBoxText ()); + itcwb_prim->append(M("TP_WBALANCE_ITCWB_PRIM_SRGB")); + itcwb_prim->append(M("TP_WBALANCE_ITCWB_PRIM_BETA")); + itcwb_prim->append(M("TP_WBALANCE_ITCWB_PRIM_XYZCAM")); + itcwb_prim->append(M("TP_WBALANCE_ITCWB_PRIM_JDCMAX")); + 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")); + /* Gtk::Box* boxgreen = Gtk::manage (new Gtk::Box ()); boxgreen->show (); @@ -373,6 +406,8 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC boxgreen->pack_start(*igreenR);*/ pack_start(*mulLabel); pack_start(*StudLabel); + pack_start(*PatchLabel); + pack_start(*PatchlevelLabel); pack_start (*temp); //pack_start (*boxgreen); @@ -382,14 +417,33 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC pack_start(*observer10); + itcwbBox->pack_start (*itcwb_green); + itcwbBox->pack_start (*itcwb_alg); + itcwbBox->pack_start (*itcwb_prim); + itcwbFrame->add(*itcwbBox); + pack_start(*itcwbFrame); + + if(options.rtSettings.itcwb_enable) { + itcwb_green->show(); + itcwb_alg->show(); + itcwb_prim->show(); + itcwbFrame->show(); + } else { + itcwb_green->show(); + itcwb_alg->hide(); + itcwb_prim->hide(); + } temp->setAdjusterListener (this); green->setAdjusterListener (this); equal->setAdjusterListener (this); tempBias->setAdjusterListener (this); observer10->setCheckBoxListener(this); + itcwb_green->setAdjusterListener (this); spotbutton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::spotPressed) ); methconn = method->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::optChanged) ); + itcwb_algconn = itcwb_alg->signal_toggled().connect( sigc::mem_fun(*this, &WhiteBalance::itcwb_alg_toggled) ); + resetButton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::resetWB) ); spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); } @@ -411,9 +465,36 @@ void WhiteBalance::enabledChanged() } } } +void WhiteBalance::itcwb_prim_changed () +{ + if (listener && getEnabled()) { + listener->panelChanged(EvWBitcwbprim, M("GENERAL_ENABLED")); + } +} +void WhiteBalance::itcwb_alg_toggled () +{ + if (batchMode) { + if (itcwb_alg->get_inconsistent()) { + itcwb_alg->set_inconsistent (false); + itcwb_algconn.block (true); + itcwb_alg->set_active (false); + itcwb_algconn.block (false); + } else if (lastitcwb_alg) { + itcwb_alg->set_inconsistent (true); + } + lastitcwb_alg = itcwb_alg->get_active (); + } + if (listener && getEnabled()) { + if (itcwb_alg->get_active ()) { + listener->panelChanged (EvWBitcwbalg, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvWBitcwbalg, M("GENERAL_DISABLED")); + } + } +} void WhiteBalance::adjusterChanged(Adjuster* a, double newval) { @@ -437,6 +518,7 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) ( a == equal || a == tempBias + || a == itcwb_green ) && ppMethod.second.type == WBEntry::Type::AUTO ) @@ -467,12 +549,16 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) if (listener && getEnabled()) { if (a == temp) { listener->panelChanged (EvWBTemp, Glib::ustring::format ((int)a->getValue())); + itcwbFrame->set_sensitive(false); } else if (a == green) { listener->panelChanged (EvWBGreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + itcwbFrame->set_sensitive(false); } else if (a == equal) { listener->panelChanged (EvWBequal, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); } else if (a == tempBias) { listener->panelChanged (EvWBtempBias, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(2), a->getValue())); + } else if (a == itcwb_green) { + listener->panelChanged (EvWBitcwgreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(2), a->getValue())); } } } @@ -507,6 +593,7 @@ void WhiteBalance::checkBoxToggled(CheckBox* c, CheckValue newval) } } + void WhiteBalance::optChanged () { Gtk::TreeModel::Row row = getActiveMethod(); @@ -524,6 +611,8 @@ void WhiteBalance::optChanged () } StudLabel->hide(); mulLabel->show(); + PatchLabel->hide(); + PatchlevelLabel->hide(); if (opt != row[methodColumns.colId]) { @@ -543,8 +632,16 @@ void WhiteBalance::optChanged () bool autit = (currMethod.ppLabel == "autitcgreen"); if (autit) { StudLabel->show(); + PatchLabel->show(); + PatchlevelLabel->show(); + equal->hide(); + itcwbFrame->set_sensitive(true); } else { StudLabel->hide(); + PatchLabel->hide(); + PatchlevelLabel->hide(); + equal->show(); + itcwbFrame->set_sensitive(false); } switch (currMethod.type) { @@ -638,6 +735,8 @@ void WhiteBalance::spotPressed () { StudLabel->hide(); mulLabel->show(); + PatchLabel->hide(); + PatchlevelLabel->hide(); if (wblistener) { wblistener->spotWBRequested (getSize()); @@ -663,6 +762,41 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) tempBias->setValue (pp->wb.tempBias); tempBias->set_sensitive(true); + itcwb_algconn.block (true); + itcwb_alg->set_active (pp->wb.itcwb_alg); + itcwb_algconn.block (false); + lastitcwb_alg = pp->wb.itcwb_alg; + itcwb_green->setValue (pp->wb.itcwb_green); + + + itcwb_primconn.block (true); + + if (pp->wb.itcwb_prim == "srgb") { + itcwb_prim->set_active(0); + } else if (pp->wb.itcwb_prim == "beta") { + itcwb_prim->set_active(1); + } else if (pp->wb.itcwb_prim == "XYZcam") { + itcwb_prim->set_active(2); + } else if (pp->wb.itcwb_prim == "jdcmax") { + itcwb_prim->set_active(3); + } + itcwb_primconn.block (false); + + + + if(options.rtSettings.itcwb_enable) { + itcwb_green->show(); + itcwb_alg->show(); + itcwb_prim->show(); + itcwbFrame->show(); + + } else { + itcwb_green->hide(); + itcwb_alg->hide(); + itcwb_prim->hide(); + itcwbFrame->hide(); + } + if (pedited) { // By default, temperature and green are said "UnEdited", but it may change later temp->setEditedState (UnEdited); @@ -670,6 +804,8 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) equal->setEditedState (pedited->wb.equal ? Edited : UnEdited); tempBias->setEditedState (pedited->wb.tempBias ? Edited : UnEdited); observer10->setEdited(pedited->wb.observer); + itcwb_alg->set_inconsistent (!pedited->wb.itcwb_alg); + itcwb_green->setEditedState (pedited->wb.itcwb_green ? Edited : UnEdited); } if (pedited && !pedited->wb.method) { @@ -780,9 +916,21 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) bool autit = (wbValues.ppLabel == "autitcgreen"); if (autit) { StudLabel->show(); + PatchLabel->show(); + PatchlevelLabel->show(); + equal->hide(); + if(pp->wb.itcwb_sampling) { + tempBias->set_sensitive(false); + } + itcwbFrame->set_sensitive(!pp->wb.itcwb_sampling); + itcwb_prim_changed (); } else { StudLabel->hide(); + PatchLabel->hide(); + PatchlevelLabel->hide(); mulLabel->show(); + equal->show(); + itcwbFrame->set_sensitive(false); } } @@ -808,16 +956,32 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pedited->wb.equal = equal->getEditedState (); pedited->wb.tempBias = tempBias->getEditedState (); pedited->wb.observer = observer10->getEdited(); + pedited->wb.itcwb_alg = !itcwb_alg->get_inconsistent(); pedited->wb.method = row[methodColumns.colLabel] != M("GENERAL_UNCHANGED"); pedited->wb.enabled = !get_inconsistent(); + pedited->wb.itcwb_prim = itcwb_prim->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wb.itcwb_green = itcwb_green->getEditedState (); } pp->wb.enabled = getEnabled(); + if (itcwb_prim->get_active_row_number() == 0) { + pp->wb.itcwb_prim = "srgb"; + } else if (itcwb_prim->get_active_row_number() == 1){ + pp->wb.itcwb_prim = "beta"; + } else if (itcwb_prim->get_active_row_number() == 2){ + pp->wb.itcwb_prim = "XYZcam"; + } else if (itcwb_prim->get_active_row_number() == 3){ + pp->wb.itcwb_prim = "jdcmax"; + } const std::pair ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); if (ppMethod.first) { pp->wb.method = ppMethod.second.ppLabel; + if (pp->wb.method != "autitcgreen") { + // Prepare migration to new ITCWB algorithm. + pp->wb.itcwb_sampling = false; + } } pp->wb.temperature = temp->getIntValue (); @@ -829,7 +993,9 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) : observer10->getValue() == CheckValue::off ? rtengine::StandardObserver::TWO_DEGREES : pp->wb.observer; + pp->wb.itcwb_alg = itcwb_alg->get_active (); pp->wb.tempBias = tempBias->getValue (); + pp->wb.itcwb_green = itcwb_green->getValue (); } void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) @@ -837,6 +1003,7 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* equal->setDefault (defParams->wb.equal); tempBias->setDefault (defParams->wb.tempBias); + itcwb_green->setDefault (defParams->wb.itcwb_green); if (wbp && defParams->wb.method == "Camera") { double ctemp; @@ -859,11 +1026,13 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* green->setDefaultEditedState (pedited->wb.green ? Edited : UnEdited); equal->setDefaultEditedState (pedited->wb.equal ? Edited : UnEdited); tempBias->setDefaultEditedState (pedited->wb.tempBias ? Edited : UnEdited); + itcwb_green->setDefaultEditedState (pedited->wb.itcwb_green ? Edited : UnEdited); } else { temp->setDefaultEditedState (Irrelevant); green->setDefaultEditedState (Irrelevant); equal->setDefaultEditedState (Irrelevant); tempBias->setDefaultEditedState (Irrelevant); + itcwb_green->setDefaultEditedState (Irrelevant); } } @@ -1015,24 +1184,62 @@ inline Gtk::TreeRow WhiteBalance::getActiveMethod () return *(method->get_active()); } -void WhiteBalance::WBChanged(double temperature, double greenVal, double rw, double gw, double bw, float studgood) +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) { idle_register.add( - [this, temperature, greenVal, rw, gw, bw, studgood]() -> bool + [this, met, temperature, greenVal, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, histmin, histmax]() -> bool { disableListener(); temp->setValue(temperature); green->setValue(greenVal); + double stud; + stud = studgood; + if(studgood < 0.0001) { + stud = 0.0001; + } + int bia2 = bia; mulLabel->set_text( Glib::ustring::compose(M("TP_WBALANCE_MULLABEL"), Glib::ustring::format(std::fixed, std::setprecision(4), rw), Glib::ustring::format(std::fixed, std::setprecision(2), gw), Glib::ustring::format(std::fixed, std::setprecision(4), bw)) ); - StudLabel->set_text( - Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(4), studgood)) - ); + if(bia == 3) { + bia2 = bia - 1; + StudLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(4), stud), + Glib::ustring::format(std::fixed, std::setprecision(0), bia2), + Glib::ustring::format(std::fixed, std::setprecision(0), temp0)) + ); + } else if(bia == 2) { + StudLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL1"), + Glib::ustring::format(std::fixed, std::setprecision(4), stud), + Glib::ustring::format(std::fixed, std::setprecision(0), bia), + Glib::ustring::format(std::fixed, std::setprecision(0), temp0)) + ); + } else { + StudLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL0"), + Glib::ustring::format(std::fixed, std::setprecision(4), stud), + Glib::ustring::format(std::fixed, std::setprecision(0), bia), + Glib::ustring::format(std::fixed, std::setprecision(0), temp0)) + ); + } + PatchLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_PATCHLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), dread), + Glib::ustring::format(std::fixed, std::setprecision(4), minchrom), + Glib::ustring::format(std::fixed, std::setprecision(0), kmin)) + ); + PatchlevelLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_PATCHLEVELLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(4), delta), + Glib::ustring::format(std::fixed, std::setprecision(0), histmin), + Glib::ustring::format(std::fixed, std::setprecision(0), histmax)) + ); + temp->setDefault(temperature); green->setDefault(greenVal); enableListener(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 56d8b646c..060026a48 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -46,6 +46,8 @@ class WhiteBalance final : public ToolParamBlock, public AdjusterListener, publi private: Gtk::Label* StudLabel; + Gtk::Label* PatchLabel; + Gtk::Label* PatchlevelLabel; Gtk::Label* mulLabel; protected: @@ -64,6 +66,9 @@ protected: }; rtengine::ProcEvent EvWBObserver10; + rtengine::ProcEvent EvWBitcwbprim; + rtengine::ProcEvent EvWBitcwbalg; + rtengine::ProcEvent EvWBitcwgreen; static Glib::RefPtr wbPixbufs[rtengine::toUnderlying(rtengine::procparams::WBEntry::Type::CUSTOM) + 1]; Glib::RefPtr refTreeModel; @@ -76,6 +81,12 @@ protected: Adjuster* equal; Adjuster* tempBias; CheckBox* observer10; + Gtk::Frame* itcwbFrame; + Gtk::CheckButton* itcwb_alg; + MyComboBoxText* itcwb_prim; + Adjuster* itcwb_green; + + bool lastitcwb_alg; Gtk::Button* spotbutton; int opt; @@ -83,7 +94,7 @@ protected: double nextGreen; WBProvider *wbp; // pointer to a ToolPanelCoordinator object, or its subclass BatchToolPanelCoordinator SpotWBListener* wblistener; - sigc::connection methconn; + sigc::connection methconn, itcwb_algconn, itcwb_primconn; int custom_temp; double custom_green; double custom_equal; @@ -131,8 +142,9 @@ public: } void setWB (int temp, double green); void resetWB (); - void WBChanged (double temp, double green, double rw, double gw, double bw, float studgood) 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) override; + void itcwb_alg_toggled (); + void itcwb_prim_changed (); void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void enabledChanged() override; From ccf8f5a66c9fd9f4d7c202d99f7e1bb8393df303 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:43:58 -0700 Subject: [PATCH 308/326] Correct the Czech language name --- rtdata/languages/Czech | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 680e0a1bb..d14a221d6 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -47,7 +47,7 @@ #046 2020-04-21 updated by mkyral #047 2020-06-02 updated by mkyral #100 -#101 @LANGUAGE_DISPLAY_NAME=Český +#101 @LANGUAGE_DISPLAY_NAME=Čeština ABOUT_TAB_BUILD;Verze ABOUT_TAB_CREDITS;Zásluhy From 548907da3422bff719d4c6142815cb3bb11d8c2d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 6 Aug 2023 16:44:54 -0700 Subject: [PATCH 309/326] Fix external editor button updates Make sure the pop-up button is updated in both multiple editors modes. --- rtgui/editwindow.cc | 7 +++++++ rtgui/editwindow.h | 2 ++ rtgui/popupcommon.cc | 16 ++++++++++++++-- rtgui/popupcommon.h | 6 ++++-- rtgui/rtwindow.cc | 11 +++++++++++ rtgui/rtwindow.h | 3 +++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index 0364b0afa..3184c21c4 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -488,6 +488,13 @@ void EditWindow::set_title_decorated(Glib::ustring fname) set_title("RawTherapee " + M("EDITWINDOW_TITLE") + subtitle); } +void EditWindow::updateExternalEditorWidget(int selectedIndex, const std::vector &editors) +{ + for (const auto& panel : epanels) { + panel.second->updateExternalEditorWidget(selectedIndex, editors); + } +} + void EditWindow::updateToolPanelToolLocations( const std::vector &favorites, bool cloneFavoriteTools) { diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index 0b10cb67e..a5932c081 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -24,6 +24,7 @@ #include "guiutils.h" class EditorPanel; +class ExternalEditor; class RTWindow; class EditWindow : @@ -66,6 +67,7 @@ public: bool selectEditorPanel(const std::string &name); bool closeOpenEditors(); bool isProcessing(); + void updateExternalEditorWidget(int selectedIndex, const std::vector &editors); void updateToolPanelToolLocations( const std::vector &favorites, bool cloneFavoriteTools); diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 2517a0a76..741d4da0f 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -20,10 +20,12 @@ */ #include + +#include "guiutils.h" #include "multilangmgr.h" #include "popupcommon.h" #include "rtimage.h" -#include "guiutils.h" +#include "threadutils.h" PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) : buttonImage (nullptr) @@ -203,6 +205,15 @@ void PopUpCommon::changeImage(const Glib::ustring& fileName, const Glib::RefPtr< void PopUpCommon::entrySelected(Gtk::Widget* widget) { + if (widget != menu->get_active()) { // Not actually selected. + return; + } + + if (!entrySelectionMutex.trylock()) { // Already being updated. + return; + } + entrySelectionMutex.unlock(); + int i = 0; for (const auto & child : menu->get_children()) { if (widget == child) { @@ -249,7 +260,8 @@ bool PopUpCommon::setSelected (int entryNum) setButtonHint(); auto radioMenuItem = dynamic_cast(menu->get_children()[entryNum]); - if (radioMenuItem && menu->get_active() != radioMenuItem) { + if (radioMenuItem && !radioMenuItem->get_active()) { + MyMutex::MyLock updateLock(entrySelectionMutex); radioMenuItem->set_active(); } diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 228e0fba0..91bfdabea 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -20,12 +20,13 @@ */ #pragma once -#include "glibmm/refptr.h" +#include "threadutils.h" + #include #include +#include #include - #include namespace Gio @@ -91,6 +92,7 @@ private: Gtk::Button* arrowButton; int selected; bool hasMenu; + MyMutex entrySelectionMutex; void changeImage(int position); void changeImage(const Glib::ustring& fileName, const Glib::RefPtr& gIcon); diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index dcfc2f05c..5513f356b 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -589,6 +589,7 @@ void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) } else { ep->setParent (this); ep->setParentWindow (this); + ep->setExternalEditorChangedSignal(&externalEditorChangedSignal); // construct closeable tab for the image Gtk::Grid* titleGrid = Gtk::manage (new Gtk::Grid ()); @@ -637,6 +638,7 @@ void RTWindow::remEditorPanel (EditorPanel* ep) wndEdit->remEditorPanel (ep); } else { bool queueHadFocus = (mainNB->get_current_page() == mainNB->page_num (*bpanel)); + ep->setExternalEditorChangedSignal(nullptr); epanels.erase (ep->getFileName()); filesEdited.erase (ep->getFileName ()); fpanel->refreshEditedState (filesEdited); @@ -1060,6 +1062,15 @@ void RTWindow::updateExternalEditorWidget(int selectedIndex, const std::vectorupdateExternalEditorWidget(selectedIndex, editors); } + + for (auto panel : epanels) { + panel.second->updateExternalEditorWidget(selectedIndex, editors); + } + + if (options.multiDisplayMode > 0) { + EditWindow::getInstance(this) + ->updateExternalEditorWidget(selectedIndex, editors); + } } void RTWindow::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 922588a19..4c3aa75ea 100755 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -20,6 +20,7 @@ #include #include +#include #if defined(__APPLE__) #include @@ -48,6 +49,8 @@ private: std::set filesEdited; std::map epanels; + sigc::signal externalEditorChangedSignal; + Splash* splash; Gtk::ProgressBar prProgBar; PLDBridge* pldBridge; From 8d437fec3827f1d4e8edbf0b7e576957c5621106 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Mon, 7 Aug 2023 07:06:55 +0200 Subject: [PATCH 310/326] Change range blmask in iplocallab - thanks to hombre --- rtengine/iplocallab.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 6db6b7627..b8a9cd76c 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -5342,6 +5342,7 @@ void ImProcFunctions::blendstruc(int bfw, int bfh, LabImage* bufcolorig, float r static void blendmask(const local_params& lp, int xstart, int ystart, int cx, int cy, int bfw, int bfh, LabImage* bufexporig, LabImage* original, LabImage* bufmaskor, LabImage* originalmas, float bl, float blab, int inv) { + bl /= 10.f; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif From 6720fa90e70571a547e2dd66a51972816e12f24e Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 7 Aug 2023 12:53:33 +0700 Subject: [PATCH 311/326] Mac: change -cli ad hoc signature to certified *Ventura* no longer supports a distribution ad hoc signatory. Changes codesign command for the -cli to use developer certificate. --- tools/osx/macosx_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index ff5a44254..c77e663dd 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -448,7 +448,7 @@ function CreateDmg { msg "Zipping disk image for redistribution:" mkdir "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" cp {"${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.dmg","${PROJECT_NAME}.app/Contents/MacOS/rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.readme.rtf"} "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" - codesign -s - -i com.rawtherapee.rawtherapee-cli -f "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/rawtherapee-cli" + codesign -s "${CODESIGNID}" -i com.rawtherapee.rawtherapee-cli -f "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/rawtherapee-cli" zip -r "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder/" if [[ -n $NIGHTLY ]]; then cp "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_macOS_${arch}_latest.zip" From 269e426cc6d999148cd69c8b65883e37257c6c85 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Mon, 7 Aug 2023 08:48:08 +0200 Subject: [PATCH 312/326] Another change to blendmask --- rtengine/iplocallab.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b8a9cd76c..bd144973e 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -18659,7 +18659,7 @@ void ImProcFunctions::Lab_Local( 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 = params->locallab.spots.at(sp).blendmask; + 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 From 12e60dd6c3b3b05d141c950b427069fb3c39abf1 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 7 Aug 2023 07:06:51 -0700 Subject: [PATCH 313/326] Mac: fix macos_bundle output formatting Updates message formatting in the bundle script to escaped formatting, eliminating output terminal errors. --- tools/osx/macosx_bundle.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index c77e663dd..970611e90 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -9,11 +9,11 @@ # - GTK_PREFIX # Formatting -fNormal="$(tput sgr0)" >/dev/null 2>&1 -fBold="$(tput bold)" >/dev/null 2>&1 +fNormal="$(printf "\e[0m")" +fBold="$(printf "\e[1m")" # Colors depend upon the user's terminal emulator color scheme - what is readable for you may be not readable for someone else. -fMagenta="$(tput setaf 5)" >/dev/null 2>&1 -fRed="$(tput setaf 1)" >/dev/null 2>&1 +fMagenta="$(printf "\e[1;35m")" +fRed="$(printf "\e[1;31m")" function msg { printf "\\n${fBold}-- %s${fNormal}\\n" "${@}" From 1f7d2d4ebcb78a2754b9f5e4e4d9230bc1ec28ef Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 12 Aug 2023 15:10:44 -0700 Subject: [PATCH 314/326] Remove metadata-exiv2 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 fae43ed25..760f3f25b 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:metadata-exiv2"]' + publish_pre_dev_labels: '[]' jobs: build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index efe2295cc..b368ad0c0 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:metadata-exiv2"]' + publish_pre_dev_labels: '[]' jobs: build: runs-on: windows-2022 From db4bfd8695578b06c24dd0eaea36e589a8c74120 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 12 Aug 2023 15:39:59 -0700 Subject: [PATCH 315/326] Add tooltips for LCP & Lensfun dir in preferences --- rtdata/languages/default | 2 ++ rtgui/preferences.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 8fa85f144..835831547 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1914,7 +1914,9 @@ PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is uned PREFERENCES_LANG;Language PREFERENCES_LANGAUTODETECT;Use system 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_MENUGROUPEXTPROGS;Group 'Open with' PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index da8272442..82ef67d2f 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -660,6 +660,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () //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); lensProfilesDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_LENSPROFILESDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties(lensProfilesDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -669,6 +670,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () // Lensfun DB dir Gtk::Label *lensfunDbDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSFUNDBDIR") + ":")); + lensfunDbDirLabel->set_tooltip_text(M("PREFERENCES_LENSFUNDBDIR_TOOLTIP")); setExpandAlignProperties(lensfunDbDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); lensfunDbDir = Gtk::manage(new MyFileChooserEntry(M("PREFERENCES_LENSFUNDBDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); lensfunDbDir->set_placeholder_text(Glib::ustring::compose("(%1)", M("GENERAL_AUTO"))); From 83263a3504165db900685878370427804d748696 Mon Sep 17 00:00:00 2001 From: Hombre57 Date: Sun, 13 Aug 2023 01:01:18 +0200 Subject: [PATCH 316/326] Fix for Treeview's editable entries incorrectly displayed --- rtdata/themes/RawTherapee-GTK3-20_.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index e909eb33f..b69e543d1 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -44,7 +44,7 @@ textview.view, treeview.view { padding: 0; margin: 0; } -.view, .textview, textview, textview.view { +.view, .textview, textview, textview.view, treeview > entry { background-color: #262626; } /* The headers of these panels */ From ac48cc55d8556403b92d3183c69080b60faabe58 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 15 Aug 2023 07:52:38 -0700 Subject: [PATCH 317/326] Better use of cache with inpaint opposed highight reconstruction (#6822) * Speed up preview when inpaint opposed enabled Only reprocess from raw if the white balance is changed. Otherwise, a cache from later in the pipeline can be used. * Remove unused code * Fix refresh map bit positions * Make WB & inpaint opposed refresh less brittle Co-authored-by: Hombre57 --------- Co-authored-by: Hombre57 --- rtengine/clutstore.cc | 2 +- rtengine/dcrop.cc | 12 ++++++------ rtengine/filmnegativeproc.cc | 2 +- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 13 ++++++++----- rtengine/iplocallab.cc | 2 +- rtengine/perspectivecorrection.cc | 2 +- rtengine/previewimage.cc | 2 +- rtengine/rawimagesource.cc | 7 +------ rtengine/rawimagesource.h | 2 +- rtengine/refreshmap.cc | 12 ++++++------ rtengine/refreshmap.h | 12 +++++++----- rtengine/rtthumbnail.cc | 2 +- rtengine/simpleprocess.cc | 6 +++--- rtengine/spot.cc | 4 ++-- rtengine/stdimagesource.cc | 2 +- rtengine/stdimagesource.h | 2 +- rtgui/whitebalance.cc | 8 ++++---- 18 files changed, 47 insertions(+), 47 deletions(-) diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index 4c70ad951..e3bd9c988 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -57,7 +57,7 @@ bool loadFile( rtengine::procparams::ColorManagementParams icm; icm.workingProfile = working_color_space; - img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams(), 0); + img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams()); if (!working_color_space.empty()) { img_src.convertColorSpace(img_float.get(), icm, curr_wb); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index dda8489df..6abfc7aba 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -231,18 +231,18 @@ void Crop::update(int todo) if (settings->leveldnautsimpl == 1) { if (params.dirpyrDenoise.Cmethod == "MAN" || params.dirpyrDenoise.Cmethod == "PON") { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); } } else { if (params.dirpyrDenoise.C2method == "MANU") { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); } } if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PRE") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "PREV")) { PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); if ((!isDetailWindow) && parent->adnListener && skip == 1 && params.dirpyrDenoise.enabled) { float lowdenoise = 1.f; @@ -454,7 +454,7 @@ void Crop::update(int todo) for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1); - parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); // we only need image reduced to 1/4 here for (int ii = 0; ii < crH; ii += 2) { @@ -615,7 +615,7 @@ void Crop::update(int todo) // if (params.dirpyrDenoise.Cmethod=="AUT" || params.dirpyrDenoise.Cmethod=="PON") {//reinit origCrop after Auto if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { //reinit origCrop after Auto PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw); } if ((todo & M_SPOT) && params.spot.enabled && !params.spot.entries.empty()) { @@ -751,7 +751,7 @@ void Crop::update(int todo) fattalCrop.reset(f); PreviewProps pp(0, 0, parent->fw, parent->fh, skip); int tr = getCoarseBitMask(params.coarse); - parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw, 0); + parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw); parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB); if (params.dirpyrDenoise.enabled || params.filmNegative.enabled || params.spot.enabled) { diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index eb029d77a..416f495c5 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -84,7 +84,7 @@ void getSpotAvgMax(ImageSource *imgsrc, ColorTemp currWB, const std::unique_ptr< } rtengine::Imagefloat spotImg(spotSize, spotSize); - imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw, 0); + imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw); auto avgMax = [spotSize, &spotImg](RGB & avg, RGB & max) -> void { avg = {}; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index bda1ceb74..2319ddada 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -109,7 +109,7 @@ public: virtual void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const = 0; // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* - virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw, int opposed) = 0; + virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw) = 0; virtual eSensorType getSensorType () const = 0; virtual bool isMono () const = 0; // true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f939535c2..e214bbfc7 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -407,6 +407,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Color HLR alters rgb output of demosaic, so re-demosaic is needed when Color HLR is being turned off; if HLR is enabled and changing method *from* Color to any other method OR HLR gets disabled when Color method was selected + If white balance changed with inpaint opposed, because inpaint opposed depends on the white balance */ // If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST @@ -414,7 +415,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported()); } - bool iscolor = (params->toneCurve.method == "Color");// || params->toneCurve.method == "Coloropp"); + bool iscolor = (params->toneCurve.method == "Color" || params->toneCurve.method == "Coloropp"); + if ((todo & M_WB) && params->toneCurve.hrenabled && params->toneCurve.method == "Coloropp") { + todo |= DEMOSAIC; + } if ((todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) @@ -872,8 +876,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) PreviewProps pp(0, 0, fw, fh, scale); // Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications ipf.setScale(scale); - int inpaintopposed = 1;//force getimage to use inpaint-opposed if enable, only once - imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw, inpaintopposed); + imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw); if ((todo & M_SPOT) && params->spot.enabled && !params->spot.entries.empty()) { spotsDone = true; @@ -2967,7 +2970,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a currWB = ColorTemp(); // = no white balance } - imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw, 0); + imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw); ImProcFunctions ipf(&ppar, true); if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) { @@ -3144,7 +3147,7 @@ void ImProcCoordinator::process() paramsUpdateMutex.unlock(); // M_VOID means no update, and is a bit higher that the rest - if (change & (M_VOID - 1)) { + if (change & (~M_VOID)) { updatePreviewImage(change, panningRelatedChange); } diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 91c8b5dc4..75bb03267 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2130,7 +2130,7 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, Imagefloat img(int(fw / SCALE + 0.5), int(fh / SCALE + 0.5)); const ProcParams neutral; - imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw, 0); + imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw); imgsrc->convertColorSpace(&img, params->icm, imgsrc->getWB()); float minVal = RT_INFINITY; float maxVal = -RT_INFINITY; diff --git a/rtengine/perspectivecorrection.cc b/rtengine/perspectivecorrection.cc index f4428faf2..7a56ef5a8 100644 --- a/rtengine/perspectivecorrection.cc +++ b/rtengine/perspectivecorrection.cc @@ -297,7 +297,7 @@ PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *sr neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); neutral.icm.outputProfile = ColorManagementParams::NoICMString; - src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw, 0); + src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw); src->convertColorSpace(img.get(), pparams->icm, src->getWB()); neutral.commonTrans.autofill = false; // Ensures crop factor is correct. diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index e131211ce..b7e6ad9f8 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -120,7 +120,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext double contrastThresholdDummy = 0.0; rawImage.demosaic(params.raw, false, contrastThresholdDummy); Imagefloat image(fw, fh); - rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw, 0); + rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw); rtengine::Image8 output(fw, fh); rawImage.convertColorSpace(&image, params.icm, wb); #ifdef _OPENMP diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d12fa7f02..eabeb2fc9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -741,9 +741,8 @@ void RawImageSource::getWBMults(const ColorTemp &ctemp, const RAWParams &raw, st autoGainComp = camInitialGain / initialGain; } -void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) +void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { - // added int opposed to force getimage to use inpaint-opposed if enable, only once MyMutex::MyLock lock(getImageMutex); tran = defTransform(ri, tran); @@ -850,10 +849,6 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag bool doHr = (hrp.hrenabled && !iscolor); if (hrp.hrenabled && iscolor) { - if(hrp.method == "Coloropp" && opposed == 1) {//force Inpaint opposed if WB change, and opposed limited the number to 1 - rgbSourceModified = false; - } - if (!rgbSourceModified) { if (hrp.method == "Color") { if (settings->verbose) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 4bcbc7a7c..e6f9da9d5 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -146,7 +146,7 @@ public: 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 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, int opposed) override; + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; eSensorType getSensorType () const override; bool isMono () const override; ColorTemp getWB () const override diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index eb4a3f888..c589e8ba4 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DARKFRAME, // EvLCPUseVign, HDR, // EvLCPUseCA, M_VOID, // EvFixedExp - ALLNORAW, // EvWBMethod, - ALLNORAW, // EvWBTemp, - ALLNORAW, // EvWBGreen, + WB, // EvWBMethod, + WB, // EvWBTemp, + WB, // EvWBGreen, AUTOEXP, // EvToneCurveMode1, AUTOEXP, // EvToneCurve2, AUTOEXP, // EvToneCurveMode2, @@ -234,7 +234,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATbadpix LUMINANCECURVE, // EvCATAutoadap DEFRINGE, // EvPFCurve - ALLNORAW, // EvWBequal + WB, // EvWBequal 0, // EvWBequalbo : obsolete HDR, // EvGradientDegree HDR, // EvGradientEnabled @@ -470,7 +470,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvRetinexgaintransmission RETINEX, // EvLskal OUTPUTPROFILE, // EvOBPCompens - ALLNORAW, // EvWBtempBias + WB, // EvWBtempBias DARKFRAME, // EvRawImageNum 0, // unused 0, // unused @@ -517,7 +517,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvTMFattalEnabled HDR, // EvTMFattalThreshold HDR, // EvTMFattalAmount - ALLNORAW, // EvWBEnabled + WB, // EvWBEnabled AUTOEXP, // EvRGBEnabled LUMINANCECURVE, // EvLEnabled DEMOSAIC, // EvPdShrEnabled diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index b53252796..7113ba6a5 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -23,17 +23,18 @@ #include "procevents.h" // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<17) +#define M_VOID (1<<20) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<16) +#define M_MINUPDATE (1<<19) // Force high quality -#define M_HIGHQUAL (1<<15) +#define M_HIGHQUAL (1<<18) // Elementary functions that can be done to // the preview image when an event occurs -#define M_SPOT (1<<19) -#define M_CSHARP (1<<18) +#define M_WB (1<<17) +#define M_SPOT (1<<16) +#define M_CSHARP (1<<15) #define M_MONITOR (1<<14) #define M_RETINEX (1<<13) #define M_CROP (1<<12) @@ -57,6 +58,7 @@ #define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define DEMOSAIC (M_RAW|M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define WB (M_WB|M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define ALLNORAW (M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define CAPTURESHARPEN (M_INIT|M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_CSHARP) #define HDR (M_SPOT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5894bfa75..59dc14f86 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -350,7 +350,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, eSensorType &sensorType, PreviewProps pp(0, 0, w, h, 1); Imagefloat tmp(w, h); - src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw, 0); + src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw); src.convertColorSpace(&tmp, neutral.icm, src.getWB()); Image8 *img = new Image8(w, h); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index cc9756919..229aee2a8 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -373,7 +373,7 @@ private: int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f; int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; PreviewProps ppP(beg_tileW, beg_tileH, crW, crH, skipP); - imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); + imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); // we only need image reduced to 1/4 here @@ -597,7 +597,7 @@ private: for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1); - imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0); + imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); @@ -757,7 +757,7 @@ private: } baseImg = new Imagefloat(fw, fh); - imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw, 1); + imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw); if (pl) { pl->setProgress(0.50); diff --git a/rtengine/spot.cc b/rtengine/spot.cc index 09186a399..5ed090712 100644 --- a/rtengine/spot.cc +++ b/rtengine/spot.cc @@ -459,7 +459,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s } } - imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw, 0); + imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw); if (cmp) { imgsrc->convertColorSpace(srcImage, *cmp, currWB); } @@ -479,7 +479,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s dstImage->b(y, x) = 60000.f; } } - imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw, 0); + imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw); if (cmp) { imgsrc->convertColorSpace(dstImage, *cmp, currWB); } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 2375d7cfd..9363c84cb 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -193,7 +193,7 @@ int StdImageSource::load (const Glib::ustring &fname) return 0; } -void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed) +void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { // the code will use OpenMP as of now. diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 866e90b99..8c2a54a3b 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -58,7 +58,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, int opposed) 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 {}; ColorTemp getWB () const override { diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index f5ed63b37..f72f3bc51 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -246,10 +246,10 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC } auto m = ProcEventMapper::getInstance(); - EvWBObserver10 = m->newEvent(ALLNORAW, "HISTORY_MSG_WBALANCE_OBSERVER10"); - EvWBitcwbprim = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_PRIM"); - EvWBitcwbalg = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_OBS"); - EvWBitcwgreen = m->newEvent(ALLNORAW, "HISTORY_MSG_WBITC_GREEN"); + EvWBObserver10 = m->newEvent(WB, "HISTORY_MSG_WBALANCE_OBSERVER10"); + EvWBitcwbprim = m->newEvent(WB, "HISTORY_MSG_WBITC_PRIM"); + EvWBitcwbalg = m->newEvent(WB, "HISTORY_MSG_WBITC_OBS"); + EvWBitcwgreen = m->newEvent(WB, "HISTORY_MSG_WBITC_GREEN"); //Add the model columns to the Combo (which is a kind of view), From 3d5810f0887fcccced2b219eaebf14259a7ba18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Sat, 19 Aug 2023 00:17:10 +0200 Subject: [PATCH 318/326] Applied requested changes from review comments --- rtgui/filmnegative.cc | 44 +++++++++++-------------------------------- rtgui/filmnegative.h | 19 ++----------------- rtgui/guiutils.cc | 33 +++++++++++++------------------- rtgui/guiutils.h | 22 +++++++++++++++++----- 4 files changed, 43 insertions(+), 75 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index f21ed8d9f..66002e23c 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -212,7 +212,7 @@ FilmNegative::FilmNegative() : picker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_PICK"), M("TP_FILMNEGATIVE_GUESS_TOOLTIP"), M("TP_FILMNEGATIVE_PICK_SIZE")), refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), refPicker(DEFAULT_SPOT_WIDTH, M("TP_FILMNEGATIVE_REF_PICK"), M("TP_FILMNEGATIVE_REF_TOOLTIP"), M("TP_FILMNEGATIVE_REF_SIZE")), - displayRectWidth(&(picker._associatedVar)), + activePicker(&picker), 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 @@ -242,9 +242,6 @@ FilmNegative::FilmNegative() : pack_start(*redRatio, Gtk::PACK_SHRINK, 0); pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); pack_start(picker, Gtk::PACK_SHRINK, 0); - // pack_start(*spotButton, Gtk::PACK_SHRINK, 0); - - // pack_start(*oldMethod, Gtk::PACK_SHRINK, 0); Gtk::Separator* const sep = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); sep->get_style_context()->add_class("grid-row-separator"); @@ -262,9 +259,8 @@ FilmNegative::FilmNegative() : pack_start(refPicker, Gtk::PACK_SHRINK, 0); - picker._spotButton.signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); - - refPicker._spotButton.signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::refSpotToggled)); + picker.add_button_toggled_event(*this, &FilmNegative::editToggled); + refPicker.add_button_toggled_event(*this, &FilmNegative::refSpotToggled); // Editing geometry; create the spot rectangle // TODO: Change behaviour to match that of the white balance spot picker (rectangle disappears behind right toolbar) @@ -432,8 +428,8 @@ void FilmNegative::setBatchMode(bool batchMode) ToolPanel::setBatchMode(batchMode); if (batchMode) { - removeIfThere(this, &picker._spotButton, false); - removeIfThere(this, &refPicker._spotButton, false); + picker.remove_if_there(this, false); + refPicker.remove_if_there(this, false); colorSpace->append(M("GENERAL_UNCHANGED")); colorSpace->set_active_text(M("GENERAL_UNCHANGED")); redRatio->showEditedCB(); @@ -542,7 +538,7 @@ bool FilmNegative::mouseOver(int modifierKey) { EditDataProvider* const provider = getEditProvider(); Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); - spotRect->setXYWH(provider->posImage.x - *displayRectWidth, provider->posImage.y - *displayRectWidth, *displayRectWidth * 2, *displayRectWidth * 2); + spotRect->setXYWH(provider->posImage.x - activePicker->get_spot_half_width(), provider->posImage.y - activePicker->get_spot_half_width() ,activePicker->get_spot_half_width() * 2, activePicker->get_spot_half_width() * 2); return true; } @@ -564,8 +560,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker._associatedVar, ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], picker._associatedVar, ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker.get_spot_half_width(), ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], picker.get_spot_half_width(), ref2, dummy)) { disableListener(); @@ -611,7 +607,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, refPicker._associatedVar, refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refPicker.get_spot_half_width(), refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); @@ -685,9 +681,7 @@ void FilmNegative::editToggled() refPicker.set_active(false); refSpotCoords.clear(); - displayRectWidth = &(picker._associatedVar); - // if (spotlistener) - // spotlistener->spotNegRequested(spotWidth); + activePicker = &picker; subscribe(); @@ -711,9 +705,7 @@ void FilmNegative::refSpotToggled() picker.set_active(false); refSpotCoords.clear(); - displayRectWidth = &(refPicker._associatedVar); - // if (spotlistener) - // spotlistener->spotNegRequested(refSpotWidth); + activePicker = &refPicker; subscribe(); @@ -731,17 +723,3 @@ void FilmNegative::refSpotToggled() } } -// void FilmNegative::spotSizeChanged () -// { -// spotWidth = atoi(spotSize->get_active_text().c_str()); - -// // if (spotlistener) -// // spotlistener->spotNegRequested(spotWidth); -// } - -// void FilmNegative::refSpotChanged() -// { -// refSpotWidth = atoi(refSpotSize->get_active_text().c_str()); -// // if (spotlistener) -// // spotlistener->spotNegRequested(refSpotWidth); -// } diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 02d032f3c..87e91af8c 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -43,12 +43,6 @@ public: virtual bool getFilmNegativeSpot(rtengine::Coord spot, int spotSize, RGB &refInput, RGB &refOutput) = 0; }; -// class FilmNegSpotListener -// { -// public: -// virtual ~FilmNegSpotListener() = default; -// virtual void spotNegRequested(int size) = 0; -// }; class FilmNegative final : public ToolParamBlock, @@ -85,10 +79,6 @@ public: bool button1Released() override; bool button3Pressed(int modifierKey) override; void switchOffEditMode() override; - // void setFilmNegSpotListener(FilmNegSpotListener* listener) - // { - // spotlistener = listener; - // } private: void editToggled(); @@ -97,9 +87,6 @@ private: void readOutputSliders(RGB &refOutput); void writeOutputSliders(const RGB &refOutput); - // void spotSizeChanged(); - // void refSpotChanged(); - // ColorTemp value corresponding to neutral RGB multipliers (1,1,1). Should be around 6500K. const rtengine::ColorTemp NEUTRAL_TEMP; @@ -109,8 +96,6 @@ private: const rtengine::ProcEvent evFilmNegativeBalance; const rtengine::ProcEvent evFilmNegativeColorSpace; - // FilmNegSpotListener* spotlistener; - std::vector refSpotCoords; RGB refInputValues; @@ -135,14 +120,14 @@ private: Adjuster* const redRatio; Adjuster* const blueRatio; - #define DEFAULT_SPOT_WIDTH 8 + static constexpr int DEFAULT_SPOT_WIDTH = 8; SpotPicker picker; Gtk::Label* const refInputLabel; SpotPicker refPicker; - int* displayRectWidth; + SpotPicker* activePicker; Adjuster* const outputLevel; Adjuster* const greenBalance; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index e3e52fc23..7d65b9e46 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1926,32 +1926,25 @@ void BackBuffer::copySurface(Cairo::RefPtr crDest, Gdk::Rectangl SpotPicker::SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey) : Gtk::Grid(), - _associatedVar(defaultValue), + _spotHalfWidth(defaultValue), _spotLabel(labelSetup(labelKey)), - _spotSizeSetter(new MyComboBoxText(selecterSetup())), + _spotSizeSetter(MyComboBoxText(selecterSetup())), _spotButton(spotButtonTemplate(buttonKey, buttonTooltip)) { - Gtk::Grid* spotSizeHelper = new Gtk::Grid(); - spotSizeHelper->set_name("Spot-Size-Helper"); - setExpandAlignProperties(spotSizeHelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - this->get_style_context()->add_class("grid-spacing"); setExpandAlignProperties(this, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - spotSizeHelper->attach (*_spotSizeSetter, 0, 0, 1, 1); - this->attach (_spotButton, 0, 0, 1, 1); this->attach (_spotLabel, 1, 0, 1, 1); - this->attach (*spotSizeHelper, 2, 0, 1, 1); - _spotSizeSetter->signal_changed().connect( sigc::mem_fun(*this, &SpotPicker::spotSizeChanged)); + this->attach (_spotSizeSetter, 2, 0, 1, 1); + _spotSizeSetter.signal_changed().connect( sigc::mem_fun(*this, &SpotPicker::spotSizeChanged)); } SpotPicker::~SpotPicker() { - delete _spotSizeSetter; } -Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) +Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) const { Gtk::Label label(key); setExpandAlignProperties(&label, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -1961,34 +1954,34 @@ Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) MyComboBoxText SpotPicker::selecterSetup() { MyComboBoxText spotSize = MyComboBoxText(); - setExpandAlignProperties(&spotSize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(&spotSize, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); spotSize.append ("2"); - if (_associatedVar == 2) { + if (_spotHalfWidth == 2) { spotSize.set_active(0); } spotSize.append ("4"); - if (_associatedVar == 4) { + if (_spotHalfWidth == 4) { spotSize.set_active(1); } spotSize.append ("8"); - if (_associatedVar == 8) { + if (_spotHalfWidth == 8) { spotSize.set_active(2); } spotSize.append ("16"); - if (_associatedVar == 16) { + if (_spotHalfWidth == 16) { spotSize.set_active(3); } spotSize.append ("32"); - if (_associatedVar == 32) { + if (_spotHalfWidth == 32) { spotSize.set_active(4); } return spotSize; @@ -2006,5 +1999,5 @@ Gtk::ToggleButton SpotPicker::spotButtonTemplate(Glib::ustring const &key, const void SpotPicker::spotSizeChanged() { - _associatedVar = atoi(_spotSizeSetter->get_active_text().c_str()); -} \ No newline at end of file + _spotHalfWidth = atoi(_spotSizeSetter.get_active_text().c_str()); +} diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 77cbdbd93..48ccb5e60 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -694,12 +694,12 @@ public: */ class SpotPicker : public Gtk::Grid { - public: - int _associatedVar; + private: + int _spotHalfWidth; Gtk::Label _spotLabel; - MyComboBoxText* const _spotSizeSetter; + MyComboBoxText _spotSizeSetter; Gtk::ToggleButton _spotButton; - + public: SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); ~SpotPicker(); inline bool get_active() @@ -710,9 +710,21 @@ class SpotPicker : public Gtk::Grid { _spotButton.set_active(b); } + int get_spot_half_width() + { + return _spotHalfWidth; + } + template void add_button_toggled_event(T_return& returnv, const T_obj function) + { + _spotButton.signal_toggled().connect(sigc::mem_fun(returnv, function)); + } + bool remove_if_there(Gtk::Container* cont, bool increference = true) + { + return removeIfThere(cont, &_spotButton, increference); + } protected: - static Gtk::Label labelSetup(Glib::ustring const &key); + Gtk::Label labelSetup(Glib::ustring const &key) const; MyComboBoxText selecterSetup(); static Gtk::ToggleButton spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip); void spotSizeChanged(); From af22f4195d67395cc3ba6a130e905629224e4380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:29:49 +0200 Subject: [PATCH 319/326] Removed empty destructor --- rtgui/guiutils.cc | 3 --- rtgui/guiutils.h | 1 - 2 files changed, 4 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 047536f3e..7e36441fb 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1981,9 +1981,6 @@ SpotPicker::SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, G this->attach (_spotSizeSetter, 2, 0, 1, 1); _spotSizeSetter.signal_changed().connect( sigc::mem_fun(*this, &SpotPicker::spotSizeChanged)); } -SpotPicker::~SpotPicker() -{ -} Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) const { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 2a7e7d089..9683899f0 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -728,7 +728,6 @@ class SpotPicker : public Gtk::Grid Gtk::ToggleButton _spotButton; public: SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); - ~SpotPicker(); inline bool get_active() { return _spotButton.get_active(); From 6b6200314f1ba54af9fe5f0b452eb7d191642893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:38:24 +0200 Subject: [PATCH 320/326] Member functions changed to const The following member functions and methods of SpotPicker changed to const: - get_active() - get_spot_half_width() - selecterSetup() - spotButtonTemplate(). --- rtgui/guiutils.cc | 4 ++-- rtgui/guiutils.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 7e36441fb..cb99b04a5 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1989,7 +1989,7 @@ Gtk::Label SpotPicker::labelSetup(Glib::ustring const &key) const return label; } -MyComboBoxText SpotPicker::selecterSetup() +MyComboBoxText SpotPicker::selecterSetup() const { MyComboBoxText spotSize = MyComboBoxText(); setExpandAlignProperties(&spotSize, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -2025,7 +2025,7 @@ MyComboBoxText SpotPicker::selecterSetup() return spotSize; } -Gtk::ToggleButton SpotPicker::spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) +Gtk::ToggleButton SpotPicker::spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) const { Gtk::ToggleButton spotButton = Gtk::ToggleButton(key); setExpandAlignProperties(&spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 9683899f0..221a56814 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -728,7 +728,7 @@ class SpotPicker : public Gtk::Grid Gtk::ToggleButton _spotButton; public: SpotPicker(int const defaultValue, Glib::ustring const &buttonKey, Glib::ustring const &buttonTooltip, Glib::ustring const &labelKey); - inline bool get_active() + inline bool get_active() const { return _spotButton.get_active(); } @@ -736,7 +736,7 @@ class SpotPicker : public Gtk::Grid { _spotButton.set_active(b); } - int get_spot_half_width() + int get_spot_half_width() const { return _spotHalfWidth; } @@ -751,8 +751,8 @@ class SpotPicker : public Gtk::Grid protected: Gtk::Label labelSetup(Glib::ustring const &key) const; - MyComboBoxText selecterSetup(); - static Gtk::ToggleButton spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip); + MyComboBoxText selecterSetup() const; + Gtk::ToggleButton spotButtonTemplate(Glib::ustring const &key, const Glib::ustring &tooltip) const; void spotSizeChanged(); }; From 75541d6281f7d706bf4d0d3079fd6856fc62abe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Batty=C3=A1nyi?= <86350313+LoKolbasz@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:59:42 +0200 Subject: [PATCH 321/326] Changes to get the full spot width where needed --- rtgui/filmnegative.cc | 8 ++++---- rtgui/guiutils.h | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 4c1692bf1..e9c9f4d4c 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -538,7 +538,7 @@ bool FilmNegative::mouseOver(int modifierKey) { EditDataProvider* const provider = getEditProvider(); EditRectangle* const spotRect = static_cast(visibleGeometry.at(0)); - spotRect->setXYWH(provider->posImage.x - activePicker->get_spot_half_width(), provider->posImage.y - activePicker->get_spot_half_width() ,activePicker->get_spot_half_width() * 2, activePicker->get_spot_half_width() * 2); + spotRect->setXYWH(provider->posImage.x - activePicker->get_spot_half_width(), provider->posImage.y - activePicker->get_spot_half_width() ,activePicker->get_spot_full_width(), activePicker->get_spot_full_width()); return true; } @@ -560,8 +560,8 @@ bool FilmNegative::button1Pressed(int modifierKey) RGB ref1, ref2, dummy; - if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker.get_spot_half_width(), ref1, dummy) && - fnp->getFilmNegativeSpot(refSpotCoords[1], picker.get_spot_half_width(), ref2, dummy)) { + if (fnp->getFilmNegativeSpot(refSpotCoords[0], picker.get_spot_full_width(), ref1, dummy) && + fnp->getFilmNegativeSpot(refSpotCoords[1], picker.get_spot_full_width(), ref2, dummy)) { disableListener(); @@ -607,7 +607,7 @@ bool FilmNegative::button1Pressed(int modifierKey) } RGB refOut; - fnp->getFilmNegativeSpot(provider->posImage, refPicker.get_spot_half_width(), refInputValues, refOut); + fnp->getFilmNegativeSpot(provider->posImage, refPicker.get_spot_full_width(), refInputValues, refOut); // Output luminance of the sampled spot float spotLum = rtengine::Color::rgbLuminance(refOut.r, refOut.g, refOut.b); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 221a56814..02811e076 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -740,6 +740,10 @@ class SpotPicker : public Gtk::Grid { return _spotHalfWidth; } + int get_spot_full_width() const + { + return _spotHalfWidth * 2; + } template void add_button_toggled_event(T_return& returnv, const T_obj function) { _spotButton.signal_toggled().connect(sigc::mem_fun(returnv, function)); From e6a2654241978c17f1f0277fa375382fbfe6e420 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 27 Aug 2023 16:32:30 -0700 Subject: [PATCH 322/326] Show "unchanged" in batch profiled lens correction --- rtgui/lensprofile.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 65c962b7b..56d3474d4 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -441,6 +441,7 @@ void LensProfilePanel::setBatchMode(bool yes) modesGrid->attach_next_to(*corrUnchangedRB, Gtk::POS_TOP, 3, 1); corrUnchangedRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrUnchangedRB)); corrUnchangedRB->set_active(true); + corrUnchangedRB->show(); } void LensProfilePanel::onLensfunCameraChanged() From f0b282a69587453ae396ce0cfd1f140310cc1e38 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 28 Aug 2023 09:32:43 -0700 Subject: [PATCH 323/326] Create findATOMIC.cmake Provided by @Floessie https://github.com/Beep6581/RawTherapee/issues/6821#issuecomment-1678626624 --- cmake/modules/findATOMIC.cmake | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 cmake/modules/findATOMIC.cmake diff --git a/cmake/modules/findATOMIC.cmake b/cmake/modules/findATOMIC.cmake new file mode 100644 index 000000000..1669983c3 --- /dev/null +++ b/cmake/modules/findATOMIC.cmake @@ -0,0 +1,36 @@ +include(CheckCXXSourceCompiles) + +set(ATOMIC_CXX_TEST_SOURCE +" +#include +int main() { + std::atomic b(false); + std::atomic i(0); + std::atomic ui(0); + b.exchange(true); + ++i; + return ++ui; +} +") + +set(SAFE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") +list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "atomic") + +check_cxx_source_compiles("${ATOMIC_CXX_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITHOUT_LIB) + +if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_cxx_source_compiles("${ATOMIC_CXX_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITH_LIB) + if (NOT HAVE_CXX_ATOMICS_WITH_LIB) + message(FATAL_ERROR "libatomic support needed for std::atomic<> but not +found.") + endif() + set(ATOMIC_LIBRARIES "atomic") + set(ATOMIC_FOUND ON) +endif() + +set(CMAKE_REQUIRED_LIBRARIES "${SAFE_CMAKE_REQUIRED_LIBRARIES}") +unset(SAFE_CMAKE_REQUIRED_LIBRARIES) + +mark_as_advanced(ATOMIC_LIBRARIES) +mark_as_advanced(ATOMIC_FOUND) From ea33323d188a80a11169710b7461b95b91080947 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 28 Aug 2023 09:37:08 -0700 Subject: [PATCH 324/326] Call findATOMIC.cmake libatomic is required in some builds. see #6821 --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e33d28cf..6f1bc382e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -565,6 +565,12 @@ if(WITH_MYFILE_MMAP) add_definitions(-DMYFILE_MMAP) endif() +# Atomic is required in some builds: #6821 +find_package(ATOMIC) +if(ATOMIC_FOUND) + target_link_libraries(executable ${ATOMIC_LIBRARIES}) +endif() + if(WITH_LTO) # Using LTO with older versions of binutils requires setting extra flags set(BINUTILS_VERSION_MININUM "2.29") From 7a5931135ed55c5f443dff90d9b2c26e3e8285fb Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 28 Aug 2023 09:43:09 -0700 Subject: [PATCH 325/326] handle libatomic in cmake module cmake/modules/findATOMIC.cmake detects libatomic flags. see #6821 --- rtgui/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index fb4acbe42..592b816a0 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -251,9 +251,10 @@ else() endif() # Excluding libatomic needed by Clang/FreeBSD, #3636 -if(OPENMP_FOUND AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - set(EXTRA_LIB_RTGUI "${EXTRA_LIB_RTGUI}" "atomic") -endif() +# Now handled in cmake/modules/findATOMIC.cmake, #6821 +# if(OPENMP_FOUND AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") +# set(EXTRA_LIB_RTGUI "${EXTRA_LIB_RTGUI}" "atomic") +# endif() # Create config.h which defines where data are stored configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h") From d6f102100b6a1d9ceebba18d07520b1dfb566bda Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Mon, 28 Aug 2023 10:06:59 -0700 Subject: [PATCH 326/326] Rename findATOMIC.cmake to FindATOMIC.cmake --- cmake/modules/{findATOMIC.cmake => FindATOMIC.cmake} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cmake/modules/{findATOMIC.cmake => FindATOMIC.cmake} (100%) diff --git a/cmake/modules/findATOMIC.cmake b/cmake/modules/FindATOMIC.cmake similarity index 100% rename from cmake/modules/findATOMIC.cmake rename to cmake/modules/FindATOMIC.cmake