From 588d6fab22ea108b9cd25e258f9bee7ded75d16f Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 16 Nov 2023 19:37:42 -0500 Subject: [PATCH] LibGfx+LibPDF: Create filter_type() for converting u8 to FilterType ...and use it in LibPDF. No behavior change. --- .../Libraries/LibGfx/ImageFormats/PNGLoader.cpp | 16 ++++++++-------- .../Libraries/LibGfx/ImageFormats/PNGShared.h | 8 ++++++++ Userland/Libraries/LibPDF/Filter.cpp | 16 +++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp index 85785526d1..a2730d9e4f 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/PNGLoader.cpp @@ -698,18 +698,18 @@ static ErrorOr decode_png_bitmap_simple(PNGLoadingContext& context, ByteBu Streamer streamer(decompression_buffer.data(), decompression_buffer.size()); for (int y = 0; y < context.height; ++y) { - PNG::FilterType filter; - if (!streamer.read(filter)) { + u8 filter_byte; + if (!streamer.read(filter_byte)) { context.state = PNGLoadingContext::State::Error; return Error::from_string_literal("PNGImageDecoderPlugin: Decoding failed"); } - if (to_underlying(filter) > 4) { + if (filter_byte > 4) { context.state = PNGLoadingContext::State::Error; return Error::from_string_literal("PNGImageDecoderPlugin: Invalid PNG filter"); } - context.scanlines.append({ filter }); + context.scanlines.append({ MUST(PNG::filter_type(filter_byte)) }); auto& scanline_buffer = context.scanlines.last().data; auto row_size = context.compute_row_size_for_width(context.width); if (row_size.has_overflow()) @@ -784,18 +784,18 @@ static ErrorOr decode_adam7_pass(PNGLoadingContext& context, Streamer& str return {}; for (int y = 0; y < subimage_context.height; ++y) { - PNG::FilterType filter; - if (!streamer.read(filter)) { + u8 filter_byte; + if (!streamer.read(filter_byte)) { context.state = PNGLoadingContext::State::Error; return Error::from_string_literal("PNGImageDecoderPlugin: Decoding failed"); } - if (to_underlying(filter) > 4) { + if (filter_byte > 4) { context.state = PNGLoadingContext::State::Error; return Error::from_string_literal("PNGImageDecoderPlugin: Invalid PNG filter"); } - subimage_context.scanlines.append({ filter }); + subimage_context.scanlines.append({ MUST(PNG::filter_type(filter_byte)) }); auto& scanline_buffer = subimage_context.scanlines.last().data; auto row_size = context.compute_row_size_for_width(subimage_context.width); diff --git a/Userland/Libraries/LibGfx/ImageFormats/PNGShared.h b/Userland/Libraries/LibGfx/ImageFormats/PNGShared.h index 299fceb29e..b8cac67c18 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/PNGShared.h +++ b/Userland/Libraries/LibGfx/ImageFormats/PNGShared.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Gfx::PNG { @@ -32,6 +33,13 @@ enum class FilterType : u8 { Paeth, }; +inline ErrorOr filter_type(u8 byte) +{ + if (byte <= 4) + return static_cast(byte); + return Error::from_string_literal("PNGImageDecoderPlugin: Invalid PNG filter"); +} + // https://www.w3.org/TR/PNG/#9Filter-type-4-Paeth ALWAYS_INLINE u8 paeth_predictor(u8 a, u8 b, u8 c) { diff --git a/Userland/Libraries/LibPDF/Filter.cpp b/Userland/Libraries/LibPDF/Filter.cpp index e64ba5ad8b..38347f24bd 100644 --- a/Userland/Libraries/LibPDF/Filter.cpp +++ b/Userland/Libraries/LibPDF/Filter.cpp @@ -162,19 +162,19 @@ PDFErrorOr Filter::decode_png_prediction(Bytes bytes, int bytes_per_ for (int row_index = 0; row_index < number_of_rows; ++row_index) { auto row = bytes.data() + row_index * bytes_per_row; - u8 algorithm_tag = row[0]; - switch (algorithm_tag) { - case 0: + auto filter = TRY(Gfx::PNG::filter_type(row[0])); + switch (filter) { + case Gfx::PNG::FilterType::None: break; - case 1: + case Gfx::PNG::FilterType::Sub: for (int i = 2; i < bytes_per_row; ++i) row[i] += row[i - 1]; break; - case 2: + case Gfx::PNG::FilterType::Up: for (int i = 1; i < bytes_per_row; ++i) row[i] += previous_row[i]; break; - case 3: + case Gfx::PNG::FilterType::Average: for (int i = 1; i < bytes_per_row; ++i) { u8 left = 0; if (i > 1) @@ -183,7 +183,7 @@ PDFErrorOr Filter::decode_png_prediction(Bytes bytes, int bytes_per_ row[i] += (left + above) / 2; } break; - case 4: + case Gfx::PNG::FilterType::Paeth: for (int i = 1; i < bytes_per_row; ++i) { u8 left = 0; u8 upper_left = 0; @@ -195,8 +195,6 @@ PDFErrorOr Filter::decode_png_prediction(Bytes bytes, int bytes_per_ row[i] += Gfx::PNG::paeth_predictor(left, above, upper_left); } break; - default: - return AK::Error::from_string_literal("Unknown PNG algorithm tag"); } previous_row = row;