Переглянути джерело

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.
Nico Weber 1 рік тому
батько
коміт
eb1c99bd72

+ 14 - 0
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.

+ 1 - 0
Userland/Libraries/LibPDF/Renderer.cpp

@@ -986,6 +986,7 @@ PDFErrorOr<void> Renderer::show_image(NonnullRefPtr<StreamObject> 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);