LibGfx: Add scaffolding for curves in lutAToBType and lutBToAType
This commit is contained in:
parent
743f494a9c
commit
4b2e18f34f
Notes:
sideshowbarker
2024-07-17 00:59:43 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/4b2e18f34f Pull-request: https://github.com/SerenityOS/serenity/pull/17419 Reviewed-by: https://github.com/awesomekling
2 changed files with 71 additions and 26 deletions
|
@ -358,6 +358,17 @@ static ErrorOr<CLUTData> read_clut_data(ReadonlyBytes bytes, AdvancedLUTHeader c
|
|||
return CLUTData { move(number_of_grid_points_in_dimension), move(values) };
|
||||
}
|
||||
|
||||
static ErrorOr<Vector<LutCurveType>> read_curves(ReadonlyBytes bytes, u32 offset, u32 count)
|
||||
{
|
||||
Vector<LutCurveType> curves;
|
||||
// FIXME: Implement.
|
||||
(void)bytes;
|
||||
(void)offset;
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
TRY(curves.try_append(adopt_ref(*new CurveTagData(0, 0, {}))));
|
||||
return curves;
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.12 lutAToBType
|
||||
|
@ -372,6 +383,7 @@ ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes
|
|||
return Error::from_string_literal("ICC::Profile: lutAToBType reserved_for_padding not 0");
|
||||
|
||||
// "Curve data elements may be shared. For example, the offsets for A, B and M curves can be identical."
|
||||
// FIXME: Implement sharing curve objects when that happens. (I haven't seen it happen in practice yet.)
|
||||
|
||||
// 10.12.2 “A” curves
|
||||
// "There are the same number of “A” curves as there are input channels. The “A” curves may only be used when
|
||||
|
@ -379,9 +391,9 @@ ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes
|
|||
// Each “A” curve is stored as an embedded curveType or a parametricCurveType (see 10.5 or 10.16). The length
|
||||
// is as indicated by the convention of the respective curve type. Note that the entire tag type, including the tag
|
||||
// type signature and reserved bytes, is included for each curve."
|
||||
if (header.offset_to_a_curves) {
|
||||
// FIXME
|
||||
}
|
||||
Optional<Vector<LutCurveType>> a_curves;
|
||||
if (header.offset_to_a_curves)
|
||||
a_curves = TRY(read_curves(bytes, header.offset_to_a_curves, header.number_of_input_channels));
|
||||
|
||||
// 10.12.3 CLUT
|
||||
Optional<CLUTData> clut_data;
|
||||
|
@ -398,9 +410,9 @@ ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes
|
|||
// or a parametricCurveType (see 10.5 or 10.16). The length is as indicated by the convention of the respective
|
||||
// curve type. Note that the entire tag type, including the tag type signature and reserved bytes, is included for
|
||||
// each curve. The “M” curves may only be used when the matrix is used."
|
||||
if (header.offset_to_m_curves) {
|
||||
// FIXME
|
||||
}
|
||||
Optional<Vector<LutCurveType>> m_curves;
|
||||
if (header.offset_to_m_curves)
|
||||
m_curves = TRY(read_curves(bytes, header.offset_to_m_curves, header.number_of_output_channels));
|
||||
|
||||
// 10.12.5 Matrix
|
||||
// "The matrix is organized as a 3 x 4 array. The elements appear in order from e1-e12. The matrix elements are
|
||||
|
@ -422,12 +434,12 @@ ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes
|
|||
// parametricCurveType (see 10.5 or 10.16). The length is as indicated by the convention of the respective curve
|
||||
// type. Note that the entire tag type, including the tag type signature and reserved bytes, are included for each
|
||||
// curve."
|
||||
if (header.offset_to_b_curves) {
|
||||
// FIXME
|
||||
}
|
||||
if (!header.offset_to_b_curves)
|
||||
return Error::from_string_literal("ICC::Profile: lutAToBType without B curves");
|
||||
Vector<LutCurveType> b_curves = TRY(read_curves(bytes, header.offset_to_b_curves, header.number_of_output_channels));
|
||||
|
||||
// FIXME: Pass curve data once it's read above.
|
||||
return adopt_ref(*new LutAToBTagData(offset, size, header.number_of_input_channels, header.number_of_output_channels, move(clut_data), e));
|
||||
return adopt_ref(*new LutAToBTagData(offset, size, header.number_of_input_channels, header.number_of_output_channels,
|
||||
move(a_curves), move(clut_data), move(m_curves), e, move(b_curves)));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<LutBToATagData>> LutBToATagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
|
@ -444,6 +456,7 @@ ErrorOr<NonnullRefPtr<LutBToATagData>> LutBToATagData::from_bytes(ReadonlyBytes
|
|||
return Error::from_string_literal("ICC::Profile: lutBToAType reserved_for_padding not 0");
|
||||
|
||||
// "Curve data elements may be shared. For example, the offsets for A, B and M curves may be identical."
|
||||
// FIXME: Implement sharing curve objects when that happens. (I haven't seen it happen in practice yet.)
|
||||
|
||||
// 10.13.2 “B” curves
|
||||
// "There are the same number of “B” curves as there are input channels. The curves are stored sequentially, with
|
||||
|
@ -451,9 +464,9 @@ ErrorOr<NonnullRefPtr<LutBToATagData>> LutBToATagData::from_bytes(ReadonlyBytes
|
|||
// or a parametricCurveType (see 10.5 or 10.16). The length is as indicated by the convention of the proper curve
|
||||
// type. Note that the entire tag type, including the tag type signature and reserved bytes, is included for each
|
||||
// curve."
|
||||
if (header.offset_to_b_curves) {
|
||||
// FIXME
|
||||
}
|
||||
if (!header.offset_to_b_curves)
|
||||
return Error::from_string_literal("ICC::Profile: lutBToAType without B curves");
|
||||
Vector<LutCurveType> b_curves = TRY(read_curves(bytes, header.offset_to_b_curves, header.number_of_input_channels));
|
||||
|
||||
// 10.13.3 Matrix
|
||||
// "The matrix is organized as a 3 x 4 array. The elements of the matrix appear in the type in order from e1 to e12.
|
||||
|
@ -475,9 +488,9 @@ ErrorOr<NonnullRefPtr<LutBToATagData>> LutBToATagData::from_bytes(ReadonlyBytes
|
|||
// a parametricCurveType (see 10.5 or 10.16). The length is as indicated by the convention of the proper curve
|
||||
// type. Note that the entire tag type, including the tag type signature and reserved bytes, are included for each
|
||||
// curve. The “M” curves may only be used when the matrix is used."
|
||||
if (header.offset_to_m_curves) {
|
||||
// FIXME
|
||||
}
|
||||
Optional<Vector<LutCurveType>> m_curves;
|
||||
if (header.offset_to_m_curves)
|
||||
m_curves = TRY(read_curves(bytes, header.offset_to_m_curves, header.number_of_input_channels));
|
||||
|
||||
// 10.13.5 CLUT
|
||||
Optional<CLUTData> clut_data;
|
||||
|
@ -494,12 +507,12 @@ ErrorOr<NonnullRefPtr<LutBToATagData>> LutBToATagData::from_bytes(ReadonlyBytes
|
|||
// Each “A” curve is stored as an embedded curveType or a parametricCurveType (see 10.5 or 10.16). The length
|
||||
// is as indicated by the convention of the proper curve type. Note that the entire tag type, including the tag type
|
||||
// signature and reserved bytes, is included for each curve."
|
||||
if (header.offset_to_a_curves) {
|
||||
// FIXME
|
||||
}
|
||||
Optional<Vector<LutCurveType>> a_curves;
|
||||
if (header.offset_to_a_curves)
|
||||
a_curves = TRY(read_curves(bytes, header.offset_to_a_curves, header.number_of_output_channels));
|
||||
|
||||
// FIXME: Pass curve data once it's read above.
|
||||
return adopt_ref(*new LutBToATagData(offset, size, header.number_of_input_channels, header.number_of_output_channels, e, move(clut_data)));
|
||||
return adopt_ref(*new LutBToATagData(offset, size, header.number_of_input_channels, header.number_of_output_channels,
|
||||
move(b_curves), e, move(m_curves), move(clut_data), move(a_curves)));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<MeasurementTagData>> MeasurementTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
|
|
|
@ -303,6 +303,8 @@ struct CLUTData {
|
|||
Variant<Vector<u8>, Vector<u16>> values;
|
||||
};
|
||||
|
||||
using LutCurveType = NonnullRefPtr<TagData>; // FIXME: Variant<CurveTagData, ParametricCurveTagData> instead?
|
||||
|
||||
// ICC v4, 10.12 lutAToBType
|
||||
class LutAToBTagData : public TagData {
|
||||
public:
|
||||
|
@ -310,32 +312,47 @@ public:
|
|||
|
||||
static ErrorOr<NonnullRefPtr<LutAToBTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||
|
||||
LutAToBTagData(u32 offset, u32 size, u8 number_of_input_channels, u8 number_of_output_channels, Optional<CLUTData> clut, Optional<EMatrix3x4> e)
|
||||
LutAToBTagData(u32 offset, u32 size, u8 number_of_input_channels, u8 number_of_output_channels,
|
||||
Optional<Vector<LutCurveType>> a_curves, Optional<CLUTData> clut, Optional<Vector<LutCurveType>> m_curves, Optional<EMatrix3x4> e, Vector<LutCurveType> b_curves)
|
||||
: TagData(offset, size, Type)
|
||||
, m_number_of_input_channels(number_of_input_channels)
|
||||
, m_number_of_output_channels(number_of_output_channels)
|
||||
, m_a_curves(move(a_curves))
|
||||
, m_clut(move(clut))
|
||||
, m_m_curves(move(m_curves))
|
||||
, m_e(e)
|
||||
, m_b_curves(move(b_curves))
|
||||
{
|
||||
VERIFY(!m_a_curves.has_value() || m_a_curves->size() == m_number_of_input_channels);
|
||||
VERIFY(!m_m_curves.has_value() || m_m_curves->size() == m_number_of_output_channels);
|
||||
VERIFY(m_b_curves.size() == m_number_of_output_channels);
|
||||
}
|
||||
|
||||
u8 number_of_input_channels() const { return m_number_of_input_channels; }
|
||||
u8 number_of_output_channels() const { return m_number_of_output_channels; }
|
||||
|
||||
Optional<Vector<LutCurveType>> const& a_curves() const { return m_a_curves; }
|
||||
Optional<CLUTData> const& clut() const { return m_clut; }
|
||||
Optional<Vector<LutCurveType>> const& m_curves() const { return m_m_curves; }
|
||||
Optional<EMatrix3x4> const& e_matrix() const { return m_e; }
|
||||
Vector<LutCurveType> const& b_curves() const { return m_b_curves; }
|
||||
|
||||
private:
|
||||
u8 m_number_of_input_channels;
|
||||
u8 m_number_of_output_channels;
|
||||
|
||||
// "Only the following combinations are permitted:
|
||||
// "It is possible to use any or all of these processing elements. At least one processing element shall be included.
|
||||
// Only the following combinations are permitted:
|
||||
// - B;
|
||||
// - M, Matrix, B;
|
||||
// - A, CLUT, B;
|
||||
// - A, CLUT, M, Matrix, B."
|
||||
// This seems to imply that the B curve is not in fact optional.
|
||||
Optional<Vector<LutCurveType>> m_a_curves;
|
||||
Optional<CLUTData> m_clut;
|
||||
Optional<Vector<LutCurveType>> m_m_curves;
|
||||
Optional<EMatrix3x4> m_e;
|
||||
Vector<LutCurveType> m_b_curves;
|
||||
};
|
||||
|
||||
// ICC v4, 10.13 lutBToAType
|
||||
|
@ -345,32 +362,47 @@ public:
|
|||
|
||||
static ErrorOr<NonnullRefPtr<LutBToATagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||
|
||||
LutBToATagData(u32 offset, u32 size, u8 number_of_input_channels, u8 number_of_output_channels, Optional<EMatrix3x4> e, Optional<CLUTData> clut)
|
||||
LutBToATagData(u32 offset, u32 size, u8 number_of_input_channels, u8 number_of_output_channels,
|
||||
Vector<LutCurveType> b_curves, Optional<EMatrix3x4> e, Optional<Vector<LutCurveType>> m_curves, Optional<CLUTData> clut, Optional<Vector<LutCurveType>> a_curves)
|
||||
: TagData(offset, size, Type)
|
||||
, m_number_of_input_channels(number_of_input_channels)
|
||||
, m_number_of_output_channels(number_of_output_channels)
|
||||
, m_b_curves(move(b_curves))
|
||||
, m_e(e)
|
||||
, m_m_curves(move(m_curves))
|
||||
, m_clut(move(clut))
|
||||
, m_a_curves(move(a_curves))
|
||||
{
|
||||
VERIFY(m_b_curves.size() == m_number_of_input_channels);
|
||||
VERIFY(!m_m_curves.has_value() || m_m_curves->size() == m_number_of_input_channels);
|
||||
VERIFY(!m_a_curves.has_value() || m_a_curves->size() == m_number_of_output_channels);
|
||||
}
|
||||
|
||||
u8 number_of_input_channels() const { return m_number_of_input_channels; }
|
||||
u8 number_of_output_channels() const { return m_number_of_output_channels; }
|
||||
|
||||
Vector<LutCurveType> const& b_curves() const { return m_b_curves; }
|
||||
Optional<EMatrix3x4> const& e_matrix() const { return m_e; }
|
||||
Optional<Vector<LutCurveType>> const& m_curves() const { return m_m_curves; }
|
||||
Optional<CLUTData> const& clut() const { return m_clut; }
|
||||
Optional<Vector<LutCurveType>> const& a_curves() const { return m_a_curves; }
|
||||
|
||||
private:
|
||||
u8 m_number_of_input_channels;
|
||||
u8 m_number_of_output_channels;
|
||||
|
||||
// "Only the following combinations are permitted:
|
||||
// "It is possible to use any or all of these processing elements. At least one processing element shall be included.
|
||||
// Only the following combinations are permitted:
|
||||
// - B;
|
||||
// - B, Matrix, M;
|
||||
// - B, CLUT, A;
|
||||
// - B, Matrix, M, CLUT, A."
|
||||
// This seems to imply that the B curve is not in fact optional.
|
||||
Vector<LutCurveType> m_b_curves;
|
||||
Optional<EMatrix3x4> m_e;
|
||||
Optional<Vector<LutCurveType>> m_m_curves;
|
||||
Optional<CLUTData> m_clut;
|
||||
Optional<Vector<LutCurveType>> m_a_curves;
|
||||
};
|
||||
|
||||
// ICC v4, 10.14 measurementType
|
||||
|
|
Loading…
Add table
Reference in a new issue