Skip to content

Commit

Permalink
icc: update tone mapping
Browse files Browse the repository at this point in the history
- update tone mapping to reflect the implementation in api-0.
- update the icc profile to output results in xyz D50 instead of Lab.
- update the icc profile to output tonemap results in api-0 only.
- add chad tag.

Test: ./ultrahdr_unit_test
  • Loading branch information
ram-mohan committed Dec 14, 2024
1 parent 4cb4626 commit c6ea59d
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 255 deletions.
34 changes: 20 additions & 14 deletions lib/include/ultrahdr/icc.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static constexpr uint32_t kTAG_wtpt = SetFourByteTag('w', 't', 'p', 't');
static constexpr uint32_t kTAG_rTRC = SetFourByteTag('r', 'T', 'R', 'C');
static constexpr uint32_t kTAG_gTRC = SetFourByteTag('g', 'T', 'R', 'C');
static constexpr uint32_t kTAG_bTRC = SetFourByteTag('b', 'T', 'R', 'C');
static constexpr uint32_t kTAG_chad = SetFourByteTag('c', 'h', 'a', 'd');
static constexpr uint32_t kTAG_cicp = SetFourByteTag('c', 'i', 'c', 'p');
static constexpr uint32_t kTAG_cprt = SetFourByteTag('c', 'p', 'r', 't');
static constexpr uint32_t kTAG_A2B0 = SetFourByteTag('A', '2', 'B', '0');
Expand All @@ -130,6 +131,7 @@ static constexpr uint32_t kTAG_CurveType = SetFourByteTag('c', 'u', 'r', 'v');
static constexpr uint32_t kTAG_mABType = SetFourByteTag('m', 'A', 'B', ' ');
static constexpr uint32_t kTAG_mBAType = SetFourByteTag('m', 'B', 'A', ' ');
static constexpr uint32_t kTAG_ParaCurveType = SetFourByteTag('p', 'a', 'r', 'a');
static constexpr uint32_t kTAG_s15Fixed16ArrayType = SetFourByteTag('s', 'f', '3', '2');

static constexpr Matrix3x3 kSRGB = {{
// ICC fixed-point (16.16) representation, taken from skcms. Please keep them exactly in sync.
Expand All @@ -153,6 +155,12 @@ static constexpr Matrix3x3 kRec2020 = {{
{-0.00193139f, 0.0299794f, 0.797162f},
}};

static constexpr Matrix3x3 bradford = {{
{1.047886, 0.022919, -0.050216},
{0.029582, 0.990484, -0.017079},
{-0.009252, 0.015073, 0.751678},
}};

static constexpr uint32_t kCICPPrimariesUnSpecified = 2;
static constexpr uint32_t kCICPPrimariesSRGB = 1;
static constexpr uint32_t kCICPPrimariesP3 = 12;
Expand Down Expand Up @@ -185,19 +193,14 @@ static inline Fixed float_round_to_fixed(float x) {
return float_saturate2int((float)floor((double)x * Fixed1 + 0.5));
}

static inline uint16_t float_round_to_unorm16(float x) {
x = x * 65535.f + 0.5f;
if (x > 65535) return 65535;
// Convert a float to a uInt16Number, with 0.0 mapping go 0 and 1.0 mapping to |one|.
static inline uint16_t float_to_uInt16Number(float x, uint16_t one) {
x = x * one + 0.5;
if (x > one) return one;
if (x < 0) return 0;
return static_cast<uint16_t>(x);
}

static inline void float_to_table16(const float f, uint8_t* table_16) {
*reinterpret_cast<uint16_t*>(table_16) = Endian_SwapBE16(float_round_to_unorm16(f));
}

static inline bool isfinitef_(float x) { return 0 == x * 0; }

struct ICCHeader {
// Size of the profile (computed)
uint32_t size;
Expand Down Expand Up @@ -243,24 +246,26 @@ struct ICCHeader {

class IccHelper {
private:
static constexpr uint32_t kTrcTableSize = 65;
static constexpr uint32_t kGridSize = 17;
static constexpr size_t kNumChannels = 3;

static std::shared_ptr<DataStruct> make_empty() { return std::make_shared<DataStruct>(0); }
static std::shared_ptr<DataStruct> write_text_tag(const char* text);
static std::string get_desc_string(const uhdr_color_transfer_t tf,
const uhdr_color_gamut_t gamut);
static std::shared_ptr<DataStruct> write_xyz_tag(float x, float y, float z);
static std::shared_ptr<DataStruct> write_trc_tag(const int table_entries, const void* table_16);
static std::shared_ptr<DataStruct> write_trc_tag(const TransferFunction& fn);
static float compute_tone_map_gain(const uhdr_color_transfer_t tf, float L);
static std::shared_ptr<DataStruct> write_chad_tag();
static std::shared_ptr<DataStruct> write_cicp_tag(uint32_t color_primaries,
uint32_t transfer_characteristics);
static std::shared_ptr<DataStruct> write_mAB_or_mBA_tag(uint32_t type, bool has_a_curves,
const uint8_t* grid_points,
const uint8_t* grid_16);
static void compute_lut_entry(const Matrix3x3& src_to_XYZD50, float rgb[3]);
const uint8_t* grid_16, bool has_m_curves,
Matrix3x3* toXYZD50);
static void compute_lut_entry(uhdr_color_transfer_t tf, uhdr_color_gamut_t cg, float rgb[3]);
static std::shared_ptr<DataStruct> write_clut(const uint8_t* grid_points, const uint8_t* grid_16);
static std::shared_ptr<DataStruct> write_matrix(const Matrix3x3* matrix);

// Checks if a set of xyz tags is equivalent to a 3x3 Matrix. Each input
// tag buffer assumed to be at least kColorantTagSize in size.
Expand All @@ -271,7 +276,8 @@ class IccHelper {
// Output includes JPEG embedding identifier and chunk information, but not
// APPx information.
static std::shared_ptr<DataStruct> writeIccProfile(const uhdr_color_transfer_t tf,
const uhdr_color_gamut_t gamut);
const uhdr_color_gamut_t gamut,
bool write_tonemap_icc = false);
// NOTE: this function is not robust; it can infer gamuts that IccHelper
// writes out but should not be considered a reference implementation for
// robust parsing of ICC profiles or their gamuts.
Expand Down
4 changes: 3 additions & 1 deletion lib/include/ultrahdr/jpegr.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,12 @@ class JpegR {
*
* \param[in] gainmap_img gainmap image descriptor
* \param[in] jpeg_enc_obj jpeg encoder object handle
* \param[in] write_tonemap_icc write tonemap details in icc header
*
* \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
*/
uhdr_error_info_t compressGainMap(uhdr_raw_image_t* gainmap_img, JpegEncoderHelper* jpeg_enc_obj);
uhdr_error_info_t compressGainMap(uhdr_raw_image_t* gainmap_img, JpegEncoderHelper* jpeg_enc_obj,
bool write_tonemap_icc = false);

/*!\brief This method is called to separate base image and gain map image from compressed
* ultrahdr image
Expand Down
Loading

0 comments on commit c6ea59d

Please sign in to comment.