import numpy as np
# PQ stuff
paper_white_nits = 0.5 # still no idea what this is, but it's some kind of dial
bt709_scale_factor = 59.5208
m1 = 0.1593017578125
m2 = 78.84375
c1 = 0.8359375
c2 = 18.8515625
c3 = 18.6875
def bt1886_eotf(x):
return 100. * pow(x, 2.4)
def bt709_oetf(x):
s1 = x * 4.5
s2 = pow(x, 1. / 2.2) * 1.099 - 0.099
return s1 if x <= 0.018 else s2
def pq_ootf(x):
return bt1886_eotf(bt709_oetf(x * bt709_scale_factor))
def pq_inv_eotf(x):
ym = pow(x, m1);
return pow((c1 + c2 * ym) / (1.0 + c3 * ym), m2)
# color stuff
mat_srgb_to_bt2020 = [
[ 0.627403896, 0.329283039, 0.0433130657],
[ 0.0690972894, 0.919540395, 0.0113623156],
[ 0.0163914389, 0.0880133077, 0.895595253]]
# womp womp
srgb_lin_val = [2.56, 0.15, 0.85]
rec2020_lin_val = np.matmul(mat_srgb_to_bt2020, srgb_lin_val)
pq_val = [pq_inv_eotf(pq_ootf(x) * (paper_white_nits /10000.)) for x in rec2020_lin_val]
print("scene-linear sRGB color", srgb_lin_val)
print("scene-linear Rec. 2020 value:", rec2020_lin_val)
print("PQ value:", pq_val)