mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibGfx+icc: Add ICCProfile support for curveType and print it
This commit is contained in:
parent
ea31aba0f4
commit
67f718aa3f
Notes:
sideshowbarker
2024-07-17 08:45:34 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/67f718aa3f Pull-request: https://github.com/SerenityOS/serenity/pull/17151
3 changed files with 66 additions and 1 deletions
|
@ -550,6 +550,29 @@ static ErrorOr<void> check_reserved(ReadonlyBytes tag_bytes)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<CurveTagData>> CurveTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.6 curveType
|
||||
VERIFY(tag_type(bytes) == Type);
|
||||
TRY(check_reserved(bytes));
|
||||
|
||||
if (bytes.size() < 3 * sizeof(u32))
|
||||
return Error::from_string_literal("ICC::Profile: curveType has not enough data for count");
|
||||
u32 count = *bit_cast<BigEndian<u32> const*>(bytes.data() + 8);
|
||||
|
||||
if (bytes.size() < 3 * sizeof(u32) + count * sizeof(u16))
|
||||
return Error::from_string_literal("ICC::Profile: curveType has not enough data for curve points");
|
||||
|
||||
BigEndian<u16> const* raw_values = bit_cast<BigEndian<u16> const*>(bytes.data() + 12);
|
||||
Vector<u16> values;
|
||||
TRY(values.try_resize(count));
|
||||
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
values[i] = raw_values[i];
|
||||
|
||||
return adopt_ref(*new CurveTagData(offset, size, move(values)));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<MultiLocalizedUnicodeTagData>> MultiLocalizedUnicodeTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.15 multiLocalizedUnicodeType
|
||||
|
@ -870,6 +893,8 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, Detail::T
|
|||
|
||||
auto type = tag_type(tag_bytes);
|
||||
switch (type) {
|
||||
case CurveTagData::Type:
|
||||
return CurveTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
|
||||
case MultiLocalizedUnicodeTagData::Type:
|
||||
return MultiLocalizedUnicodeTagData::from_bytes(tag_bytes, entry.offset_to_beginning_of_tag_data_element, entry.size_of_tag_data_element);
|
||||
case S15Fixed16ArrayTagData::Type:
|
||||
|
|
|
@ -258,6 +258,36 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// ICC v4, 10.6 curveType
|
||||
class CurveTagData : public TagData {
|
||||
public:
|
||||
static constexpr TagTypeSignature Type { 0x63757276 }; // 'curv'
|
||||
|
||||
static ErrorOr<NonnullRefPtr<CurveTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||
|
||||
CurveTagData(u32 offset, u32 size, Vector<u16> values)
|
||||
: TagData(offset, size, Type)
|
||||
, m_values(move(values))
|
||||
{
|
||||
}
|
||||
|
||||
// "The curveType embodies a one-dimensional function which maps an input value in the domain of the function
|
||||
// to an output value in the range of the function. The domain and range values are in the range of 0,0 to 1,0.
|
||||
// - When n is equal to 0, an identity response is assumed.
|
||||
// - When n is equal to 1, then the curve value shall be interpreted as a gamma value, encoded as a
|
||||
// u8Fixed8Number. Gamma shall be interpreted as the exponent in the equation y = pow(x,γ) and not as an inverse.
|
||||
// - When n is greater than 1, the curve values (which embody a sampled one-dimensional function) shall be
|
||||
// defined as follows:
|
||||
// - The first entry represents the input value 0,0, the last entry represents the input value 1,0, and intermediate
|
||||
// entries are uniformly spaced using an increment of 1,0/(n-1). These entries are encoded as uInt16Numbers
|
||||
// (i.e. the values represented by the entries, which are in the range 0,0 to 1,0 are encoded in the range 0 to
|
||||
// 65 535). Function values between the entries shall be obtained through linear interpolation."
|
||||
Vector<u16> const& values() const { return m_values; }
|
||||
|
||||
private:
|
||||
Vector<u16> m_values;
|
||||
};
|
||||
|
||||
// ICC v4, 10.15 multiLocalizedUnicodeType
|
||||
class MultiLocalizedUnicodeTagData : public TagData {
|
||||
public:
|
||||
|
|
|
@ -94,7 +94,17 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
profile->for_each_tag([](auto tag_signature, auto tag_data) {
|
||||
outln("{}: {}, offset {}, size {}", tag_signature, tag_data->type(), tag_data->offset(), tag_data->size());
|
||||
|
||||
if (tag_data->type() == Gfx::ICC::MultiLocalizedUnicodeTagData::Type) {
|
||||
if (tag_data->type() == Gfx::ICC::CurveTagData::Type) {
|
||||
auto& curve = static_cast<Gfx::ICC::CurveTagData&>(*tag_data);
|
||||
if (curve.values().is_empty()) {
|
||||
outln(" identity curve");
|
||||
} else if (curve.values().size() == 1) {
|
||||
outln(" gamma: {}", FixedPoint<8, u16>::create_raw(curve.values()[0]));
|
||||
} else {
|
||||
// FIXME: Maybe print the actual points if -v is passed?
|
||||
outln(" curve with {} points", curve.values().size());
|
||||
}
|
||||
} else if (tag_data->type() == Gfx::ICC::MultiLocalizedUnicodeTagData::Type) {
|
||||
auto& multi_localized_unicode = static_cast<Gfx::ICC::MultiLocalizedUnicodeTagData&>(*tag_data);
|
||||
for (auto& record : multi_localized_unicode.records()) {
|
||||
outln(" {:c}{:c}/{:c}{:c}: \"{}\"",
|
||||
|
|
Loading…
Reference in a new issue