main f2d166b

pattern_test.go RawHistoryFolder

1package pattern
2
3import (
4	"image"
5	"math"
6	"testing"
7)
8
9func TestPatchesTileTheSurface(t *testing.T) {
10	for _, mode := range []string{"sdr", "hdr"} {
11		for _, size := range [][2]int{{640, 360}, {641, 361}} {
12			w, h := size[0], size[1]
13			patches := Patches(mode, w, h)
14			if len(patches) != Columns*Rows {
15				t.Fatalf("%s %dx%d: %d patches", mode, w, h, len(patches))
16			}
17			covered := make([]int, w*h)
18			for _, p := range patches {
19				if !p.Rect.In(image.Rect(0, 0, w, h)) || p.Rect.Empty() {
20					t.Fatalf("%s %dx%d: bad rect %v", mode, w, h, p.Rect)
21				}
22				for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
23					for x := p.Rect.Min.X; x < p.Rect.Max.X; x++ {
24						covered[y*w+x]++
25					}
26				}
27			}
28			for i, n := range covered {
29				if n != 1 {
30					t.Fatalf("%s %dx%d: pixel (%d,%d) covered %d times", mode, w, h, i%w, i/w, n)
31				}
32			}
33		}
34	}
35}
36
37func TestPatchesModes(t *testing.T) {
38	if Patches("bogus", 640, 360) != nil {
39		t.Fatal("unknown mode must yield nil")
40	}
41	sdr := Patches("sdr", 600, 200)
42	if sdr[5].SRGB != [3]uint8{255, 128, 0} || sdr[11].SRGB != [3]uint8{255, 255, 0} {
43		t.Fatalf("sdr patches: %v", sdr)
44	}
45	hdr := Patches("hdr", 600, 200)
46	if hdr[3].Nits != [3]float64{203, 203, 203} || hdr[5].Nits != [3]float64{1000, 1000, 1000} {
47		t.Fatalf("hdr neutrals: %v", hdr)
48	}
49	// BT.709 red at 203 nits in BT.2020.
50	want := [3]float64{0.627404 * 203, 0.069097 * 203, 0.016391 * 203}
51	for i, v := range hdr[9].Nits {
52		if math.Abs(v-want[i]) > 1e-9 {
53			t.Fatalf("709 red = %v, want %v", hdr[9].Nits, want)
54		}
55	}
56	if c := sdr[0].Centre(); c != image.Pt(50, 50) {
57		t.Fatalf("centre = %v", c)
58	}
59}
60
61func TestPQEncode(t *testing.T) {
62	if v := PQEncode(203); math.Abs(v-0.5807) > 1e-4 {
63		t.Fatalf("PQEncode(203) = %v", v)
64	}
65	if v := PQEncode(10000); math.Abs(v-1) > 1e-4 {
66		t.Fatalf("PQEncode(10000) = %v", v)
67	}
68	if PQEncode(0) != 0 || PQEncode(-1) != 0 {
69		t.Fatal("PQEncode must clamp to zero")
70	}
71}
72
73func TestPQDecodeInvertsPQEncode(t *testing.T) {
74	for _, nits := range []float64{0.001, 0.02, 1, 10, 100, 203, 400, 1000, 4000, 10000} {
75		if got := PQDecode(PQEncode(nits)); math.Abs(got-nits) > nits*1e-9+1e-9 {
76			t.Errorf("PQDecode(PQEncode(%v)) = %v", nits, got)
77		}
78	}
79	for _, v := range []float64{0, 0.0313, 0.1508, 0.5807, 0.75, 1} {
80		if got := PQEncode(PQDecode(v)); math.Abs(got-v) > 1e-9 {
81			t.Errorf("PQEncode(PQDecode(%v)) = %v", v, got)
82		}
83	}
84	if PQDecode(0) != 0 || PQDecode(-1) != 0 || math.Abs(PQDecode(1)-10000) > 1e-6 {
85		t.Fatal("PQDecode endpoints")
86	}
87	// The compositor's near-black residue (0.0313 PQ) is a few hundredths of a nit.
88	if v := PQDecode(0.0313); v < 0.01 || v > 0.05 {
89		t.Fatalf("PQDecode(0.0313) = %v nits", v)
90	}
91}
92
93func TestSRGBToLinear(t *testing.T) {
94	if SRGBToLinear(0) != 0 || math.Abs(SRGBToLinear(1)-1) > 1e-12 {
95		t.Fatal("endpoints")
96	}
97	if v := SRGBToLinear(128.0 / 255); math.Abs(v-0.2158605) > 1e-6 {
98		t.Fatalf("SRGBToLinear(128/255) = %v", v)
99	}
100}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close