LibGfx+icc: Add ICCProfile support for XYZType and print it

This commit is contained in:
Nico Weber 2023-01-22 22:25:44 -05:00 committed by Linus Groh
parent 2bfd09b173
commit 6cfb057430
Notes: sideshowbarker 2024-07-17 01:21:18 +09:00
3 changed files with 46 additions and 0 deletions

View File

@ -781,6 +781,28 @@ ErrorOr<NonnullRefPtr<TextTagData>> TextTagData::from_bytes(ReadonlyBytes bytes,
return adopt_ref(*new TextTagData(offset, size, TRY(String::from_utf8(StringView(text_data, length - 1))))); return adopt_ref(*new TextTagData(offset, size, TRY(String::from_utf8(StringView(text_data, length - 1)))));
} }
ErrorOr<NonnullRefPtr<XYZTagData>> XYZTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
{
// ICC v4, 10.31 XYZType
VERIFY(tag_type(bytes) == XYZTagData::Type);
TRY(check_reserved(bytes));
// "The XYZType contains an array of three encoded values for PCSXYZ, CIEXYZ, or nCIEXYZ values. The
// number of sets of values is determined from the size of the tag."
size_t byte_size = bytes.size() - 8;
if (byte_size % sizeof(XYZNumber) != 0)
return Error::from_string_literal("ICC::Profile: XYZType wrong size");
size_t xyz_count = byte_size / sizeof(XYZNumber);
XYZNumber const* raw_xyzs = bit_cast<XYZNumber const*>(bytes.data() + 8);
Vector<XYZ, 1> xyzs;
TRY(xyzs.try_resize(xyz_count));
for (size_t i = 0; i < xyz_count; ++i)
xyzs[i] = (XYZ)raw_xyzs[i];
return adopt_ref(*new XYZTagData(offset, size, move(xyzs)));
}
ErrorOr<void> Profile::read_header(ReadonlyBytes bytes) ErrorOr<void> Profile::read_header(ReadonlyBytes bytes)
{ {
if (bytes.size() < sizeof(ICCHeader)) if (bytes.size() < sizeof(ICCHeader))
@ -832,6 +854,8 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, Detail::T
return TextDescriptionTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element); return TextDescriptionTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
case TextTagData::Type: case TextTagData::Type:
return TextTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element); return TextTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
case XYZTagData::Type:
return XYZTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
default: default:
// FIXME: optionally ignore tags of unknown type // FIXME: optionally ignore tags of unknown type
return adopt_ref(*new UnknownTagData(entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element, type)); return adopt_ref(*new UnknownTagData(entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element, type));

View File

@ -335,6 +335,25 @@ private:
String m_text; String m_text;
}; };
// ICC v4, 10.31 XYZType
class XYZTagData : public TagData {
public:
static constexpr TagTypeSignature Type { 0x58595A20 }; // 'XYZ '
static ErrorOr<NonnullRefPtr<XYZTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
XYZTagData(u32 offset, u32 size, Vector<XYZ, 1> xyzs)
: TagData(offset, size, Type)
, m_xyzs(move(xyzs))
{
}
Vector<XYZ, 1> const& xyzs() const { return m_xyzs; }
private:
Vector<XYZ, 1> m_xyzs;
};
namespace Detail { namespace Detail {
struct TagTableEntry; struct TagTableEntry;
} }

View File

@ -110,6 +110,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
out_optional(" macintosh", MUST(text_description.macintosh_description().map([](auto description) { return String::formatted("\"{}\"", description); }))); out_optional(" macintosh", MUST(text_description.macintosh_description().map([](auto description) { return String::formatted("\"{}\"", description); })));
} else if (tag_data->type() == Gfx::ICC::TextTagData::Type) { } else if (tag_data->type() == Gfx::ICC::TextTagData::Type) {
outln(" text: \"{}\"", static_cast<Gfx::ICC::TextTagData&>(*tag_data).text()); outln(" text: \"{}\"", static_cast<Gfx::ICC::TextTagData&>(*tag_data).text());
} else if (tag_data->type() == Gfx::ICC::XYZTagData::Type) {
for (auto& xyz : static_cast<Gfx::ICC::XYZTagData&>(*tag_data).xyzs())
outln(" {}", xyz);
} }
}); });