From 6dc5608d958b6ef0810ee0b819f09f0a7ada747d Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 31 Jan 2024 20:55:51 -0500 Subject: [PATCH] image: Allow saving CMYK jpegs `image` can't transform from RGB to CMYK yet, so the only way to do this is by having a CMYK input. For example, this works now (and it does a full decode and re-encode): Build/lagom/bin/image -o out.jpg \ Tests/LibGfx/test-inputs/jpg/buggie-cmyk.jpg Using this to convert `.pam` files written by `mutool extract` to jpegs is a somewhat convenient method of looking at these .pam files. --- Userland/Utilities/image.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Userland/Utilities/image.cpp b/Userland/Utilities/image.cpp index f56a94085a..eb0b0b0b3c 100644 --- a/Userland/Utilities/image.cpp +++ b/Userland/Utilities/image.cpp @@ -125,15 +125,24 @@ static ErrorOr> convert_image_profile(LoadedImage& imag static ErrorOr save_image(LoadedImage& image, StringView out_path, bool ppm_ascii, u8 jpeg_quality) { - if (!image.bitmap.has>()) - return Error::from_string_view("Can't save CMYK bitmaps yet, convert to RGB first with --convert-to-color-profile"sv); - auto& frame = image.bitmap.get>(); - auto stream = [out_path]() -> ErrorOr> { auto output_stream = TRY(Core::File::open(out_path, Core::File::OpenMode::Write)); return Core::OutputBufferedFile::create(move(output_stream)); }; + if (image.bitmap.has>()) { + auto& cmyk_frame = image.bitmap.get>(); + + if (out_path.ends_with(".jpg"sv, CaseSensitivity::CaseInsensitive) || out_path.ends_with(".jpeg"sv, CaseSensitivity::CaseInsensitive)) { + TRY(Gfx::JPEGWriter::encode(*TRY(stream()), *cmyk_frame, { .icc_data = image.icc_data, .quality = jpeg_quality })); + return {}; + } + + return Error::from_string_view("Can save CMYK bitmaps only as .jpg, convert to RGB first with --convert-to-color-profile"sv); + } + + auto& frame = image.bitmap.get>(); + if (out_path.ends_with(".jpg"sv, CaseSensitivity::CaseInsensitive) || out_path.ends_with(".jpeg"sv, CaseSensitivity::CaseInsensitive)) { TRY(Gfx::JPEGWriter::encode(*TRY(stream()), *frame, { .icc_data = image.icc_data, .quality = jpeg_quality })); return {};