@@ -121,6 +121,7 @@ static constexpr uint32_t kTAG_wtpt = SetFourByteTag('w', 't', 'p', 't');
121121static constexpr uint32_t kTAG_rTRC = SetFourByteTag(' r' , ' T' , ' R' , ' C' );
122122static constexpr uint32_t kTAG_gTRC = SetFourByteTag(' g' , ' T' , ' R' , ' C' );
123123static constexpr uint32_t kTAG_bTRC = SetFourByteTag(' b' , ' T' , ' R' , ' C' );
124+ static constexpr uint32_t kTAG_chad = SetFourByteTag(' c' , ' h' , ' a' , ' d' );
124125static constexpr uint32_t kTAG_cicp = SetFourByteTag(' c' , ' i' , ' c' , ' p' );
125126static constexpr uint32_t kTAG_cprt = SetFourByteTag(' c' , ' p' , ' r' , ' t' );
126127static constexpr uint32_t kTAG_A2B0 = SetFourByteTag(' A' , ' 2' , ' B' , ' 0' );
@@ -130,27 +131,32 @@ static constexpr uint32_t kTAG_CurveType = SetFourByteTag('c', 'u', 'r', 'v');
130131static constexpr uint32_t kTAG_mABType = SetFourByteTag(' m' , ' A' , ' B' , ' ' );
131132static constexpr uint32_t kTAG_mBAType = SetFourByteTag(' m' , ' B' , ' A' , ' ' );
132133static constexpr uint32_t kTAG_ParaCurveType = SetFourByteTag(' p' , ' a' , ' r' , ' a' );
134+ static constexpr uint32_t kTAG_s15Fixed16ArrayType = SetFourByteTag(' s' , ' f' , ' 3' , ' 2' );
133135
136+ // All these tables are derived using function skcms_PrimariesToXYZD50() at
137+ // https://cs.android.com/android/platform/superproject/main/+/main:external/skia/modules/skcms/skcms.cc
134138static constexpr Matrix3x3 kSRGB = {{
135- // ICC fixed-point (16.16) representation, taken from skcms. Please keep them exactly in sync.
136- // 0.436065674f, 0.385147095f, 0.143066406f,
137- // 0.222488403f, 0.716873169f, 0.060607910f,
138- // 0.013916016f, 0.097076416f, 0.714096069f,
139- {FixedToFloat (0x6FA2 ), FixedToFloat (0x6299 ), FixedToFloat (0x24A0 )},
140- {FixedToFloat (0x38F5 ), FixedToFloat (0xB785 ), FixedToFloat (0x0F84 )},
141- {FixedToFloat (0x0390 ), FixedToFloat (0x18DA ), FixedToFloat (0xB6CF )},
139+ {0 .43606575f , 0 .38515151f , 0 .14307842f },
140+ {0 .22249318f , 0 .71688701f , 0 .06061981f },
141+ {0 .01392392f , 0 .09708132f , 0 .71409936f },
142142}};
143143
144144static constexpr Matrix3x3 kDisplayP3 = {{
145- {0 .515102f , 0 .291965f , 0 .157153f },
146- {0 .241182f , 0 .692236f , 0 .0665819f },
147- {-0 .00104941f , 0 .0418818f , 0 .784378f },
145+ {0 .51514644f , 0 .29200998f , 0 .15713925f },
146+ {0 .24120032f , 0 .69222254f , 0 .06657714f },
147+ {-0 .00105014f , 0 .04187827f , 0 .78427647f },
148148}};
149149
150150static constexpr Matrix3x3 kRec2020 = {{
151- {0 .673459f , 0 .165661f , 0 .125100f },
152- {0 .279033f , 0 .675338f , 0 .0456288f },
153- {-0 .00193139f , 0 .0299794f , 0 .797162f },
151+ {0 .67351546f , 0 .16569726f , 0 .12508295f },
152+ {0 .27905901f , 0 .67531801f , 0 .04562299f },
153+ {-0 .00193243f , 0 .02997783f , 0 .7970592f },
154+ }};
155+
156+ static constexpr Matrix3x3 adaptation_matrix = {{
157+ {1 .04792979f , 0 .02294687f , -0 .05019227f },
158+ {0 .02962781f , 0 .99043443f , -0 .0170738f },
159+ {-0 .00924304f , 0 .01505519f , 0 .75187428f },
154160}};
155161
156162static constexpr uint32_t kCICPPrimariesUnSpecified = 2 ;
@@ -185,19 +191,14 @@ static inline Fixed float_round_to_fixed(float x) {
185191 return float_saturate2int ((float )floor ((double )x * Fixed1 + 0.5 ));
186192}
187193
188- static inline uint16_t float_round_to_unorm16 (float x) {
189- x = x * 65535 .f + 0 .5f ;
190- if (x > 65535 ) return 65535 ;
194+ // Convert a float to a uInt16Number, with 0.0 mapping go 0 and 1.0 mapping to |one|.
195+ static inline uint16_t float_to_uInt16Number (float x, uint16_t one) {
196+ x = x * one + 0.5 ;
197+ if (x > one) return one;
191198 if (x < 0 ) return 0 ;
192199 return static_cast <uint16_t >(x);
193200}
194201
195- static inline void float_to_table16 (const float f, uint8_t * table_16) {
196- *reinterpret_cast <uint16_t *>(table_16) = Endian_SwapBE16 (float_round_to_unorm16 (f));
197- }
198-
199- static inline bool isfinitef_ (float x) { return 0 == x * 0 ; }
200-
201202struct ICCHeader {
202203 // Size of the profile (computed)
203204 uint32_t size;
@@ -243,24 +244,26 @@ struct ICCHeader {
243244
244245class IccHelper {
245246 private:
246- static constexpr uint32_t kTrcTableSize = 65 ;
247247 static constexpr uint32_t kGridSize = 17 ;
248248 static constexpr size_t kNumChannels = 3 ;
249249
250+ static std::shared_ptr<DataStruct> make_empty () { return std::make_shared<DataStruct>(0 ); }
250251 static std::shared_ptr<DataStruct> write_text_tag (const char * text);
251252 static std::string get_desc_string (const uhdr_color_transfer_t tf,
252253 const uhdr_color_gamut_t gamut);
253254 static std::shared_ptr<DataStruct> write_xyz_tag (float x, float y, float z);
254255 static std::shared_ptr<DataStruct> write_trc_tag (const int table_entries, const void * table_16);
255256 static std::shared_ptr<DataStruct> write_trc_tag (const TransferFunction& fn);
256- static float compute_tone_map_gain ( const uhdr_color_transfer_t tf, float L );
257+ static std::shared_ptr<DataStruct> write_chad_tag ( );
257258 static std::shared_ptr<DataStruct> write_cicp_tag (uint32_t color_primaries,
258259 uint32_t transfer_characteristics);
259260 static std::shared_ptr<DataStruct> write_mAB_or_mBA_tag (uint32_t type, bool has_a_curves,
260261 const uint8_t * grid_points,
261- const uint8_t * grid_16);
262- static void compute_lut_entry (const Matrix3x3& src_to_XYZD50, float rgb[3 ]);
262+ const uint8_t * grid_16, bool has_m_curves,
263+ Matrix3x3* toXYZD50);
264+ static void compute_lut_entry (uhdr_color_transfer_t tf, uhdr_color_gamut_t cg, float rgb[3 ]);
263265 static std::shared_ptr<DataStruct> write_clut (const uint8_t * grid_points, const uint8_t * grid_16);
266+ static std::shared_ptr<DataStruct> write_matrix (const Matrix3x3* matrix);
264267
265268 // Checks if a set of xyz tags is equivalent to a 3x3 Matrix. Each input
266269 // tag buffer assumed to be at least kColorantTagSize in size.
@@ -271,7 +274,8 @@ class IccHelper {
271274 // Output includes JPEG embedding identifier and chunk information, but not
272275 // APPx information.
273276 static std::shared_ptr<DataStruct> writeIccProfile (const uhdr_color_transfer_t tf,
274- const uhdr_color_gamut_t gamut);
277+ const uhdr_color_gamut_t gamut,
278+ bool write_tonemap_icc = false );
275279 // NOTE: this function is not robust; it can infer gamuts that IccHelper
276280 // writes out but should not be considered a reference implementation for
277281 // robust parsing of ICC profiles or their gamuts.
0 commit comments