From b9677be8a799ecd9aecf3e612f35116e6b6ecb21 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2024 20:59:24 -0400 Subject: [PATCH] LibGfx/JPEG2000: Decode COM marker segment data We don't do anything with this (except log the contents if JPEG2000_DEBUG is 1). The motivation is that we now decode all marker segments that are used in all JPEG2000 files I've seen so far, allowing us to make remaining unknown marker types fatal. --- .../LibGfx/ImageFormats/JPEG2000Loader.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp b/Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp index 876e3db52c3..ec651f74de9 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp @@ -10,6 +10,7 @@ #include #include #include +#include // Core coding system spec (.jp2 format): T-REC-T.800-201511-S!!PDF-E.pdf available here: // https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.800-201511-S!!PDF-E&type=items @@ -408,6 +409,35 @@ static ErrorOr read_quantization_default(ReadonlyBytes data return qcd; } +// A.9.2 Comment (COM) +struct Comment { + enum CommentType { + Binary = 0, + ISO_IEC_8859_15 = 1, + }; + CommentType type { Binary }; // "Rcom" in spec. + ReadonlyBytes data; +}; + +static ErrorOr read_comment(ReadonlyBytes data) +{ + if (data.size() < 2) + return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough data for COM marker segment"); + + Comment com; + u16 comment_type = *reinterpret_cast const*>(data.data()); + if (comment_type > 1) + return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Invalid comment type"); + com.type = static_cast(comment_type); + com.data = data.slice(1); + + dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COM marker segment: comment_type={}, size()={}", (int)com.type, com.data.size()); + if (com.type == Comment::ISO_IEC_8859_15) + dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COM marker segment, ISO/IEC 8859-15 text: '{}'", TRY(TextCodec::decoder_for("ISO-8859-1"sv)->to_utf8(StringView { com.data }))); + + return com; +} + struct JPEG2000LoadingContext { enum class State { NotDecoded = 0, @@ -427,6 +457,7 @@ struct JPEG2000LoadingContext { ImageAndTileSize siz; CodingStyleDefault cod; QuantizationDefault qcd; + Vector coms; }; struct MarkerSegment { @@ -513,6 +544,8 @@ static ErrorOr parse_codestream_main_header(JPEG2000LoadingContext& contex return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple QCD markers in main header"); context.qcd = TRY(read_quantization_default(marker.data.value())); saw_QCD_marker = true; + } else if (marker.marker == J2K_COM) { + context.coms.append(TRY(read_comment(marker.data.value()))); } else { // FIXME: These are valid main header markers. Parse contents. dbgln("JPEG2000ImageDecoderPlugin: marker {:#04x} not yet implemented", marker.marker);