mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 21:27:34 +00:00
LibGfx: Add scaffolding for curves in lutAToBType and lutBToAType
This commit is contained in:
parent
743f494a9c
commit
4b2e18f34f
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) };
|
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)
|
ErrorOr<NonnullRefPtr<LutAToBTagData>> LutAToBTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||||
{
|
{
|
||||||
// ICC v4, 10.12 lutAToBType
|
// 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");
|
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."
|
// "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
|
// 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
|
// "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
|
// 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
|
// 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."
|
// type signature and reserved bytes, is included for each curve."
|
||||||
if (header.offset_to_a_curves) {
|
Optional<Vector<LutCurveType>> a_curves;
|
||||||
// FIXME
|
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
|
// 10.12.3 CLUT
|
||||||
Optional<CLUTData> clut_data;
|
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
|
// 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
|
// 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."
|
// each curve. The “M” curves may only be used when the matrix is used."
|
||||||
if (header.offset_to_m_curves) {
|
Optional<Vector<LutCurveType>> m_curves;
|
||||||
// FIXME
|
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
|
// 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
|
// "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
|
// 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
|
// type. Note that the entire tag type, including the tag type signature and reserved bytes, are included for each
|
||||||
// curve."
|
// curve."
|
||||||
if (header.offset_to_b_curves) {
|
if (!header.offset_to_b_curves)
|
||||||
// FIXME
|
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,
|
||||||
return adopt_ref(*new LutAToBTagData(offset, size, header.number_of_input_channels, header.number_of_output_channels, move(clut_data), e));
|
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)
|
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");
|
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."
|
// "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
|
// 10.13.2 “B” curves
|
||||||
// "There are the same number of “B” curves as there are input channels. The curves are stored sequentially, with
|
// "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
|
// 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
|
// type. Note that the entire tag type, including the tag type signature and reserved bytes, is included for each
|
||||||
// curve."
|
// curve."
|
||||||
if (header.offset_to_b_curves) {
|
if (!header.offset_to_b_curves)
|
||||||
// FIXME
|
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
|
// 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.
|
// "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
|
// 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
|
// 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."
|
// curve. The “M” curves may only be used when the matrix is used."
|
||||||
if (header.offset_to_m_curves) {
|
Optional<Vector<LutCurveType>> m_curves;
|
||||||
// FIXME
|
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
|
// 10.13.5 CLUT
|
||||||
Optional<CLUTData> clut_data;
|
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
|
// 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
|
// 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."
|
// signature and reserved bytes, is included for each curve."
|
||||||
if (header.offset_to_a_curves) {
|
Optional<Vector<LutCurveType>> a_curves;
|
||||||
// FIXME
|
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,
|
||||||
return adopt_ref(*new LutBToATagData(offset, size, header.number_of_input_channels, header.number_of_output_channels, e, move(clut_data)));
|
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)
|
ErrorOr<NonnullRefPtr<MeasurementTagData>> MeasurementTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||||
|
|
|
@ -303,6 +303,8 @@ struct CLUTData {
|
||||||
Variant<Vector<u8>, Vector<u16>> values;
|
Variant<Vector<u8>, Vector<u16>> values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using LutCurveType = NonnullRefPtr<TagData>; // FIXME: Variant<CurveTagData, ParametricCurveTagData> instead?
|
||||||
|
|
||||||
// ICC v4, 10.12 lutAToBType
|
// ICC v4, 10.12 lutAToBType
|
||||||
class LutAToBTagData : public TagData {
|
class LutAToBTagData : public TagData {
|
||||||
public:
|
public:
|
||||||
|
@ -310,32 +312,47 @@ public:
|
||||||
|
|
||||||
static ErrorOr<NonnullRefPtr<LutAToBTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
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)
|
: TagData(offset, size, Type)
|
||||||
, m_number_of_input_channels(number_of_input_channels)
|
, m_number_of_input_channels(number_of_input_channels)
|
||||||
, m_number_of_output_channels(number_of_output_channels)
|
, m_number_of_output_channels(number_of_output_channels)
|
||||||
|
, m_a_curves(move(a_curves))
|
||||||
, m_clut(move(clut))
|
, m_clut(move(clut))
|
||||||
|
, m_m_curves(move(m_curves))
|
||||||
, m_e(e)
|
, 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_input_channels() const { return m_number_of_input_channels; }
|
||||||
u8 number_of_output_channels() const { return m_number_of_output_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<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; }
|
Optional<EMatrix3x4> const& e_matrix() const { return m_e; }
|
||||||
|
Vector<LutCurveType> const& b_curves() const { return m_b_curves; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u8 m_number_of_input_channels;
|
u8 m_number_of_input_channels;
|
||||||
u8 m_number_of_output_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;
|
||||||
// - M, Matrix, B;
|
// - M, Matrix, B;
|
||||||
// - A, CLUT, B;
|
// - A, CLUT, B;
|
||||||
// - A, CLUT, M, Matrix, 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<CLUTData> m_clut;
|
||||||
|
Optional<Vector<LutCurveType>> m_m_curves;
|
||||||
Optional<EMatrix3x4> m_e;
|
Optional<EMatrix3x4> m_e;
|
||||||
|
Vector<LutCurveType> m_b_curves;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ICC v4, 10.13 lutBToAType
|
// ICC v4, 10.13 lutBToAType
|
||||||
|
@ -345,32 +362,47 @@ public:
|
||||||
|
|
||||||
static ErrorOr<NonnullRefPtr<LutBToATagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
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)
|
: TagData(offset, size, Type)
|
||||||
, m_number_of_input_channels(number_of_input_channels)
|
, m_number_of_input_channels(number_of_input_channels)
|
||||||
, m_number_of_output_channels(number_of_output_channels)
|
, m_number_of_output_channels(number_of_output_channels)
|
||||||
|
, m_b_curves(move(b_curves))
|
||||||
, m_e(e)
|
, m_e(e)
|
||||||
|
, m_m_curves(move(m_curves))
|
||||||
, m_clut(move(clut))
|
, 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_input_channels() const { return m_number_of_input_channels; }
|
||||||
u8 number_of_output_channels() const { return m_number_of_output_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<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<CLUTData> const& clut() const { return m_clut; }
|
||||||
|
Optional<Vector<LutCurveType>> const& a_curves() const { return m_a_curves; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u8 m_number_of_input_channels;
|
u8 m_number_of_input_channels;
|
||||||
u8 m_number_of_output_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;
|
||||||
// - B, Matrix, M;
|
// - B, Matrix, M;
|
||||||
// - B, CLUT, A;
|
// - B, CLUT, A;
|
||||||
// - B, Matrix, M, 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<EMatrix3x4> m_e;
|
||||||
|
Optional<Vector<LutCurveType>> m_m_curves;
|
||||||
Optional<CLUTData> m_clut;
|
Optional<CLUTData> m_clut;
|
||||||
|
Optional<Vector<LutCurveType>> m_a_curves;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ICC v4, 10.14 measurementType
|
// ICC v4, 10.14 measurementType
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue