mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibGfx+icc: Read viewingConditionsType
Not terribly useful in practice either and also mostly for completionism. But with this, we can dump all types present in Lightroom Classic-exported jpegs :^)
This commit is contained in:
parent
664946c543
commit
c61cfdd5ed
Notes:
sideshowbarker
2024-07-17 02:56:25 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/c61cfdd5ed Pull-request: https://github.com/SerenityOS/serenity/pull/17411
4 changed files with 60 additions and 1 deletions
|
@ -600,6 +600,8 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, u32 offse
|
|||
return TextDescriptionTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
case TextTagData::Type:
|
||||
return TextTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
case ViewingConditionsTagData::Type:
|
||||
return ViewingConditionsTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
case XYZTagData::Type:
|
||||
return XYZTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
default:
|
||||
|
@ -1259,7 +1261,8 @@ ErrorOr<void> Profile::check_tag_types()
|
|||
|
||||
// ICC v4, 9.2.51 viewingConditionsTag
|
||||
// "Permitted tag types: viewingConditionsType"
|
||||
// FIXME
|
||||
if (!has_type(viewingConditionsTag, { ViewingConditionsTagData::Type }, {}))
|
||||
return Error::from_string_literal("ICC::Profile: viewingConditionsTag has unexpected type");
|
||||
|
||||
// FIXME: Add validation for v2-only tags:
|
||||
// - ICC v2, 6.4.14 crdInfoTag
|
||||
|
|
|
@ -934,6 +934,31 @@ ErrorOr<NonnullRefPtr<TextTagData>> TextTagData::from_bytes(ReadonlyBytes bytes,
|
|||
return adopt_ref(*new TextTagData(offset, size, TRY(String::from_utf8(StringView(text_data, length - 1)))));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<ViewingConditionsTagData>> ViewingConditionsTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.30 viewingConditionsType
|
||||
VERIFY(tag_type(bytes) == Type);
|
||||
TRY(check_reserved(bytes));
|
||||
|
||||
// Table 84 — viewingConditionsType encoding
|
||||
struct ViewingConditionsHeader {
|
||||
XYZNumber unnormalized_ciexyz_values_for_illuminant; // "(in which Y is in cd/m2)"
|
||||
XYZNumber unnormalized_ciexyz_values_for_surround; // "(in which Y is in cd/m2)"
|
||||
BigEndian<MeasurementTagData::StandardIlluminant> illuminant_type;
|
||||
};
|
||||
static_assert(AssertSize<ViewingConditionsHeader, 28>());
|
||||
|
||||
if (bytes.size() < 2 * sizeof(u32) + sizeof(ViewingConditionsHeader))
|
||||
return Error::from_string_literal("ICC::Profile: viewingConditionsType has not enough data");
|
||||
|
||||
auto& header = *bit_cast<ViewingConditionsHeader const*>(bytes.data() + 8);
|
||||
|
||||
TRY(MeasurementTagData::validate_standard_illuminant(header.illuminant_type));
|
||||
|
||||
return adopt_ref(*new ViewingConditionsTagData(offset, size, header.unnormalized_ciexyz_values_for_illuminant,
|
||||
header.unnormalized_ciexyz_values_for_surround, header.illuminant_type));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<XYZTagData>> XYZTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.31 XYZType
|
||||
|
|
|
@ -679,6 +679,32 @@ private:
|
|||
String m_text;
|
||||
};
|
||||
|
||||
// ICC v4, 10.30 viewingConditionsType
|
||||
class ViewingConditionsTagData : public TagData {
|
||||
public:
|
||||
static constexpr TagTypeSignature Type { 0x76696577 }; // 'view'
|
||||
|
||||
static ErrorOr<NonnullRefPtr<ViewingConditionsTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||
|
||||
ViewingConditionsTagData(u32 offset, u32 size, XYZ const& unnormalized_ciexyz_values_for_illuminant,
|
||||
XYZ const& unnormalized_ciexyz_values_for_surround, MeasurementTagData::StandardIlluminant illuminant_type)
|
||||
: TagData(offset, size, Type)
|
||||
, m_unnormalized_ciexyz_values_for_illuminant(unnormalized_ciexyz_values_for_illuminant)
|
||||
, m_unnormalized_ciexyz_values_for_surround(unnormalized_ciexyz_values_for_surround)
|
||||
, m_illuminant_type(illuminant_type)
|
||||
{
|
||||
}
|
||||
|
||||
XYZ const& unnormalized_ciexyz_values_for_illuminant() const { return m_unnormalized_ciexyz_values_for_illuminant; }
|
||||
XYZ const& unnormalized_ciexyz_values_for_surround() const { return m_unnormalized_ciexyz_values_for_surround; }
|
||||
MeasurementTagData::StandardIlluminant illuminant_type() const { return m_illuminant_type; }
|
||||
|
||||
private:
|
||||
XYZ m_unnormalized_ciexyz_values_for_illuminant; // "(in which Y is in cd/m2)"
|
||||
XYZ m_unnormalized_ciexyz_values_for_surround; // "(in which Y is in cd/m2)"
|
||||
MeasurementTagData::StandardIlluminant m_illuminant_type;
|
||||
};
|
||||
|
||||
// ICC v4, 10.31 XYZType
|
||||
class XYZTagData : public TagData {
|
||||
public:
|
||||
|
|
|
@ -311,6 +311,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
out_optional(" macintosh", MUST(text_description.macintosh_description().map([](auto description) { return String::formatted("\"{}\"", description); })));
|
||||
} else if (tag_data->type() == Gfx::ICC::TextTagData::Type) {
|
||||
outln(" text: \"{}\"", static_cast<Gfx::ICC::TextTagData&>(*tag_data).text());
|
||||
} else if (tag_data->type() == Gfx::ICC::ViewingConditionsTagData::Type) {
|
||||
auto& viewing_conditions = static_cast<Gfx::ICC::ViewingConditionsTagData&>(*tag_data);
|
||||
outln(" unnormalized CIEXYZ values for illuminant (in which Y is in cd/m²): {}", viewing_conditions.unnormalized_ciexyz_values_for_illuminant());
|
||||
outln(" unnormalized CIEXYZ values for surround (in which Y is in cd/m²): {}", viewing_conditions.unnormalized_ciexyz_values_for_surround());
|
||||
outln(" illuminant type: {}", Gfx::ICC::MeasurementTagData::standard_illuminant_name(viewing_conditions.illuminant_type()));
|
||||
} else if (tag_data->type() == Gfx::ICC::XYZTagData::Type) {
|
||||
for (auto& xyz : static_cast<Gfx::ICC::XYZTagData&>(*tag_data).xyzs())
|
||||
outln(" {}", xyz);
|
||||
|
|
Loading…
Reference in a new issue