From f4ee9a2333c6b854da6017e8bc026a5466357da4 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 12 Jan 2024 09:02:50 -0500 Subject: [PATCH] LibPDF: Support drawing images with 16 bits per channel This uses the tried-and-true "throw away the lower 8 bits" technique for now. This lets us render Tests/LibPDF/wide-gamut-only.pdf. --- Userland/Libraries/LibPDF/Renderer.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index 07cac390ef..244f3cd94a 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -1092,23 +1092,32 @@ PDFErrorOr Renderer::load_image(NonnullRefPtrnumber_of_components(); - Vector upsampled_storage; + Vector resampled_storage; if (bits_per_component < 8) { UpsampleMode mode = color_space->family() == ColorSpaceFamily::Indexed ? UpsampleMode::StoreValuesUnchanged : UpsampleMode::UpsampleTo8Bit; - upsampled_storage = upsample_to_8_bit(content, width * n_components, bits_per_component, mode); - content = upsampled_storage; + resampled_storage = upsample_to_8_bit(content, width * n_components, bits_per_component, mode); + content = resampled_storage; bits_per_component = 8; if (is_image_mask) { // "a sample value of 0 marks the page with the current color, and a 1 leaves the previous contents unchanged." // That's opposite of the normal alpha convention, and we're upsampling masks to 8 bit and use that as normal alpha. - for (u8& byte : upsampled_storage) + for (u8& byte : resampled_storage) byte = ~byte; } - } + } else if (bits_per_component == 16) { + if (color_space->family() == ColorSpaceFamily::Indexed) + return Error(Error::Type::RenderingUnsupported, "16 bpp indexed images not yet supported"); - if (bits_per_component == 16) { - return Error(Error::Type::RenderingUnsupported, "16 bpp images not yet supported"); + // PDF 1.7 spec, 4.8.2 Sample Representation: + // "units of 16 bits are given with the most significant byte first" + // FIXME: Eventually use all 16 bits instead of throwing away the lower 8 bits. + resampled_storage.ensure_capacity(content.size() / 2); + for (size_t i = 0; i < content.size(); i += 2) + resampled_storage.append(content[i]); + + content = resampled_storage; + bits_per_component = 8; } Vector decode_array;