diff options
author | Nico Weber <thakis@chromium.org> | 2023-01-04 15:34:25 -0500 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-01-05 10:54:35 +0100 |
commit | 68f678f566b533396a9c629784289ae3653f40ed (patch) | |
tree | 1550af72430c3adc918e7ef55afd135b9b5be019 /Userland | |
parent | fafacbb87b0acf48420a3e6d5e2e3793f037956e (diff) | |
download | serenity-68f678f566b533396a9c629784289ae3653f40ed.zip |
LibGfx+icc: Print if profile id is valid
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGfx/ICCProfile.cpp | 24 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/ICCProfile.h | 2 | ||||
-rw-r--r-- | Userland/Utilities/icc.cpp | 11 |
3 files changed, 34 insertions, 3 deletions
diff --git a/Userland/Libraries/LibGfx/ICCProfile.cpp b/Userland/Libraries/LibGfx/ICCProfile.cpp index e8a4098563..bcdb839c60 100644 --- a/Userland/Libraries/LibGfx/ICCProfile.cpp +++ b/Userland/Libraries/LibGfx/ICCProfile.cpp @@ -248,6 +248,9 @@ Optional<Crypto::Hash::MD5::DigestType> parse_profile_id(ICCHeader const& header Crypto::Hash::MD5::DigestType md5; static_assert(sizeof(md5.data) == sizeof(header.profile_md5)); memcpy(md5.data, header.profile_md5, sizeof(md5.data)); + + // FIXME: Consider comparing read id with compute_id() result and failing if they aren't equal. + return md5; } } @@ -386,4 +389,25 @@ ErrorOr<NonnullRefPtr<Profile>> Profile::try_load_from_externally_owned_memory(R return profile; } +Crypto::Hash::MD5::DigestType Profile::compute_id(ReadonlyBytes bytes) +{ + // ICC v4, 7.2.18 Profile ID field + // The Profile ID shall be calculated using the MD5 fingerprinting method as defined in Internet RFC 1321. + // The entire profile, whose length is given by the size field in the header, + // with the profile flags field (bytes 44 to 47, see 7.2.11), + // rendering intent field (bytes 64 to 67, see 7.2.15), + // and profile ID field (bytes 84 to 99) in the profile header + // temporarily set to zeros (00h), shall be used to calculate the ID. + const u8 zero[16] = {}; + Crypto::Hash::MD5 md5; + md5.update(bytes.slice(0, 44)); + md5.update(ReadonlyBytes { zero, 4 }); // profile flags field + md5.update(bytes.slice(48, 64 - 48)); + md5.update(ReadonlyBytes { zero, 4 }); // rendering intent field + md5.update(bytes.slice(68, 84 - 68)); + md5.update(ReadonlyBytes { zero, 16 }); // profile ID field + md5.update(bytes.slice(100)); + return md5.digest(); +} + } diff --git a/Userland/Libraries/LibGfx/ICCProfile.h b/Userland/Libraries/LibGfx/ICCProfile.h index 2d85bd4dcd..e4e0140699 100644 --- a/Userland/Libraries/LibGfx/ICCProfile.h +++ b/Userland/Libraries/LibGfx/ICCProfile.h @@ -139,6 +139,8 @@ public: XYZ const& pcs_illuminant() const { return m_pcs_illuminant; } Optional<Crypto::Hash::MD5::DigestType> const& id() const { return m_id; } + static Crypto::Hash::MD5::DigestType compute_id(ReadonlyBytes); + private: Version m_version; DeviceClass m_device_class; diff --git a/Userland/Utilities/icc.cpp b/Userland/Utilities/icc.cpp index 6c67b7fec1..67d0ced9d9 100644 --- a/Userland/Utilities/icc.cpp +++ b/Userland/Utilities/icc.cpp @@ -40,9 +40,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) outln("pcs illuminant: {}", profile->pcs_illuminant()); out("id: "); - if (auto id = profile->id(); id.has_value()) - outln("{}", *id); - else + if (auto id = profile->id(); id.has_value()) { + out("{}", *id); + auto computed = Gfx::ICC::Profile::compute_id(icc_file->bytes()); + if (*id == computed) + outln(" (valid)"); + else + outln(" (invalid! valid would be {})", computed); + } else outln("(not set)"); return 0; |