diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index 63e94c9ef8..58670a5886 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -284,6 +284,8 @@ macro (oiio_add_all_tests) FOUNDVAR OPENJPEG_FOUND IMAGEDIR j2kp4files_v1_5 URL http://www.itu.int/net/ITU-T/sigdb/speimage/ImageForm-s.aspx?val=10100803) + oiio_add_tests (jxl + FOUNDVAR JXL_FOUND) set (all_openexr_tests openexr-suite openexr-multires openexr-chroma openexr-decreasingy openexr-v2 openexr-window perchannel oiiotool-deep) diff --git a/src/jpegxl.imageio/jxlinput.cpp b/src/jpegxl.imageio/jxlinput.cpp index 2be2efaf4c..9ed3b1c45b 100644 --- a/src/jpegxl.imageio/jxlinput.cpp +++ b/src/jpegxl.imageio/jxlinput.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,7 @@ class JxlInput final : public ImageInput { std::string m_filename; int m_next_scanline; // Which scanline is the next to read? uint32_t m_channels; + JxlColorEncoding m_color_encoding; JxlDecoderPtr m_decoder; JxlResizableParallelRunnerPtr m_runner; std::unique_ptr m_config; // Saved copy of configuration spec @@ -346,6 +348,23 @@ JxlInput::open(const std::string& name, ImageSpec& newspec) m_spec = ImageSpec(info.xsize, info.ysize, m_channels, m_data_type); + if (m_icc_profile.size() && m_icc_profile.data()) { + m_spec.attribute("ICCProfile", + TypeDesc(TypeDesc::UINT8, m_icc_profile.size()), + m_icc_profile.data()); + std::string errormsg; + + bool ok = decode_icc_profile(cspan(m_icc_profile.data(), + m_icc_profile.size()), + m_spec, errormsg); + + if (!ok && OIIO::get_int_attribute("imageinput:strict")) { + errorfmt("Possible corrupt file, could not decode ICC profile: {}\n", + errormsg); + return false; + } + } + newspec = m_spec; return true; } diff --git a/src/jpegxl.imageio/jxloutput.cpp b/src/jpegxl.imageio/jxloutput.cpp index f1b47a0d3b..c5802e3b27 100644 --- a/src/jpegxl.imageio/jxloutput.cpp +++ b/src/jpegxl.imageio/jxloutput.cpp @@ -538,6 +538,21 @@ JxlOutput::save_image(const void* data) return false; } + // Write the ICC profile, if available + const ParamValue* icc_profile_parameter = m_spec.find_attribute( + "ICCProfile"); + if (icc_profile_parameter != nullptr) { + unsigned char* icc_profile + = (unsigned char*)icc_profile_parameter->data(); + uint32_t length = icc_profile_parameter->type().size(); + if (icc_profile && length) { + if (JXL_ENC_SUCCESS + != JxlEncoderSetICCProfile(m_encoder.get(), icc_profile, + length)) { + errorfmt("JxlEncoderSetICCProfile failed\n"); + } + } + } // No more image frames nor metadata boxes to add DBG std::cout << "calling JxlEncoderCloseInput()\n"; diff --git a/testsuite/jxl/ref/out.txt b/testsuite/jxl/ref/out.txt new file mode 100644 index 0000000000..040910d3c9 --- /dev/null +++ b/testsuite/jxl/ref/out.txt @@ -0,0 +1,21 @@ +Reading tahoe-icc.jxl +tahoe-icc.jxl : 128 x 96, 3 channel, uint8 jpegxl + SHA-1: 069F1A3E5567349C2D34E535B29913029EF1B09C + channel list: R, G, B + ICCProfile: 0, 0, 2, 48, 65, 68, 66, 69, 2, 16, 0, 0, 109, 110, 116, 114, ... [560 x uint8] + ICCProfile:attributes: "Reflective, Glossy, Positive, Color" + ICCProfile:cmm_type: 1094992453 + ICCProfile:color_space: "RGB" + ICCProfile:copyright: "Copyright 1999 Adobe Systems Incorporated" + ICCProfile:creation_date: "1999:06:03 00:00:00" + ICCProfile:creator_signature: "41444245" + ICCProfile:device_class: "Display device profile" + ICCProfile:flags: "Not Embedded, Independent" + ICCProfile:manufacturer: "6e6f6e65" + ICCProfile:model: "0" + ICCProfile:platform_signature: "Apple Computer, Inc." + ICCProfile:profile_connection_space: "XYZ" + ICCProfile:profile_description: "Adobe RGB (1998)" + ICCProfile:profile_size: 560 + ICCProfile:profile_version: "2.1.0" + ICCProfile:rendering_intent: "Perceptual" diff --git a/testsuite/jxl/ref/test-jxl.icc b/testsuite/jxl/ref/test-jxl.icc new file mode 100644 index 0000000000..fe2cab55e6 Binary files /dev/null and b/testsuite/jxl/ref/test-jxl.icc differ diff --git a/testsuite/jxl/run.py b/testsuite/jxl/run.py new file mode 100755 index 0000000000..d112da67b1 --- /dev/null +++ b/testsuite/jxl/run.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +# Copyright Contributors to the OpenImageIO project. +# SPDX-License-Identifier: Apache-2.0 +# https://github.com/AcademySoftwareFoundation/OpenImageIO + + +# Test adding and extracting ICC profiles +command += oiiotool ("../common/tahoe-tiny.tif --iccread ref/test-jxl.icc -o tahoe-icc.jxl") +command += info_command ("tahoe-icc.jxl", safematch=True) +command += oiiotool ("tahoe-icc.jxl --iccwrite test-jxl.icc") + +outputs = [ + "test-jxl.icc", + "out.txt" +]