From eb1c99bd72bc7ee9a91970edb8c3aea94b28d093 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 22 Nov 2023 20:31:38 -0500 Subject: [PATCH] LibPDF+LibGfx: Make SMasks on jpeg images work SMasks are greyscale images that get used as alpha channel for a different image. JPEGs in PDFs are stored as streams with /DCTDecode filters, and we have a separate code path for loading those in the PDF renderer. That code path just calls our JPEG decoder, which creates bitmaps with format BGRx8888. So when we process an SMask for such a bitmap, we have to change the bitmap's format to BGRA8888 in addition to setting alpha values on all pixels. --- Userland/Libraries/LibGfx/Bitmap.h | 14 ++++++++++++++ Userland/Libraries/LibPDF/Renderer.cpp | 1 + 2 files changed, 15 insertions(+) diff --git a/Userland/Libraries/LibGfx/Bitmap.h b/Userland/Libraries/LibGfx/Bitmap.h index 8b61a7d5fa..75369b2dde 100644 --- a/Userland/Libraries/LibGfx/Bitmap.h +++ b/Userland/Libraries/LibGfx/Bitmap.h @@ -177,6 +177,20 @@ public: void fill(Color); [[nodiscard]] bool has_alpha_channel() const { return m_format == BitmapFormat::BGRA8888 || m_format == BitmapFormat::RGBA8888; } + void add_alpha_channel() + { + switch (m_format) { + case BitmapFormat::BGRx8888: + m_format = BitmapFormat::BGRA8888; + break; + case BitmapFormat::RGBA8888: + case BitmapFormat::BGRA8888: + // Nothing to do. + break; + case BitmapFormat::Invalid: + VERIFY_NOT_REACHED(); + } + } [[nodiscard]] BitmapFormat format() const { return m_format; } // Call only for BGRx8888 and BGRA8888 bitmaps. diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index ed4fa40e21..bde2d63a56 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -986,6 +986,7 @@ PDFErrorOr Renderer::show_image(NonnullRefPtr image) if (smask_bitmap->size() != image_bitmap->size()) smask_bitmap = TRY(smask_bitmap->scaled_to_size(image_bitmap->size())); + image_bitmap->add_alpha_channel(); for (int j = 0; j < image_bitmap->height(); ++j) { for (int i = 0; i < image_bitmap->width(); ++i) { auto image_color = image_bitmap->get_pixel(i, j);