Browse Source

LibGfx/JPEG+CMYKBitmap: Extract the CMYK to RGB conversion code

Right now, the JPEG decoder is the only one supporting CMYK, but that
won't last for long. So, let's move the conversion to CMYKBitmap.
Lucas CHOLLET 1 year ago
parent
commit
09b2b3539b

+ 17 - 0
Userland/Libraries/LibGfx/CMYKBitmap.cpp

@@ -15,4 +15,21 @@ ErrorOr<NonnullRefPtr<CMYKBitmap>> CMYKBitmap::create_with_size(IntSize const& s
     return adopt_ref(*new CMYKBitmap(size, move(data)));
     return adopt_ref(*new CMYKBitmap(size, move(data)));
 }
 }
 
 
+ErrorOr<RefPtr<Bitmap>> CMYKBitmap::to_low_quality_rgb() const
+{
+    if (!m_rgb_bitmap) {
+        m_rgb_bitmap = TRY(Bitmap::create(BitmapFormat::BGRx8888, { m_size.width(), m_size.height() }));
+
+        for (int y = 0; y < m_size.height(); ++y) {
+            for (int x = 0; x < m_size.width(); ++x) {
+                auto const& cmyk = scanline(y)[x];
+                u8 k = 255 - cmyk.k;
+                m_rgb_bitmap->scanline(y)[x] = Color((255 - cmyk.c) * k / 255, (255 - cmyk.m) * k / 255, (255 - cmyk.y) * k / 255).value();
+            }
+        }
+    }
+
+    return m_rgb_bitmap;
+}
+
 }
 }

+ 5 - 0
Userland/Libraries/LibGfx/CMYKBitmap.h

@@ -9,6 +9,7 @@
 #include <AK/ByteBuffer.h>
 #include <AK/ByteBuffer.h>
 #include <AK/NonnullRefPtr.h>
 #include <AK/NonnullRefPtr.h>
 #include <AK/RefCounted.h>
 #include <AK/RefCounted.h>
+#include <LibGfx/Bitmap.h>
 #include <LibGfx/Size.h>
 #include <LibGfx/Size.h>
 
 
 namespace Gfx {
 namespace Gfx {
@@ -32,6 +33,8 @@ public:
     [[nodiscard]] CMYK* begin();
     [[nodiscard]] CMYK* begin();
     [[nodiscard]] CMYK* end();
     [[nodiscard]] CMYK* end();
 
 
+    ErrorOr<RefPtr<Bitmap>> to_low_quality_rgb() const;
+
 private:
 private:
     CMYKBitmap(IntSize const& size, ByteBuffer data)
     CMYKBitmap(IntSize const& size, ByteBuffer data)
         : m_size(size)
         : m_size(size)
@@ -41,6 +44,8 @@ private:
 
 
     IntSize m_size;
     IntSize m_size;
     ByteBuffer m_data;
     ByteBuffer m_data;
+
+    mutable RefPtr<Bitmap> m_rgb_bitmap;
 };
 };
 
 
 inline CMYK* CMYKBitmap::scanline(int y)
 inline CMYK* CMYKBitmap::scanline(int y)

+ 1 - 19
Userland/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp

@@ -1694,24 +1694,6 @@ static void invert_colors_for_adobe_images(JPEGLoadingContext const& context, Ve
     }
     }
 }
 }
 
 
-static ErrorOr<void> cmyk_to_rgb(JPEGLoadingContext& context)
-{
-    VERIFY(context.cmyk_bitmap);
-    VERIFY(!context.bitmap);
-
-    context.bitmap = TRY(Bitmap::create(BitmapFormat::BGRx8888, { context.frame.width, context.frame.height }));
-
-    for (int y = 0; y < context.frame.height; ++y) {
-        for (int x = 0; x < context.frame.width; ++x) {
-            auto const& cmyk = context.cmyk_bitmap->scanline(y)[x];
-            u8 k = 255 - cmyk.k;
-            context.bitmap->scanline(y)[x] = Color((255 - cmyk.c) * k / 255, (255 - cmyk.m) * k / 255, (255 - cmyk.y) * k / 255).value();
-        }
-    }
-
-    return {};
-}
-
 static void ycck_to_cmyk(Vector<Macroblock>& macroblocks)
 static void ycck_to_cmyk(Vector<Macroblock>& macroblocks)
 {
 {
     // 7 - Conversions between colour encodings
     // 7 - Conversions between colour encodings
@@ -2026,7 +2008,7 @@ ErrorOr<ImageFrameDescriptor> JPEGImageDecoderPlugin::frame(size_t index, Option
     }
     }
 
 
     if (m_context->cmyk_bitmap && !m_context->bitmap)
     if (m_context->cmyk_bitmap && !m_context->bitmap)
-        TRY(cmyk_to_rgb(*m_context));
+        return ImageFrameDescriptor { TRY(m_context->cmyk_bitmap->to_low_quality_rgb()), 0 };
 
 
     return ImageFrameDescriptor { m_context->bitmap, 0 };
     return ImageFrameDescriptor { m_context->bitmap, 0 };
 }
 }