1616#include < cassert>
1717#include < cstdio>
1818
19+ #include < OpenImageIO/color.h>
1920#include < OpenImageIO/filesystem.h>
2021#include < OpenImageIO/fmath.h>
2122#include < OpenImageIO/imageio.h>
@@ -54,7 +55,6 @@ class JxlInput final : public ImageInput {
5455 std::string m_filename;
5556 int m_next_scanline; // Which scanline is the next to read?
5657 uint32_t m_channels;
57- JxlColorEncoding m_color_encoding;
5858 JxlDecoderPtr m_decoder;
5959 JxlResizableParallelRunnerPtr m_runner;
6060 std::unique_ptr<ImageSpec> m_config; // Saved copy of configuration spec
@@ -224,6 +224,8 @@ JxlInput::open(const std::string& name, ImageSpec& newspec)
224224 JxlDataType jxl_data_type;
225225 TypeDesc m_data_type;
226226 uint32_t bits = 0 ;
227+ JxlColorEncoding color_encoding {};
228+ bool have_color_encoding = false ;
227229
228230 for (;;) {
229231 JxlDecoderStatus status = JxlDecoderProcessInput (m_decoder.get ());
@@ -300,6 +302,16 @@ JxlInput::open(const std::string& name, ImageSpec& newspec)
300302 errorfmt (" JxlDecoderGetColorAsICCProfile failed\n " );
301303 return false ;
302304 }
305+
306+ // Get the color encoding of the pixel data
307+ // This will return JXL_DEC_ERR for a valid file without color
308+ // encoding information, so don't report an error.
309+ if (JXL_DEC_SUCCESS
310+ == JxlDecoderGetColorAsEncodedProfile (
311+ m_decoder.get (), JXL_COLOR_PROFILE_TARGET_DATA,
312+ &color_encoding)) {
313+ have_color_encoding = true ;
314+ }
303315 } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) {
304316 DBG std::cout << " JXL_DEC_NEED_IMAGE_OUT_BUFFER\n " ;
305317
@@ -348,6 +360,7 @@ JxlInput::open(const std::string& name, ImageSpec& newspec)
348360
349361 m_spec = ImageSpec (info.xsize , info.ysize , m_channels, m_data_type);
350362
363+ // Read ICC profile
351364 if (m_icc_profile.size () && m_icc_profile.data ()) {
352365 m_spec.attribute (" ICCProfile" ,
353366 TypeDesc (TypeDesc::UINT8, m_icc_profile.size ()),
@@ -365,6 +378,21 @@ JxlInput::open(const std::string& name, ImageSpec& newspec)
365378 }
366379 }
367380
381+ // Read CICP from color encoding. Custom primaries, custom white point and
382+ // arbitrary gamma not supported currently.
383+ if (have_color_encoding && color_encoding.primaries != JXL_PRIMARIES_CUSTOM
384+ && color_encoding.white_point != JXL_WHITE_POINT_CUSTOM
385+ && color_encoding.transfer_function != JXL_TRANSFER_FUNCTION_GAMMA) {
386+ const int cicp[4 ] = { color_encoding.primaries ,
387+ color_encoding.transfer_function , 0 /* RGB */ ,
388+ 1 /* Full range */ };
389+ m_spec.attribute (" CICP" , TypeDesc (TypeDesc::INT, 4 ), cicp);
390+ const ColorConfig& colorconfig (ColorConfig::default_colorconfig ());
391+ string_view interop_id = colorconfig.get_color_interop_id (cicp);
392+ if (!interop_id.empty ())
393+ m_spec.attribute (" oiio:ColorSpace" , interop_id);
394+ }
395+
368396 newspec = m_spec;
369397 return true ;
370398}
0 commit comments