mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:37:46 +00:00
icc: Print if a curve looks like the sRGB curve
This commit is contained in:
parent
fe8c0292ad
commit
6c7b3c56f2
1 changed files with 67 additions and 0 deletions
|
@ -74,6 +74,39 @@ static void out_parametric_curve(Gfx::ICC::ParametricCurveTagData const& paramet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float curve_distance_u8(Gfx::ICC::TagData const& tag1, Gfx::ICC::TagData const& tag2)
|
||||||
|
{
|
||||||
|
VERIFY(tag1.type() == Gfx::ICC::CurveTagData::Type || tag1.type() == Gfx::ICC::ParametricCurveTagData::Type);
|
||||||
|
VERIFY(tag2.type() == Gfx::ICC::CurveTagData::Type || tag2.type() == Gfx::ICC::ParametricCurveTagData::Type);
|
||||||
|
|
||||||
|
float curve1_data[256];
|
||||||
|
if (tag1.type() == Gfx::ICC::CurveTagData::Type) {
|
||||||
|
auto& curve1 = static_cast<Gfx::ICC::CurveTagData const&>(tag1);
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
curve1_data[i] = curve1.evaluate(i / 255.f);
|
||||||
|
} else {
|
||||||
|
auto& parametric_curve1 = static_cast<Gfx::ICC::ParametricCurveTagData const&>(tag1);
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
curve1_data[i] = parametric_curve1.evaluate(i / 255.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float curve2_data[256];
|
||||||
|
if (tag2.type() == Gfx::ICC::CurveTagData::Type) {
|
||||||
|
auto& curve2 = static_cast<Gfx::ICC::CurveTagData const&>(tag2);
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
curve2_data[i] = curve2.evaluate(i / 255.f);
|
||||||
|
} else {
|
||||||
|
auto& parametric_curve2 = static_cast<Gfx::ICC::ParametricCurveTagData const&>(tag2);
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
curve2_data[i] = parametric_curve2.evaluate(i / 255.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance = 0;
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
distance += fabsf(curve1_data[i] - curve2_data[i]);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
static ErrorOr<void> out_curve_tag(Gfx::ICC::TagData const& tag, int indent_amount)
|
static ErrorOr<void> out_curve_tag(Gfx::ICC::TagData const& tag, int indent_amount)
|
||||||
{
|
{
|
||||||
VERIFY(tag.type() == Gfx::ICC::CurveTagData::Type || tag.type() == Gfx::ICC::ParametricCurveTagData::Type);
|
VERIFY(tag.type() == Gfx::ICC::CurveTagData::Type || tag.type() == Gfx::ICC::ParametricCurveTagData::Type);
|
||||||
|
@ -81,6 +114,40 @@ static ErrorOr<void> out_curve_tag(Gfx::ICC::TagData const& tag, int indent_amou
|
||||||
out_curve(static_cast<Gfx::ICC::CurveTagData const&>(tag), indent_amount);
|
out_curve(static_cast<Gfx::ICC::CurveTagData const&>(tag), indent_amount);
|
||||||
if (tag.type() == Gfx::ICC::ParametricCurveTagData::Type)
|
if (tag.type() == Gfx::ICC::ParametricCurveTagData::Type)
|
||||||
out_parametric_curve(static_cast<Gfx::ICC::ParametricCurveTagData const&>(tag), indent_amount);
|
out_parametric_curve(static_cast<Gfx::ICC::ParametricCurveTagData const&>(tag), indent_amount);
|
||||||
|
|
||||||
|
auto sRGB_curve = TRY(Gfx::ICC::sRGB_curve());
|
||||||
|
|
||||||
|
// Some example values (for abs distance summed over the 256 values of an u8):
|
||||||
|
// In Compact-ICC-Profiles/profiles:
|
||||||
|
// AdobeCompat-v2.icc: 1.14 (this is a gamma 2.2 curve, so not really sRGB but close)
|
||||||
|
// AdobeCompat-v4.icc: 1.13
|
||||||
|
// AppleCompat-v2.icc: 11.94 (gamma 1.8 curve)
|
||||||
|
// DCI-P3-v4.icc: 8.29 (gamma 2.6 curve)
|
||||||
|
// DisplayP3-v2-magic.icc: 0.000912 (looks sRGB-ish)
|
||||||
|
// DisplayP3-v2-micro.icc: 0.010819
|
||||||
|
// DisplayP3-v4.icc: 0.001062 (yes, definitely sRGB)
|
||||||
|
// Rec2020-g24-v4.icc: 4.119216 (gamma 2.4 curve)
|
||||||
|
// Rec2020-v4.icc: 7.805417 (custom non-sRGB curve)
|
||||||
|
// Rec709-v4.icc: 7.783267 (same custom non-sRGB curve as Rec2020)
|
||||||
|
// sRGB-v2-magic.icc: 0.000912
|
||||||
|
// sRGB-v2-micro.icc: 0.010819
|
||||||
|
// sRGB-v2-nano.icc: 0.052516
|
||||||
|
// sRGB-v4.icc: 0.001062
|
||||||
|
// scRGB-v2.icc: 48.379859 (linear identity curve)
|
||||||
|
// Google sRGB IEC61966-2.1 (from a Pixel jpeg, parametric): 0
|
||||||
|
// Google sRGB IEC61966-2.1 (from a Pixel jpeg, LUT curve): 0.00096
|
||||||
|
// Apple 2015 Display P3 (from iPhone 7, parametric): 0.011427 (has the old, left intersection for switching from linear to exponent)
|
||||||
|
// HP sRGB: 0.00096
|
||||||
|
// color.org sRGB2014.icc: 0.00096
|
||||||
|
// color.org sRGB_ICC_v4_Appearance.icc, AToB1Tag, a curves: 0.441926 -- but this is not _really_ sRGB
|
||||||
|
// color.org sRGB_v4_ICC_preference.icc, AToB1Tag, a curves: 2.205453 -- not really sRGB either
|
||||||
|
// So `< 0.06` identifies sRGB in practice (for u8 values).
|
||||||
|
float u8_distance_to_sRGB = curve_distance_u8(*sRGB_curve, tag);
|
||||||
|
if (u8_distance_to_sRGB < 0.06f)
|
||||||
|
outln("{: >{}}Looks like sRGB's curve (distance {})", "", indent_amount, u8_distance_to_sRGB);
|
||||||
|
else
|
||||||
|
outln("{: >{}}Does not look like sRGB's curve (distance: {})", "", indent_amount, u8_distance_to_sRGB);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue