Skip to content

Instantly share code, notes, and snippets.

@asahilina
Created May 26, 2022 07:41
Show Gist options
  • Save asahilina/2a80fe5e4476de56412508ec78245b9b to your computer and use it in GitHub Desktop.
Save asahilina/2a80fe5e4476de56412508ec78245b9b to your computer and use it in GitHub Desktop.
# 0 (BT.601 full range -> RGB)
[[ 1.00000000e+00 -9.76562500e-04 1.40173340e+00 -7.00378418e-01]
[ 1.00000000e+00 -3.43750000e-01 -7.14111328e-01 5.28930664e-01]
[ 1.00000000e+00 1.77221680e+00 9.76562500e-04 -8.86596680e-01]]
Tests (YUV scale=255):
(0, 128, 128) -> [ 0.70037842 -0.52893066 0.88659668]
(255, 128, 128) -> [255.70037842 254.47106934 255.88659668]
(256, 128, 128) -> [256.70037842 255.47106934 256.88659668]
Tests (YUV scale=256):
(0, 128, 128) -> [0. 0. 0.]
(255, 128, 128) -> [254.00390625 254.00390625 254.00390625]
(256, 128, 128) -> [255. 255. 255.]
# 1 (BT.709 full range -> RGB)
[[ 1.00000000e+00 -1.22070312e-04 1.57470703e+00 -7.87292480e-01]
[ 1.00000000e+00 -1.87255859e-01 -4.68139648e-01 3.27697754e-01]
[ 1.00000000e+00 1.85559082e+00 1.22070312e-04 -9.27856445e-01]]
Tests (YUV scale=255):
(0, 128, 128) -> [ 0.78729248 -0.32769775 0.92785645]
(255, 128, 128) -> [255.78729248 254.67230225 255.92785645]
(256, 128, 128) -> [256.78729248 255.67230225 256.92785645]
Tests (YUV scale=256):
(0, 128, 128) -> [0. 0. 0.]
(255, 128, 128) -> [254.00390625 254.00390625 254.00390625]
(256, 128, 128) -> [255. 255. 255.]
# 2 (BT.2020 full range -> RGB)
[[ 1.00000000e+00 0.00000000e+00 1.47460938e+00 -7.37304688e-01]
[ 1.00000000e+00 -1.64550781e-01 -5.71289062e-01 3.67919922e-01]
[ 1.00000000e+00 1.88134766e+00 -1.22070312e-04 -9.40612793e-01]]
Tests (YUV scale=255):
(0, 128, 128) -> [ 0.73730469 -0.36791992 0.94061279]
(255, 128, 128) -> [255.73730469 254.63208008 255.94061279]
(256, 128, 128) -> [256.73730469 255.63208008 256.94061279]
Tests (YUV scale=256):
(0, 128, 128) -> [0. 0. 0.]
(255, 128, 128) -> [254.00390625 254.00390625 254.00390625]
(256, 128, 128) -> [255. 255. 255.]
# 3 (BT.601 limited range -> RGB)
[[ 1.16894531e+00 -1.09863281e-03 1.60192871e+00 -8.73474121e-01]
[ 1.16894531e+00 -3.92822266e-01 -8.16162109e-01 5.31433105e-01]
[ 1.16894531e+00 2.02526855e+00 1.09863281e-03 -1.08624268e+00]]
Tests (YUV scale=255):
(16, 128, 128) -> [ 0.87347412 -0.53143311 1.08624268]
(235, 128, 128) -> [256.87249756 255.46759033 257.08526611]
Tests (YUV scale=256):
(16, 128, 128) -> [0. 0. 0.]
(235, 128, 128) -> [254.99902725 254.99902725 254.99902725]
# 4 (BT.709 limited range -> RGB)
[[ 1.16894531e+00 -1.22070312e-04 1.79968262e+00 -9.72839355e-01]
[ 1.16894531e+00 -2.13989258e-01 -5.35034180e-01 3.01452637e-01]
[ 1.16894531e+00 2.12072754e+00 1.22070312e-04 -1.13348389e+00]]
Tests (YUV scale=255):
(16, 128, 128) -> [ 0.97283936 -0.30145264 1.13348389]
(235, 128, 128) -> [256.97186279 255.6975708 257.13250732]
Tests (YUV scale=256):
(16, 128, 128) -> [0. 0. 0.]
(235, 128, 128) -> [254.99902725 254.99902725 254.99902725]
# 5 (BT.2020 limited range -> RGB)
[[ 1.16894531e+00 0.00000000e+00 1.68530273e+00 -9.15710449e-01]
[ 1.16894531e+00 -1.87988281e-01 -6.52954102e-01 3.47412109e-01]
[ 1.16894531e+00 2.15014648e+00 -1.22070312e-04 -1.14807129e+00]]
Tests (YUV scale=255):
(16, 128, 128) -> [ 0.91571045 -0.34741211 1.14807129]
(235, 128, 128) -> [256.91473389 255.65161133 257.14709473]
Tests (YUV scale=256):
(16, 128, 128) -> [0. 0. 0.]
(235, 128, 128) -> [254.99902725 254.99902725 254.99902725]
# 6 (Unknown YUV->RGB)
[[ 1.14978027 0. 1.40551758 -0.85095215]
[ 1.14978027 -0.3449707 -0.71594238 0.38226318]
[ 1.14978027 1.77648926 0. -1.03643799]]
Tests (YUV scale=255):
(16, 128, 128) -> [-18.69006348 -19.92327881 -18.50457764]
(235, 128, 128) -> [233.11181641 231.87860107 233.29730225]
Tests (YUV scale=256):
(16, 128, 128) -> [-19.46468353 -19.46468353 -19.46468353]
(235, 128, 128) -> [231.35359526 231.35359526 231.35359526]
# 7 (null)
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Tests (YUV scale=255):
(16, 128, 128) -> [0. 0. 0.]
(235, 128, 128) -> [0. 0. 0.]
Tests (YUV scale=256):
(16, 128, 128) -> [0. 0. 0.]
(235, 128, 128) -> [0. 0. 0.]
# 8 (RGB -> BT.601 full range)
[[ 0.29898071 0.58700562 0.11401367 0. ]
[-0.16897583 -0.33099365 0.49996948 0.5 ]
[ 0.5 -0.41900635 -0.08099365 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 0. 127.5 127.5]
(255, 255, 255) -> [255. 127.5 127.5]
Tests (YUV scale=256):
(0, 0, 0) -> [ 0. 128. 128.]
(255, 255, 255) -> [256. 128. 128.]
# 9 (RGB -> BT.709 full range)
[[ 0.21261597 0.71520996 0.07217407 0. ]
[-0.11462402 -0.38540649 0.5 0.5 ]
[ 0.5 -0.45422363 -0.04580688 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 0. 127.5 127.5]
(255, 255, 255) -> [255. 127.49221802 127.49221802]
Tests (YUV scale=256):
(0, 0, 0) -> [ 0. 128. 128.]
(255, 255, 255) -> [256. 127.9921875 127.9921875]
# 10 (RGB -> BT.2020 full range)
[[ 0.26269531 0.67800903 0.05929565 0. ]
[-0.1395874 -0.3604126 0.5 0.5 ]
[ 0.5 -0.45980835 -0.04022217 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 0. 127.5 127.5]
(255, 255, 255) -> [255. 127.5 127.49221802]
Tests (YUV scale=256):
(0, 0, 0) -> [ 0. 128. 128.]
(255, 255, 255) -> [256. 128. 127.9921875]
# 11 (RGB -> BT.601 limited range)
[[ 0.25576782 0.50216675 0.09753418 0.0625 ]
[-0.14785767 -0.28964233 0.4375 0.5 ]
[ 0.4375 -0.36663818 -0.07086182 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 15.9375 127.5 127.5 ]
(255, 255, 255) -> [234.08203125 127.5 127.5 ]
Tests (YUV scale=256):
(0, 0, 0) -> [ 16. 128. 128.]
(255, 255, 255) -> [235. 128. 128.]
# 12 (RGB -> BT.709 limited range)
[[ 0.18188477 0.61184692 0.06173706 0.0625 ]
[-0.10028076 -0.33721924 0.4375 0.5 ]
[ 0.4375 -0.39743042 -0.04006958 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 15.9375 127.5 127.5 ]
(255, 255, 255) -> [234.08203125 127.5 127.5 ]
Tests (YUV scale=256):
(0, 0, 0) -> [ 16. 128. 128.]
(255, 255, 255) -> [235. 128. 128.]
# 13 (RGB -> BT.2020 limited range)
[[ 0.22473145 0.58001709 0.05072021 0.0625 ]
[-0.12216187 -0.31536865 0.4375 0.5 ]
[ 0.4375 -0.40231323 -0.03518677 0.5 ]]
Tests (YUV scale=255):
(0, 0, 0) -> [ 15.9375 127.5 127.5 ]
(255, 255, 255) -> [234.08203125 127.49221802 127.5 ]
Tests (YUV scale=256):
(0, 0, 0) -> [ 16. 128. 128.]
(255, 255, 255) -> [235. 127.9921875 128. ]
# 14 (Unknown (identity?))
[[-1. 0. 0. 0.]
[ 0. -1. 0. 0.]
[ 0. 0. -1. 0.]]
Tests (YUV scale=255):
(0, 0, 0) -> [0. 0. 0.]
(255, 255, 255) -> [-255. -255. -255.]
Tests (YUV scale=256):
(0, 0, 0) -> [0. 0. 0.]
(255, 255, 255) -> [-256. -256. -256.]
import numpy as np
m = bytes.fromhex("""
00 20 F8 FF DB 2C 2D D3 00 20 00 F5 26 E9 DA 21
00 20 B6 38 08 00 42 C7 00 20 FF FF 64 32 9D CD
00 20 02 FA 05 F1 F9 14 00 20 61 3B 01 00 9E C4
00 20 00 00 30 2F D0 D0 00 20 BC FA B8 ED 8C 17
00 20 34 3C FF FF CD C3 68 25 F7 FF 43 33 19 C8
68 25 6E F3 E2 E5 03 22 68 25 CF 40 09 00 7B BA
68 25 FF FF 97 39 BD C1 68 25 27 F9 E1 EE 4B 13
68 25 DD 43 01 00 75 B7 68 25 00 00 EE 35 65 C5
68 25 FC F9 1B EB 3C 16 68 25 CE 44 FF FF 86 B6
CB 24 00 00 FA 2C 8A C9 CB 24 F6 F4 17 E9 77 18
CB 24 D9 38 00 00 AB BD 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
45 26 23 4B 98 0E 00 00 5F EA A2 D5 FF 3F 00 40
00 40 5E CA A2 F5 00 40 37 1B 8C 5B 3D 09 00 00
54 F1 AB CE 00 40 00 40 00 40 DC C5 23 FA 00 40
A0 21 C9 56 97 07 00 00 22 EE DE D1 00 40 00 40
00 40 25 C5 DA FA 00 40 BD 20 47 40 7C 0C 00 08
13 ED ED DA 00 38 00 40 00 38 12 D1 EE F6 00 40
48 17 51 4E E7 07 00 08 2A F3 D6 D4 00 38 00 40
00 38 21 CD DF FA 00 40 C4 1C 3E 4A 7E 06 00 08
5D F0 A2 D7 00 38 00 40 00 38 81 CC 7F FB 00 40
00 80 00 00 00 00 00 00 00 00 00 80 00 00 00 00
00 00 00 00 00 80 00 00
""".replace(" ", "").replace("\n", ""))
import struct
idx = 0
ranges = [
# YUV -> RGB
# Y U V off
[0x2000, 0x2000, 0x2000, 0x4000],
# RGB -> YUV
# R G B off
[0x8000, 0x8000, 0x8000, 0x8000],
]
desc = [
"BT.601 full range -> RGB",
"BT.709 full range -> RGB",
"BT.2020 full range -> RGB",
"BT.601 limited range -> RGB",
"BT.709 limited range -> RGB",
"BT.2020 limited range -> RGB",
"Unknown YUV->RGB",
"null",
"RGB -> BT.601 full range",
"RGB -> BT.709 full range",
"RGB -> BT.2020 full range",
"RGB -> BT.601 limited range",
"RGB -> BT.709 limited range",
"RGB -> BT.2020 limited range",
"Unknown (identity?)",
]
def do_test(mtx, v, iscale=255, oscale=255):
vin = np.matrix(list(v) + [iscale]).reshape((4, 1)) / iscale
vout = np.array(((mtx * vin) * oscale)).flatten()
print(f" {v} -> {vout}")
while m:
print(f"# {idx} ({desc[idx]})")
mtx = []
for row in range(3):
v = struct.unpack("<4h", m[:8])
m = m[8:]
r = ranges[idx // 8]
v = [i / j for i, j in zip(v, r)]
mtx.append(v)
#v = [f"{i:6.3f}" for i in v]
#print("[ " + ", ".join(v) + "]")
mtx = np.matrix(mtx)
print(mtx)
for scale in (255, 256):
print(f" Tests (YUV scale={scale}):")
if idx < 3:
do_test(mtx, (0, 128, 128), scale, 255)
do_test(mtx, (255, 128, 128), scale, 255)
do_test(mtx, (256, 128, 128), scale, 255)
elif idx < 8:
do_test(mtx, (16, 128, 128), scale, 255)
do_test(mtx, (235, 128, 128), scale, 255)
else:
do_test(mtx, (0, 0, 0), 255, scale)
do_test(mtx, (255, 255, 255), 255, scale)
print()
idx += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment