From 8ed3f7c4c25c742c374fcd46040340df84640f48 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 12 Feb 2023 09:44:08 -0500 Subject: [PATCH] LibGfx: Add a size-less CurveTagData::from_bytes() overload in ICC code The curve data in lutAToBType and lutBToAType can store 'curv' data, but other than in the main ICC tag table, the size of the tag data isn't explicitly stored. So it must be computed from the data contents. Extract the function body into a helper can call that from both variants. --- Userland/Libraries/LibGfx/ICC/TagTypes.cpp | 30 +++++++++++++++++++--- Userland/Libraries/LibGfx/ICC/TagTypes.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibGfx/ICC/TagTypes.cpp b/Userland/Libraries/LibGfx/ICC/TagTypes.cpp index 45ce7b5da7..fe7b0d9e0a 100644 --- a/Userland/Libraries/LibGfx/ICC/TagTypes.cpp +++ b/Userland/Libraries/LibGfx/ICC/TagTypes.cpp @@ -167,17 +167,25 @@ ErrorOr> CicpTagData::from_bytes(ReadonlyBytes bytes, return try_make_ref_counted(offset, size, color_primaries, transfer_characteristics, matrix_coefficients, video_full_range_flag); } -ErrorOr> CurveTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size) +namespace { + +struct CurveData { + u32 computed_size; + Vector values; +}; + +ErrorOr curve_data_from_bytes(ReadonlyBytes bytes) { // ICC v4, 10.6 curveType - VERIFY(tag_type(bytes) == Type); + VERIFY(tag_type(bytes) == CurveTagData::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 const*>(bytes.data() + 8); - if (bytes.size() < 3 * sizeof(u32) + count * sizeof(u16)) + u32 computed_size = 3 * sizeof(u32) + count * sizeof(u16); + if (bytes.size() < computed_size) return Error::from_string_literal("ICC::Profile: curveType has not enough data for curve points"); auto* raw_values = bit_cast const*>(bytes.data() + 12); @@ -187,7 +195,21 @@ ErrorOr> CurveTagData::from_bytes(ReadonlyBytes byte for (u32 i = 0; i < count; ++i) values[i] = raw_values[i]; - return try_make_ref_counted(offset, size, move(values)); + return CurveData { computed_size, move(values) }; +} + +} + +ErrorOr> CurveTagData::from_bytes(ReadonlyBytes bytes, u32 offset) +{ + auto curve_data = TRY(curve_data_from_bytes(bytes)); + return try_make_ref_counted(offset, curve_data.computed_size, move(curve_data.values)); +} + +ErrorOr> CurveTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size) +{ + auto curve_data = TRY(curve_data_from_bytes(bytes)); + return try_make_ref_counted(offset, size, move(curve_data.values)); } ErrorOr> Lut16TagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size) diff --git a/Userland/Libraries/LibGfx/ICC/TagTypes.h b/Userland/Libraries/LibGfx/ICC/TagTypes.h index 62099b460a..41ae8e1ee5 100644 --- a/Userland/Libraries/LibGfx/ICC/TagTypes.h +++ b/Userland/Libraries/LibGfx/ICC/TagTypes.h @@ -137,6 +137,7 @@ class CurveTagData : public TagData { public: static constexpr TagTypeSignature Type { 0x63757276 }; // 'curv' + static ErrorOr> from_bytes(ReadonlyBytes, u32 offset); static ErrorOr> from_bytes(ReadonlyBytes, u32 offset, u32 size); CurveTagData(u32 offset, u32 size, Vector values)