mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibGfx+icc: Add ICCProfile support for s15Fixed16ArrayType and print it
This is the type of the chromaticAdaptationTag, which is a required tag in v4 profiles for all non-DeviceLink profiles.
This commit is contained in:
parent
9c5820326d
commit
9756842734
3 changed files with 65 additions and 0 deletions
|
@ -612,6 +612,28 @@ ErrorOr<NonnullRefPtr<MultiLocalizedUnicodeTagData>> MultiLocalizedUnicodeTagDat
|
||||||
return adopt_ref(*new MultiLocalizedUnicodeTagData(offset, size, move(records)));
|
return adopt_ref(*new MultiLocalizedUnicodeTagData(offset, size, move(records)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<NonnullRefPtr<S15Fixed16ArrayTagData>> S15Fixed16ArrayTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||||
|
{
|
||||||
|
// ICC v4, 10.22 s15Fixed16ArrayType
|
||||||
|
VERIFY(tag_type(bytes) == Type);
|
||||||
|
TRY(check_reserved(bytes));
|
||||||
|
|
||||||
|
// "This type represents an array of generic 4-byte (32-bit) fixed point quantity. The number of values is determined
|
||||||
|
// from the size of the tag."
|
||||||
|
size_t byte_size = bytes.size() - 8;
|
||||||
|
if (byte_size % sizeof(s15Fixed16Number) != 0)
|
||||||
|
return Error::from_string_literal("ICC::Profile: s15Fixed16ArrayType has wrong size");
|
||||||
|
|
||||||
|
size_t count = byte_size / sizeof(s15Fixed16Number);
|
||||||
|
BigEndian<s15Fixed16Number> const* raw_values = bit_cast<BigEndian<s15Fixed16Number> const*>(bytes.data() + 8);
|
||||||
|
Vector<S15Fixed16, 9> values;
|
||||||
|
TRY(values.try_resize(count));
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
values[i] = S15Fixed16::create_raw(raw_values[i]);
|
||||||
|
|
||||||
|
return adopt_ref(*new S15Fixed16ArrayTagData(offset, size, move(values)));
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<TextDescriptionTagData>> TextDescriptionTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
ErrorOr<NonnullRefPtr<TextDescriptionTagData>> TextDescriptionTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||||
{
|
{
|
||||||
// ICC v2, 6.5.17 textDescriptionType
|
// ICC v2, 6.5.17 textDescriptionType
|
||||||
|
@ -850,6 +872,8 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, Detail::T
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MultiLocalizedUnicodeTagData::Type:
|
case MultiLocalizedUnicodeTagData::Type:
|
||||||
return MultiLocalizedUnicodeTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
|
return MultiLocalizedUnicodeTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
|
||||||
|
case S15Fixed16ArrayTagData::Type:
|
||||||
|
return S15Fixed16ArrayTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
|
||||||
case TextDescriptionTagData::Type:
|
case TextDescriptionTagData::Type:
|
||||||
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:
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Error.h>
|
#include <AK/Error.h>
|
||||||
|
#include <AK/FixedPoint.h>
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/NonnullRefPtr.h>
|
#include <AK/NonnullRefPtr.h>
|
||||||
|
@ -282,6 +283,27 @@ private:
|
||||||
Vector<Record> m_records;
|
Vector<Record> m_records;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ICC v4, 10.22 s15Fixed16ArrayType
|
||||||
|
class S15Fixed16ArrayTagData : public TagData {
|
||||||
|
public:
|
||||||
|
static constexpr TagTypeSignature Type { 0x73663332 }; // 'sf32'
|
||||||
|
|
||||||
|
using S15Fixed16 = FixedPoint<16, i32>;
|
||||||
|
|
||||||
|
static ErrorOr<NonnullRefPtr<S15Fixed16ArrayTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||||
|
|
||||||
|
S15Fixed16ArrayTagData(u32 offset, u32 size, Vector<S15Fixed16, 9> values)
|
||||||
|
: TagData(offset, size, Type)
|
||||||
|
, m_values(move(values))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<S15Fixed16, 9> const& values() const { return m_values; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<S15Fixed16, 9> m_values;
|
||||||
|
};
|
||||||
|
|
||||||
// ICC v2, 6.5.17 textDescriptionType
|
// ICC v2, 6.5.17 textDescriptionType
|
||||||
class TextDescriptionTagData : public TagData {
|
class TextDescriptionTagData : public TagData {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -102,6 +102,25 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
record.iso_3166_1_country_code >> 8, record.iso_3166_1_country_code & 0xff,
|
record.iso_3166_1_country_code >> 8, record.iso_3166_1_country_code & 0xff,
|
||||||
record.text);
|
record.text);
|
||||||
}
|
}
|
||||||
|
} else if (tag_data->type() == Gfx::ICC::S15Fixed16ArrayTagData::Type) {
|
||||||
|
// This tag can contain arbitrarily many fixed-point numbers, but in practice it's
|
||||||
|
// exclusively used for the 'chad' tag, where it always contains 9 values that
|
||||||
|
// represent a 3x3 matrix. So print the values in groups of 3.
|
||||||
|
auto& fixed_array = static_cast<Gfx::ICC::S15Fixed16ArrayTagData&>(*tag_data);
|
||||||
|
out(" [");
|
||||||
|
int i = 0;
|
||||||
|
for (auto value : fixed_array.values()) {
|
||||||
|
if (i > 0) {
|
||||||
|
out(",");
|
||||||
|
if (i % 3 == 0) {
|
||||||
|
outln();
|
||||||
|
out(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out(" {}", value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
outln(" ]");
|
||||||
} else if (tag_data->type() == Gfx::ICC::TextDescriptionTagData::Type) {
|
} else if (tag_data->type() == Gfx::ICC::TextDescriptionTagData::Type) {
|
||||||
auto& text_description = static_cast<Gfx::ICC::TextDescriptionTagData&>(*tag_data);
|
auto& text_description = static_cast<Gfx::ICC::TextDescriptionTagData&>(*tag_data);
|
||||||
outln(" ascii: \"{}\"", text_description.ascii_description());
|
outln(" ascii: \"{}\"", text_description.ascii_description());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue