1+ #ifndef  SRC_JZAZBZ_HLSL
2+ #define  SRC_JZAZBZ_HLSL
3+ 
4+ #include  "Color.hlsl" 
5+ 
6+ // ----------------------------------------------------------------------------- 
7+ // Jzazbz 
8+ //  
9+ // Reference: 
10+ // Muhammad Safdar, Guihua Cui, Youn Jin Kim, and Ming Ronnier Luo, 
11+ // "Perceptually uniform color space for image signals including high dynamic 
12+ // range and wide gamut," Opt. Express 25, 15131-15151 (2017) 
13+ // ----------------------------------------------------------------------------- 
14+ namespace  JzAzBz
15+ {
16+     #define  JZAZBZ_EXPONENT_SCALE_FACTOR 1.7f  // Scale factor for exponent 
17+ 
18+     // Input: linear rgb with a paper white of ~100 nits (SDR neutral) 
19+     // Jz Luminance-like 
20+     // Az Red–Green opponent axis 
21+     // Bz Blue–Yellow opponent axis 
22+     float3  rgbToJzazbz (float3  rgb, uint  colorSpace = CS_DEFAULT)
23+     {
24+         // The matrix below is for BT.2020 input. 
25+         // The transforms should fold with the ones below when compiled. 
26+         if  (colorSpace == CS_BT709)
27+         {
28+             rgb = BT709_To_BT2020 (rgb);
29+         }
30+         else  if  (colorSpace == CS_AP1)
31+         {
32+             rgb = float3 (1 , 0 , 1 ); // Not done 
33+         }
34+ 
35+         float3  lms;
36+         lms.x = rgb[0 ] * 0.530004f  + rgb[1 ] * 0.355704f  + rgb[2 ] * 0.086090f ;
37+         lms.y = rgb[0 ] * 0.289388f  + rgb[1 ] * 0.525395f  + rgb[2 ] * 0.157481f ;
38+         lms.z = rgb[0 ] * 0.091098f  + rgb[1 ] * 0.147588f  + rgb[2 ] * 0.734234f ;
39+ 
40+         float3  lmsPQ = Linear_to_PQ (lms / (HDR10_MaxWhiteNits / Rec709_WhiteLevelNits), GCT_MIRROR, JZAZBZ_EXPONENT_SCALE_FACTOR);
41+ 
42+         float  iz = 0.5f  * lmsPQ.x + 0.5f  * lmsPQ.y;
43+ 
44+         float3  jab;
45+         jab.x = (0.44f  * iz) / (1.0f  - 0.56f  * iz) - 1. 6295499532821566e-11f ;
46+         jab.y = 3.524000f  * lmsPQ.x - 4.066708f  * lmsPQ.y + 0.542708f  * lmsPQ.z;
47+         jab.z = 0.199076f  * lmsPQ.x + 1.096799f  * lmsPQ.y - 1.295875f  * lmsPQ.z;
48+         return  jab;
49+     }
50+ 
51+     // Output: linear rgb 
52+     float3  jzazbzToRgb (float3  jab, uint  colorSpace = CS_DEFAULT)
53+     {
54+         float  jz = jab[0 ] + 1. 6295499532821566e-11f ;
55+         float  iz = jz / (0.44f  + 0.56f  * jz);
56+         float  a  = jab[1 ];
57+         float  b  = jab[2 ];
58+ 
59+         float3  lms;
60+         lms.x = iz + a * 1. 386050432715393e-1f  + b * 5. 804731615611869e-2f ;
61+         lms.y = iz + a * -1. 386050432715393e-1f  + b * -5. 804731615611869e-2f ;
62+         lms.z = iz + a * -9. 601924202631895e-2f  + b * -8. 118918960560390e-1f ;
63+ 
64+         float3  lmsLin = PQ_to_Linear (lms, GCT_MIRROR, JZAZBZ_EXPONENT_SCALE_FACTOR) * (HDR10_MaxWhiteNits / Rec709_WhiteLevelNits);
65+ 
66+         float3  rgb;
67+         rgb.x = lmsLin.x * 2.990669f  + lmsLin.y * -2.049742f  + lmsLin.z * 0.088977f ;
68+         rgb.y = lmsLin.x * -1.634525f  + lmsLin.y * 3.145627f  + lmsLin.z * -0.483037f ;
69+         rgb.z = lmsLin.x * -0.042505f  + lmsLin.y * -0.377983f  + lmsLin.z * 1.448019f ;
70+         if  (colorSpace == CS_BT709)
71+         {
72+             rgb = BT2020_To_BT709 (rgb);
73+         }
74+         return  rgb;
75+     }
76+ }
77+ 
78+ #endif  // SRC_JZAZBZ_HLSL 
0 commit comments