LibGfx/ICC: Add a convert_cmyk_image() method

It converts from a CMYKBitmap to an (rgb) bitmap, using a real
color profile.

The API design here isn't super scalable (what if we want to also
handle grayscale inputs? What if we also want to convert _to_ cmyk
or grayscale?), but we have to start somewhere. Uses of this can
inform future API improvements.
This commit is contained in:
Nico Weber 2024-01-24 11:44:09 -05:00 committed by Andreas Kling
parent 11b623b1fd
commit 88b49a639e
2 changed files with 27 additions and 0 deletions

View file

@ -6,6 +6,7 @@
#include <AK/Endian.h>
#include <LibGfx/CIELAB.h>
#include <LibGfx/CMYKBitmap.h>
#include <LibGfx/ICC/BinaryFormat.h>
#include <LibGfx/ICC/Profile.h>
#include <LibGfx/ICC/Tags.h>
@ -1660,6 +1661,31 @@ ErrorOr<void> Profile::convert_image(Gfx::Bitmap& bitmap, Profile const& source_
return {};
}
ErrorOr<void> Profile::convert_cmyk_image(Bitmap& out, CMYKBitmap const& in, Profile const& source_profile) const
{
if (out.size() != in.size())
return Error::from_string_literal("ICC::Profile::convert_cmyk_image: out and in must have the same dimensions");
// Might fail if `out` has a scale_factor() != 1.
if (out.data_size() != in.data_size())
return Error::from_string_literal("ICC::Profile::convert_cmyk_image: out and in must have the same buffer size");
static_assert(sizeof(ARGB32) == sizeof(CMYK));
ARGB32* out_data = out.begin();
CMYK const* in_data = const_cast<CMYKBitmap&>(in).begin();
for (size_t i = 0; i < in.data_size() / sizeof(CMYK); ++i) {
u8 cmyk[] = { in_data[i].c, in_data[i].m, in_data[i].y, in_data[i].k };
auto pcs = TRY(source_profile.to_pcs(cmyk));
u8 rgb[3];
TRY(from_pcs(source_profile, pcs, rgb));
out_data[i] = Color(rgb[0], rgb[1], rgb[2]).value();
}
return {};
}
XYZ const& Profile::red_matrix_column() const { return xyz_data(redMatrixColumnTag); }
XYZ const& Profile::green_matrix_column() const { return xyz_data(greenMatrixColumnTag); }
XYZ const& Profile::blue_matrix_column() const { return xyz_data(blueMatrixColumnTag); }

View file

@ -275,6 +275,7 @@ public:
ErrorOr<CIELAB> to_lab(ReadonlyBytes) const;
ErrorOr<void> convert_image(Bitmap&, Profile const& source_profile) const;
ErrorOr<void> convert_cmyk_image(Bitmap&, CMYKBitmap const&, Profile const& source_profile) const;
// Only call these if you know that this is an RGB matrix-based profile.
XYZ const& red_matrix_column() const;