From 8239c9d468f1ce0ffc400763cc1d84d7e8cb6251 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 19 Aug 2025 16:38:18 -0400 Subject: [PATCH] Fix checksum generation and add tests We want to confirm that we can load Ids from the icc profile AND be able to generate the same ID from the file's data which is the same as the an ID that would be in the file. --- src/colors/cms/profile.cpp | 22 ++++++++++++++++------ src/colors/cms/profile.h | 2 ++ testfiles/src/colors/cms-test.cpp | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/colors/cms/profile.cpp b/src/colors/cms/profile.cpp index 9c4f83616c..87abb6786b 100644 --- a/src/colors/cms/profile.cpp +++ b/src/colors/cms/profile.cpp @@ -283,11 +283,11 @@ bool Profile::isIccFile(std::string const &filepath) } /** - * Get or generate a profile Id, and save in the object for later use. + * Get the id from the cms header itself, ususally correct but sometimes will be + * completely empty. Use generate_checksum to make a new one. */ -std::string Profile::generate_id() const +std::string Profile::get_id() const { - // 1. get the id from the cms header itself, ususally correct. cmsUInt8Number tmp[16]; cmsGetHeaderProfileID(_handle, tmp); @@ -297,13 +297,21 @@ std::string Profile::generate_id() const // Setw must happen each loop oo << std::setw(2) << static_cast(digit); } + return oo.str(); +} + +/** + * Get or generate a profile Id, and save in the object for later use. + */ +std::string Profile::generate_id() const +{ + auto s = get_id(); #ifdef __APPLE__ - auto s = oo.str(); if (std::count_if(s.begin(), s.end(), [](char c){ return c == '0'; }) < 24) #else - if (std::ranges::count(oo.str(), '0') < 24) + if (std::ranges::count(s, '0') < 24) #endif - return oo.str(); // Done + return s; // Done // If there's no path, then what we have is a generated or in-memory profile // which is unlikely to ever need to be matched with anything via id but it's // also true that this id would change between computers, and creation date. @@ -326,6 +334,8 @@ std::string Profile::generate_checksum() const return "~"; } // Zero out the required bytes as per the above specification + for (unsigned i = 44; i < 48; i++) + data[i] = 0; for (unsigned i = 64; i < 68; i++) data[i] = 0; for (unsigned i = 84; i < 100; i++) diff --git a/src/colors/cms/profile.h b/src/colors/cms/profile.h index 09f266805a..79133b8b7f 100644 --- a/src/colors/cms/profile.h +++ b/src/colors/cms/profile.h @@ -71,6 +71,8 @@ private: std::string _checksum; bool _in_home = false; +public: + std::string get_id() const; std::string generate_id() const; std::string generate_checksum() const; }; diff --git a/testfiles/src/colors/cms-test.cpp b/testfiles/src/colors/cms-test.cpp index de29d5b2a0..3d28e87a6b 100644 --- a/testfiles/src/colors/cms-test.cpp +++ b/testfiles/src/colors/cms-test.cpp @@ -230,6 +230,20 @@ TEST(ColorCmsProfile, cmsDumpBase64) "AAA9aGxjbXMEMAAAbW50clJHQiBYWVogB+YAAgAWAA0AGQAuYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEA"); } +TEST(ColorCmsProfile, cmsGenerateId) +{ + auto profile = CMS::Profile::create_from_uri(cmyk_profile); + + EXPECT_EQ(profile->get_id(), "00000000000000000000000000000000"); + EXPECT_EQ(profile->generate_id(), "f9185275b4d6bcee53bc48dddb70fce5"); + EXPECT_EQ(profile->generate_checksum(), "f9185275b4d6bcee53bc48dddb70fce5"); + + profile = CMS::Profile::create_from_uri(grb_profile); + EXPECT_EQ(profile->get_id(), "f9eda5a42a222a28f0adb82a938eeb0e"); + EXPECT_EQ(profile->generate_id(), "f9eda5a42a222a28f0adb82a938eeb0e"); + EXPECT_EQ(profile->generate_checksum(), "f9eda5a42a222a28f0adb82a938eeb0e"); +} + // ================= CMS::Transform ================= // TEST(ColorCmsTransform, applyTransformColor) -- GitLab