LibGfx/ICC: Extract matrix computation functions
No behavior (or perf) change.
This commit is contained in:
parent
5c5a24c6b7
commit
19d434b229
Notes:
sideshowbarker
2024-07-17 11:29:41 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/19d434b229 Pull-request: https://github.com/SerenityOS/serenity/pull/22683 Reviewed-by: https://github.com/LucasChollet ✅
2 changed files with 33 additions and 25 deletions
Userland/Libraries/LibGfx/ICC
|
@ -1304,19 +1304,13 @@ ErrorOr<FloatVector3> Profile::to_pcs(ReadonlyBytes color) const
|
|||
// [connection_X] = [redMatrixColumn_X greenMatrixColumn_X blueMatrixColumn_X] [ linear_r ]
|
||||
// [connection_Y] = [redMatrixColumn_Y greenMatrixColumn_Y blueMatrixColumn_Y] * [ linear_g ]
|
||||
// [connection_Z] = [redMatrixColumn_Z greenMatrixColumn_Z blueMatrixColumn_Z] [ linear_b ]"
|
||||
float linear_r = evaluate_curve(redTRCTag, color[0] / 255.f);
|
||||
float linear_g = evaluate_curve(greenTRCTag, color[1] / 255.f);
|
||||
float linear_b = evaluate_curve(blueTRCTag, color[2] / 255.f);
|
||||
FloatVector3 linear_rgb {
|
||||
evaluate_curve(redTRCTag, color[0] / 255.f),
|
||||
evaluate_curve(greenTRCTag, color[1] / 255.f),
|
||||
evaluate_curve(blueTRCTag, color[2] / 255.f),
|
||||
};
|
||||
|
||||
auto const& red_matrix_column = this->red_matrix_column();
|
||||
auto const& green_matrix_column = this->green_matrix_column();
|
||||
auto const& blue_matrix_column = this->blue_matrix_column();
|
||||
|
||||
float X = red_matrix_column.X * linear_r + green_matrix_column.X * linear_g + blue_matrix_column.X * linear_b;
|
||||
float Y = red_matrix_column.Y * linear_r + green_matrix_column.Y * linear_g + blue_matrix_column.Y * linear_b;
|
||||
float Z = red_matrix_column.Z * linear_r + green_matrix_column.Z * linear_g + blue_matrix_column.Z * linear_b;
|
||||
|
||||
return FloatVector3 { X, Y, Z };
|
||||
return rgb_to_xyz_matrix() * linear_rgb;
|
||||
}
|
||||
|
||||
return Error::from_string_literal("ICC::Profile::to_pcs: What happened?!");
|
||||
|
@ -1512,19 +1506,7 @@ ErrorOr<void> Profile::from_pcs(Profile const& source_profile, FloatVector3 pcs,
|
|||
|
||||
// Convert from XYZ to linear rgb.
|
||||
// FIXME: Inverting matrix and curve on every call to this function is very inefficient.
|
||||
auto const& red_matrix_column = this->red_matrix_column();
|
||||
auto const& green_matrix_column = this->green_matrix_column();
|
||||
auto const& blue_matrix_column = this->blue_matrix_column();
|
||||
|
||||
FloatMatrix3x3 forward_matrix {
|
||||
red_matrix_column.X, green_matrix_column.X, blue_matrix_column.X,
|
||||
red_matrix_column.Y, green_matrix_column.Y, blue_matrix_column.Y,
|
||||
red_matrix_column.Z, green_matrix_column.Z, blue_matrix_column.Z
|
||||
};
|
||||
if (!forward_matrix.is_invertible())
|
||||
return Error::from_string_literal("ICC::Profile::from_pcs: matrix not invertible");
|
||||
auto matrix = forward_matrix.inverse();
|
||||
FloatVector3 linear_rgb = matrix * pcs;
|
||||
FloatVector3 linear_rgb = TRY(xyz_to_rgb_matrix()) * pcs;
|
||||
|
||||
auto evaluate_curve_inverse = [this](TagSignature curve_tag, float f) {
|
||||
auto const& trc = *m_tag_table.get(curve_tag).value();
|
||||
|
@ -1635,4 +1617,25 @@ Optional<String> Profile::tag_string_data(TagSignature signature) const
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<FloatMatrix3x3> Profile::xyz_to_rgb_matrix() const
|
||||
{
|
||||
FloatMatrix3x3 forward_matrix = rgb_to_xyz_matrix();
|
||||
if (!forward_matrix.is_invertible())
|
||||
return Error::from_string_literal("ICC::Profile::from_pcs: matrix not invertible");
|
||||
return forward_matrix.inverse();
|
||||
}
|
||||
|
||||
FloatMatrix3x3 Profile::rgb_to_xyz_matrix() const
|
||||
{
|
||||
auto const& red_matrix_column = this->red_matrix_column();
|
||||
auto const& green_matrix_column = this->green_matrix_column();
|
||||
auto const& blue_matrix_column = this->blue_matrix_column();
|
||||
|
||||
return FloatMatrix3x3 {
|
||||
red_matrix_column.X, green_matrix_column.X, blue_matrix_column.X,
|
||||
red_matrix_column.Y, green_matrix_column.Y, blue_matrix_column.Y,
|
||||
red_matrix_column.Z, green_matrix_column.Z, blue_matrix_column.Z
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <LibGfx/CIELAB.h>
|
||||
#include <LibGfx/ICC/DistinctFourCC.h>
|
||||
#include <LibGfx/ICC/TagTypes.h>
|
||||
#include <LibGfx/Matrix3x3.h>
|
||||
#include <LibGfx/Vector3.h>
|
||||
|
||||
namespace Gfx::ICC {
|
||||
|
@ -247,6 +248,10 @@ private:
|
|||
// FIXME: The color conversion stuff should be in some other class.
|
||||
ErrorOr<FloatVector3> to_pcs_a_to_b(TagData const& tag_data, ReadonlyBytes) const;
|
||||
ErrorOr<void> from_pcs_b_to_a(TagData const& tag_data, FloatVector3 const&, Bytes) const;
|
||||
|
||||
// Only valid for RGB matrix-based profiles.
|
||||
ErrorOr<FloatMatrix3x3> xyz_to_rgb_matrix() const;
|
||||
FloatMatrix3x3 rgb_to_xyz_matrix() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue