@@ -330,8 +330,12 @@ read_info(png_structp& sp, png_infop& ip, int& bit_depth, int& color_type,
330330 {
331331 png_byte pri = 0 , trc = 0 , mtx = 0 , vfr = 0 ;
332332 if (png_get_cICP (sp, ip, &pri, &trc, &mtx, &vfr)) {
333- int cicp[4 ] = { pri, trc, mtx, vfr };
333+ const int cicp[4 ] = { pri, trc, mtx, vfr };
334334 spec.attribute (CICP_ATTR, TypeDesc (TypeDesc::INT, 4 ), cicp);
335+ const ColorConfig& colorconfig (ColorConfig::default_colorconfig ());
336+ string_view interop_id = colorconfig.get_color_interop_id (cicp);
337+ if (!interop_id.empty ())
338+ spec.attribute (" oiio:ColorSpace" , interop_id);
335339 }
336340 }
337341#endif
@@ -608,7 +612,8 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
608612 string_view colorspace = spec.get_string_attribute (" oiio:ColorSpace" ,
609613 " srgb_rec709_scene" );
610614 const ColorConfig& colorconfig (ColorConfig::default_colorconfig ());
611- srgb = false ;
615+ OIIO_MAYBE_UNUSED bool wrote_colorspace = false ;
616+ srgb = false ;
612617 if (colorconfig.equivalent (colorspace, " srgb_rec709_scene" )) {
613618 srgb = true ;
614619 gamma = 1 .0f ;
@@ -628,7 +633,8 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
628633 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
629634 return " Could not set PNG gAMA chunk" ;
630635 png_set_gAMA (sp, ip, 1.0 );
631- srgb = false ;
636+ srgb = false ;
637+ wrote_colorspace = true ;
632638 } else if (Strutil::istarts_with (colorspace, " Gamma" )) {
633639 // Back compatible, this is DEPRECATED(3.1)
634640 Strutil::parse_word (colorspace);
@@ -638,24 +644,28 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
638644 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
639645 return " Could not set PNG gAMA chunk" ;
640646 png_set_gAMA (sp, ip, 1 .0f / gamma);
641- srgb = false ;
647+ srgb = false ;
648+ wrote_colorspace = true ;
642649 } else if (colorconfig.equivalent (colorspace, " g22_rec709_scene" )) {
643650 gamma = 2 .2f ;
644651 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
645652 return " Could not set PNG gAMA chunk" ;
646653 png_set_gAMA (sp, ip, 1 .0f / gamma);
647- srgb = false ;
654+ srgb = false ;
655+ wrote_colorspace = true ;
648656 } else if (colorconfig.equivalent (colorspace, " g18_rec709_scene" )) {
649657 gamma = 1 .8f ;
650658 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
651659 return " Could not set PNG gAMA chunk" ;
652660 png_set_gAMA (sp, ip, 1 .0f / gamma);
653- srgb = false ;
661+ srgb = false ;
662+ wrote_colorspace = true ;
654663 } else if (colorconfig.equivalent (colorspace, " srgb_rec709_scene" )) {
655664 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
656665 return " Could not set PNG gAMA and cHRM chunk" ;
657666 png_set_sRGB_gAMA_and_cHRM (sp, ip, PNG_sRGB_INTENT_ABSOLUTE);
658- srgb = true ;
667+ srgb = true ;
668+ wrote_colorspace = true ;
659669 }
660670
661671 // Write ICC profile, if we have anything
@@ -667,8 +677,10 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
667677 return " Could not set PNG iCCP chunk" ;
668678 unsigned char * icc_profile
669679 = (unsigned char *)icc_profile_parameter->data ();
670- if (icc_profile && length)
680+ if (icc_profile && length) {
671681 png_set_iCCP (sp, ip, " Embedded Profile" , 0 , icc_profile, length);
682+ wrote_colorspace = true ;
683+ }
672684 }
673685
674686 if (false && !spec.find_attribute (" DateTime" )) {
@@ -724,13 +736,17 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
724736 }
725737
726738#ifdef PNG_cICP_SUPPORTED
739+ // Only automatically determine CICP from oiio::ColorSpace if we didn't
740+ // write colorspace metadata yet.
727741 const ParamValue* p = spec.find_attribute (CICP_ATTR,
728742 TypeDesc (TypeDesc::INT, 4 ));
729- if (p) {
730- const int * int_vals = static_cast <const int *>(p->data ());
743+ cspan<int > cicp = (p) ? p->as_cspan <int >()
744+ : (!wrote_colorspace) ? colorconfig.get_cicp (colorspace)
745+ : cspan<int >();
746+ if (!cicp.empty ()) {
731747 png_byte vals[4 ];
732748 for (int i = 0 ; i < 4 ; ++i)
733- vals[i] = static_cast <png_byte>(int_vals [i]);
749+ vals[i] = static_cast <png_byte>(cicp [i]);
734750 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
735751 return " Could not set PNG cICP chunk" ;
736752 // libpng will only write the chunk if the third byte is 0
0 commit comments