diff --git a/rtdata/dcpprofiles/camera_model_aliases.json b/rtdata/dcpprofiles/camera_model_aliases.json new file mode 100644 index 000000000..66297a853 --- /dev/null +++ b/rtdata/dcpprofiles/camera_model_aliases.json @@ -0,0 +1,30 @@ +{ + "Canon EOS 100D": ["Canon EOS Kiss X7", "Canon EOS REBEL SL1"], + "Canon EOS 200D": ["Canon EOS Kiss X9", "Canon EOS Rebel SL2"], + "Canon EOS 300D": ["Canon EOS Kiss Digital", "Canon EOS Digital Rebel"], + "Canon EOS 350D": ["Canon EOS 350D DIGITAL", "Canon EOS Kiss Digital N", "Canon EOS DIGITAL REBEL XT"], + "Canon EOS 400D": ["Canon EOS 400D DIGITAL", "Canon EOS Kiss Digital X", "Canon EOS DIGITAL REBEL XTi"], + "Canon EOS 450D": ["Canon EOS Kiss Digital X2", "Canon EOS Kiss X2", "Canon EOS DIGITAL REBEL XSi"], + "Canon EOS 500D": ["Canon EOS Kiss X3", "Canon EOS REBEL T1i"], + "Canon EOS 550D": ["Canon EOS Kiss X4", "Canon EOS REBEL T2i"], + "Canon EOS 600D": ["Canon EOS Kiss X5", "Canon EOS REBEL T3i"], + "Canon EOS 650D": ["Canon EOS Kiss X6i", "Canon EOS REBEL T4i"], + "Canon EOS 700D": ["Canon EOS Kiss X7i", "Canon EOS REBEL T5i"], + "Canon EOS 750D": ["Canon EOS Kiss X8i", "Canon EOS Rebel T6i"], + "Canon EOS 760D": ["Canon EOS 8000D", "Canon EOS Rebel T6s"], + "Canon EOS 800D": ["Canon EOS Kiss X9i", "Canon EOS Rebel T7i"], + "Canon EOS 1000D": ["Canon EOS Kiss Digital F", "Canon EOS DIGITAL REBEL XS"], + "Canon EOS 1200D": ["Canon EOS Kiss X70", "Canon EOS REBEL T5"], + "Canon EOS 1300D": ["Canon EOS Kiss X80", "Canon EOS Rebel T6"], + + "MINOLTA DYNAX 5D": ["Minolta Maxxum 5D", "Minolta Alpha 5D", "Minolta Alpha Sweet"], + "MINOLTA DYNAX 7D": ["Minolta Maxxum 7D", "Minolta Alpha 7D"], + + "Panasonic DC-FZ82": ["Panasonic DMC-FZ80", "Panasonic DMC-FZ85"], + "Panasonic DC-TZ90": ["Panasonic DC-ZS70", "Panasonic DC-FZ91", "Panasonic DC-FZ92", "Panasonic DC-FZ93"], + "Panasonic DMC-G8": ["Panasonic DMC-G80", "Panasonic DMC-G81", "Panasonic DMC-G85"], + "Panasonic DMC-LX15": ["Panasonic DMC-LX9", "Panasonic DMC-LX10"], + "Panasonic DC-TZ100": ["Panasonic DC-ZS100", "Panasonic DC-ZS110", "Panasonic DC-TZ101", "Panasonic DC-TZ110"], + "Panasonic DMC-TZ71": ["Panasonic DMC-TZ70", "Panasonic DMC-ZS50"], + "Panasonic DMC-TZ81": ["Panasonic DMC-TZ80", "Panasonic DMC-TZ85", "Panasonic DMC-ZS60"] +} diff --git a/rtdata/dcpprofiles/camera_model_aliases.txt b/rtdata/dcpprofiles/camera_model_aliases.txt deleted file mode 100644 index 4dea42628..000000000 --- a/rtdata/dcpprofiles/camera_model_aliases.txt +++ /dev/null @@ -1,3 +0,0 @@ -Canon EOS 600D;Canon EOS Kiss X5;Canon EOS Rebel T3i -Canon EOS 1300D;Canon EOS Kiss X80;Canon EOS Rebel T6 -MINOLTA DYNAX 7D;MINOLTA MAXXUM 7D;MINOLTA ALPHA 7D;MINOLTA ALPHA SWEET diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index fe798cb99..164c7680e 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -18,15 +18,26 @@ */ #include +#include #include +#include #include "dcp.h" + +#include "cJSON.h" #include "iccmatrices.h" #include "iccstore.h" -#include "rawimagesource.h" #include "improcfun.h" +#include "rawimagesource.h" #include "rt_math.h" +namespace rtengine +{ + +extern const Settings* settings; + +} + using namespace rtengine; using namespace rtexif; @@ -42,7 +53,7 @@ DCPProfile::Matrix invert3x3(const DCPProfile::Matrix& a) std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl; } return res; - + // const double res00 = a[1][1] * a[2][2] - a[2][1] * a[1][2]; // const double res10 = a[2][0] * a[1][2] - a[1][0] * a[2][2]; // const double res20 = a[1][0] * a[2][1] - a[2][0] * a[1][1]; @@ -382,6 +393,57 @@ double xyCoordToTemperature(const std::array& white_xy) return res; } +std::map getAliases(const Glib::ustring& profile_dir) +{ + const std::unique_ptr> file( + g_fopen(Glib::build_filename(profile_dir, "camera_model_aliases.json").c_str(), "rb"), + [](std::FILE* file) + { + std::fclose(file); + } + ); + + if (!file) { + return {}; + } + + std::fseek(file.get(), 0, SEEK_END); + const long length = std::ftell(file.get()); + if (length <= 0) { + return {}; + } + + std::unique_ptr buffer(new char[length + 1]); + std::fseek(file.get(), 0, SEEK_SET); + const std::size_t read = std::fread(buffer.get(), 1, length, file.get()); + buffer[read] = 0; + + cJSON_Minify(buffer.get()); + const std::unique_ptr root(cJSON_Parse(buffer.get())); + if (!root || !root->child) { + if (settings->verbose) { + std::cout << "Could not parse 'camera_model_aliases.json' file." << std::endl; + } + return {}; + } + + std::map res; + + for (const cJSON* camera = root->child; camera; camera = camera->next) { + if (cJSON_IsArray(camera)) { + const std::size_t array_size = cJSON_GetArraySize(camera); + for (std::size_t index = 0; index < array_size; ++index) { + const cJSON* const alias = cJSON_GetArrayItem(camera, index); + if (cJSON_IsString(alias)) { + res[alias->valuestring] = camera->string; + } + } + } + } + + return res; +} + } struct DCPProfile::ApplyState::Data { @@ -953,9 +1015,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : valid = true; } -DCPProfile::~DCPProfile() -{ -} +DCPProfile::~DCPProfile() = default; DCPProfile::operator bool() const { @@ -1203,7 +1263,7 @@ void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int float cnewr = FCLIP(newr); float cnewg = FCLIP(newg); float cnewb = FCLIP(newb); - + float h, s, v; Color::rgb2hsvdcp(cnewr, cnewg, cnewb, h, s, v); @@ -1721,7 +1781,6 @@ DCPStore* DCPStore::getInstance() return &instance; } - DCPStore::~DCPStore() { for (auto &p : profile_cache) { @@ -1729,7 +1788,6 @@ DCPStore::~DCPStore() } } - void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) { MyMutex::MyLock lock(mutex); @@ -1748,7 +1806,7 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) while (!dirs.empty()) { // Process directory - Glib::ustring dirname = dirs.back(); + const Glib::ustring dirname = dirs.back(); dirs.pop_back(); std::unique_ptr dir; @@ -1784,6 +1842,16 @@ 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); + + if (real != file_std_profiles.end()) { + file_std_profiles[alias_name] = real->second; + } + } } }