@@ -40,7 +40,6 @@ For further information see the following mailing list threads:
4040OIIO_PLUGIN_NAMESPACE_BEGIN
4141
4242#define ICC_PROFILE_ATTR " ICCProfile"
43- #define CICP_ATTR " CICP"
4443
4544namespace PNG_pvt {
4645
@@ -330,8 +329,9 @@ read_info(png_structp& sp, png_infop& ip, int& bit_depth, int& color_type,
330329 {
331330 png_byte pri = 0 , trc = 0 , mtx = 0 , vfr = 0 ;
332331 if (png_get_cICP (sp, ip, &pri, &trc, &mtx, &vfr)) {
333- int cicp[4 ] = { pri, trc, mtx, vfr };
334- spec.attribute (CICP_ATTR, TypeDesc (TypeDesc::INT, 4 ), cicp);
332+ const int cicp[4 ] = { pri, trc, mtx, vfr };
333+ const ColorConfig& colorconfig (ColorConfig::default_colorconfig ());
334+ colorconfig.set_colorspace_cicp (spec, cicp);
335335 }
336336 }
337337#endif
@@ -608,7 +608,8 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
608608 string_view colorspace = spec.get_string_attribute (" oiio:ColorSpace" ,
609609 " srgb_rec709_scene" );
610610 const ColorConfig& colorconfig (ColorConfig::default_colorconfig ());
611- srgb = false ;
611+ bool wrote_colorspace = false ;
612+ srgb = false ;
612613 if (colorconfig.equivalent (colorspace, " srgb_rec709_scene" )) {
613614 srgb = true ;
614615 gamma = 1 .0f ;
@@ -628,7 +629,8 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
628629 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
629630 return " Could not set PNG gAMA chunk" ;
630631 png_set_gAMA (sp, ip, 1.0 );
631- srgb = false ;
632+ srgb = false ;
633+ wrote_colorspace = true ;
632634 } else if (Strutil::istarts_with (colorspace, " Gamma" )) {
633635 // Back compatible, this is DEPRECATED(3.1)
634636 Strutil::parse_word (colorspace);
@@ -638,24 +640,28 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
638640 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
639641 return " Could not set PNG gAMA chunk" ;
640642 png_set_gAMA (sp, ip, 1 .0f / gamma);
641- srgb = false ;
643+ srgb = false ;
644+ wrote_colorspace = true ;
642645 } else if (colorconfig.equivalent (colorspace, " g22_rec709_scene" )) {
643646 gamma = 2 .2f ;
644647 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
645648 return " Could not set PNG gAMA chunk" ;
646649 png_set_gAMA (sp, ip, 1 .0f / gamma);
647- srgb = false ;
650+ srgb = false ;
651+ wrote_colorspace = true ;
648652 } else if (colorconfig.equivalent (colorspace, " g18_rec709_scene" )) {
649653 gamma = 1 .8f ;
650654 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
651655 return " Could not set PNG gAMA chunk" ;
652656 png_set_gAMA (sp, ip, 1 .0f / gamma);
653- srgb = false ;
657+ srgb = false ;
658+ wrote_colorspace = true ;
654659 } else if (colorconfig.equivalent (colorspace, " srgb_rec709_scene" )) {
655660 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
656661 return " Could not set PNG gAMA and cHRM chunk" ;
657662 png_set_sRGB_gAMA_and_cHRM (sp, ip, PNG_sRGB_INTENT_ABSOLUTE);
658- srgb = true ;
663+ srgb = true ;
664+ wrote_colorspace = true ;
659665 }
660666
661667 // Write ICC profile, if we have anything
@@ -667,8 +673,10 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
667673 return " Could not set PNG iCCP chunk" ;
668674 unsigned char * icc_profile
669675 = (unsigned char *)icc_profile_parameter->data ();
670- if (icc_profile && length)
676+ if (icc_profile && length) {
671677 png_set_iCCP (sp, ip, " Embedded Profile" , 0 , icc_profile, length);
678+ wrote_colorspace = true ;
679+ }
672680 }
673681
674682 if (false && !spec.find_attribute (" DateTime" )) {
@@ -724,13 +732,16 @@ write_info(png_structp& sp, png_infop& ip, int& color_type, ImageSpec& spec,
724732 }
725733
726734#ifdef PNG_cICP_SUPPORTED
727- const ParamValue* p = spec.find_attribute (CICP_ATTR,
728- TypeDesc (TypeDesc::INT, 4 ));
729- if (p) {
730- const int * int_vals = static_cast <const int *>(p->data ());
735+ // Only automatically determine CICP from oiio::ColorSpace if we didn't
736+ // write colorspace metadata yet.
737+ const bool auto_cicp = !wrote_colorspace;
738+ int cicp[4 ];
739+ if (colorconfig.get_colorspace_cicp (spec, auto_cicp, cicp)) {
740+ // Matrix must be RGB according to PNG spec v3
741+ cicp[2 ] = 0 ;
731742 png_byte vals[4 ];
732743 for (int i = 0 ; i < 4 ; ++i)
733- vals[i] = static_cast <png_byte>(int_vals [i]);
744+ vals[i] = static_cast <png_byte>(cicp [i]);
734745 if (setjmp (png_jmpbuf (sp))) // NOLINT(cert-err52-cpp)
735746 return " Could not set PNG cICP chunk" ;
736747 // libpng will only write the chunk if the third byte is 0
0 commit comments