From 19bee8393d4667c252f26389ff238a0a13b261b8 Mon Sep 17 00:00:00 2001 From: aplefull Date: Mon, 10 Mar 2025 10:26:12 +0100 Subject: [PATCH] LibGfx: Add support for YCCK jpeg files --- Libraries/LibGfx/ImageFormats/JPEGLoader.cpp | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp b/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp index f29bdb257cf..4118a4b88b0 100644 --- a/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp +++ b/Libraries/LibGfx/ImageFormats/JPEGLoader.cpp @@ -81,8 +81,10 @@ ErrorOr JPEGLoadingContext::decode() if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) return Error::from_string_literal("Failed to read JPEG header"); - if (cinfo.jpeg_color_space == JCS_CMYK || cinfo.jpeg_color_space == JCS_YCCK) { + if (cinfo.jpeg_color_space == JCS_CMYK) { cinfo.out_color_space = JCS_CMYK; + } else if (cinfo.jpeg_color_space == JCS_YCCK) { + cinfo.out_color_space = JCS_YCCK; } else { cinfo.out_color_space = JCS_EXT_BGRX; } @@ -112,6 +114,37 @@ ErrorOr JPEGLoadingContext::decode() break; } } + + // If image is in YCCK color space, we convert it to CMYK + // and then CMYK code path will handle the rest + if (cinfo.out_color_space == JCS_YCCK) { + for (int i = 0; i < cmyk_bitmap->size().height(); ++i) { + for (int j = 0; j < cmyk_bitmap->size().width(); ++j) { + auto const& cmyk = cmyk_bitmap->scanline(i)[j]; + + auto y = cmyk.c; + auto cb = cmyk.m; + auto cr = cmyk.y; + auto k = cmyk.k; + + int r = y + 1.402f * (cr - 128); + int g = y - 0.3441f * (cb - 128) - 0.7141f * (cr - 128); + int b = y + 1.772f * (cb - 128); + + y = clamp(r, 0, 255); + cb = clamp(g, 0, 255); + cr = clamp(b, 0, 255); + k = 255 - k; + + cmyk_bitmap->scanline(i)[j] = { + y, + cb, + cr, + k, + }; + } + } + } } JOCTET* icc_data_ptr = nullptr;