nx_light_test.nx source
↩ module page · 141 lines · 4710 B
1// nx_light_test.nx -- smoke for V3 light/exposure primitives.
2
3import "syscalls.nx"
4import "nx_image.nx"
5import "nx_light.nx"
6
7func main() -> i64 {
8 // === Test 1: integer sqrt ===
9 if nx_math_isqrt(0) != 0 { return 1 }
10 if nx_math_isqrt(100) != 10 { return 2 }
11 if nx_math_isqrt(16129) != 127 { return 3 }
12
13 // === Test 2: mean luminance on uniform image ===
14 let img1: *Image = nx_image_alloc(16, 16, 1)
15 var y: i64 = 0
16 while y < 16 {
17 var x: i64 = 0
18 while x < 16 {
19 nx_image_set(img1, x, y, 0, 100)
20 x = x + 1
21 }
22 y = y + 1
23 }
24 if nx_light_mean_luminance(img1) != 100 { return 10 }
25
26 // === Test 3: stddev on uniform image = 0 ===
27 if nx_light_stddev_luminance(img1, 100) != 0 { return 11 }
28
29 // === Test 4: min/max on uniform ===
30 if nx_light_min(img1) != 100 { return 12 }
31 if nx_light_max(img1) != 100 { return 13 }
32 if nx_light_dynamic_range(img1) != 0 { return 14 }
33
34 // === Test 5: checkerboard 0/255 stats ===
35 let img2: *Image = nx_image_alloc(16, 16, 1)
36 var y2: i64 = 0
37 while y2 < 16 {
38 var x2: i64 = 0
39 while x2 < 16 {
40 let par: i64 = (x2 + y2) - ((x2 + y2) / 2) * 2
41 var v: i64 = 0
42 if par == 1 { v = 255 }
43 nx_image_set(img2, x2, y2, 0, v)
44 x2 = x2 + 1
45 }
46 y2 = y2 + 1
47 }
48 // Mean = 127 (128 pixels at 255, 128 at 0, total 32640, /256 = 127.5 -> 127 int)
49 let m2: i64 = nx_light_mean_luminance(img2)
50 if m2 < 126 { return 20 }
51 if m2 > 128 { return 21 }
52 // Stddev ~= 127 (each pixel deviates by 127.5)
53 let s2: i64 = nx_light_stddev_luminance(img2, m2)
54 if s2 < 120 { return 22 }
55 if s2 > 130 { return 23 }
56 // Range = 255
57 if nx_light_dynamic_range(img2) != 255 { return 24 }
58
59 // === Test 6: underexposed fraction ===
60 // Image is all dark (value 5). Underexposed below 10 = all pixels.
61 let img3: *Image = nx_image_alloc(16, 16, 1)
62 var y3: i64 = 0
63 while y3 < 16 {
64 var x3: i64 = 0
65 while x3 < 16 {
66 nx_image_set(img3, x3, y3, 0, 5)
67 x3 = x3 + 1
68 }
69 y3 = y3 + 1
70 }
71 let u3: i64 = nx_light_underexposed_frac(img3, 10)
72 if u3 != 1024 { return 30 }
73
74 // === Test 7: overexposed fraction ===
75 let img4: *Image = nx_image_alloc(16, 16, 1)
76 var y4: i64 = 0
77 while y4 < 16 {
78 var x4: i64 = 0
79 while x4 < 16 {
80 nx_image_set(img4, x4, y4, 0, 250)
81 x4 = x4 + 1
82 }
83 y4 = y4 + 1
84 }
85 let o4: i64 = nx_light_overexposed_frac(img4, 245)
86 if o4 != 1024 { return 31 }
87
88 // === Test 8: direction classifier ===
89 // Strong positive gx, zero gy -> East (0)
90 if nx_light_direction_classify(100, 0) != 0 { return 40 }
91 // Strong negative gx -> West (4)
92 if nx_light_direction_classify(-100, 0) != 4 { return 41 }
93 // Strong positive gy -> South (y-down) (2)
94 if nx_light_direction_classify(0, 100) != 2 { return 42 }
95 // Strong negative gy -> North (6)
96 if nx_light_direction_classify(0, -100) != 6 { return 43 }
97 // Both positive, equal -> SE (1)
98 if nx_light_direction_classify(50, 50) != 1 { return 44 }
99 // Negative x, positive y -> SW (3)
100 if nx_light_direction_classify(-50, 50) != 3 { return 45 }
101 // Both negative -> NW (5)
102 if nx_light_direction_classify(-50, -50) != 5 { return 46 }
103 // Positive x, negative y -> NE (7)
104 if nx_light_direction_classify(50, -50) != 7 { return 47 }
105 // Zero magnitude -> -1
106 if nx_light_direction_classify(0, 0) != -1 { return 48 }
107
108 // === Test 9: direction histogram on a vertical edge ===
109 // Vertical edge (right=bright, left=dark) yields gx>0, gy=0.
110 // Most votes should be in bin 0 (East).
111 let edge: *Image = nx_image_alloc(16, 16, 1)
112 var yv: i64 = 0
113 while yv < 16 {
114 var xv: i64 = 0
115 while xv < 16 {
116 var v: i64 = 0
117 if xv >= 8 { v = 255 }
118 nx_image_set(edge, xv, yv, 0, v)
119 xv = xv + 1
120 }
121 yv = yv + 1
122 }
123 let gx: *ImageS64 = nx_image_sobel_x(edge)
124 let gy: *ImageS64 = nx_image_sobel_y(edge)
125 let hist: *i64 = (sys_mmap(8 * 8)) as *i64
126 nx_light_direction_hist(gx, gy, 100, hist)
127 // Bin 0 (East) should dominate
128 var dominant: i64 = 0
129 var best_v: i64 = hist[0]
130 var i: i64 = 1
131 while i < 8 {
132 if hist[i] > best_v {
133 best_v = hist[i]
134 dominant = i
135 }
136 i = i + 1
137 }
138 if dominant != 0 { return 50 }
139
140 return 0
141}