90 lines
3.7 KiB
Text
90 lines
3.7 KiB
Text
# lab_test.ludic - what the lab computes without a window: the PNGs it writes (a shot, raw pixels), the cameras
|
|
# a scene names, and the scenes a program adds
|
|
import "ludic.lab"
|
|
program LabTest {
|
|
numbers float
|
|
friend module lab_test of ludic_lab
|
|
function nothing() -> void { }
|
|
def LabScenes one { setup: fn nothing }
|
|
def LabScenes two { setup: fn nothing }
|
|
|
|
function ppm(path: string) -> void {
|
|
let hdr = "P6\n2 2\n255\n"
|
|
let b = buffer(len(hdr) + 12)
|
|
for i in 0 .. len(hdr) { b[i] = hdr[i] }
|
|
for i in 0 .. 12 { b[len(hdr) + i] = i * 20 }
|
|
Fs.write_bytes(path, b, len(hdr) + 12)
|
|
}
|
|
|
|
test "a PPM becomes a PNG with its signature, its size and a valid IEND" (lab_st: mut LabState) {
|
|
let dir = Os.temp_dir()
|
|
ppm(`{dir}/lab_test.ppm`)
|
|
expect(lab_ppm_to_png(lab_st, `{dir}/lab_test.ppm`, `{dir}/lab_test.png`))
|
|
let p = Fs.read_bytes(`{dir}/lab_test.png`)
|
|
expect(p != null)
|
|
expect_eq(p[0], 137)
|
|
expect_eq(p[1], 80)
|
|
expect_eq(p[19], 2) # IHDR width, low byte
|
|
expect_eq(p[23], 2) # height
|
|
let n = len(p)
|
|
# the IEND chunk's CRC is always AE 42 60 82
|
|
expect_eq(p[n - 4], 174)
|
|
expect_eq(p[n - 3], 66)
|
|
expect_eq(p[n - 2], 96)
|
|
expect_eq(p[n - 1], 130)
|
|
expect(not Fs.exists(`{dir}/lab_test.ppm`))
|
|
}
|
|
|
|
test "raw pixels become a PNG of their channel count" (lab_png_st: LabPngState) {
|
|
let dir = Os.temp_dir()
|
|
let px = buffer(3 * 2 * 4)
|
|
for i in 0 .. 24 { px[i] = i * 10 }
|
|
expect(lab_png_write(lab_png_st, `{dir}/lab_test_rgba.png`, 3, 2, 4, px))
|
|
let p = Fs.read_bytes(`{dir}/lab_test_rgba.png`)
|
|
expect_eq(p[19], 3) # width
|
|
expect_eq(p[25], 6) # colour type RGBA
|
|
expect_eq(len(p), lp_png_size(3, 2, 4))
|
|
expect(not lab_png_write(lab_png_st, `{dir}/lab_test_short.png`, 9, 9, 4, px))
|
|
}
|
|
|
|
test "16-bit samples become a 16-bit PNG, two bytes a sample" (lab_png_st: LabPngState) {
|
|
let dir = Os.temp_dir()
|
|
let px = buffer(3 * 2 * 2)
|
|
for i in 0 .. 12 { px[i] = i * 20 }
|
|
expect(lab_png_write16_from(lab_png_st, `{dir}/lab_test_r16.png`, 3, 2, 1, px, 0))
|
|
let p = Fs.read_bytes(`{dir}/lab_test_r16.png`)
|
|
expect_eq(p[24], 16) # bit depth
|
|
expect_eq(p[25], 0) # colour type grey
|
|
expect_eq(len(p), lp_png_bytes(3 * 2, 2))
|
|
expect(not lab_png_write16_from(lab_png_st, `{dir}/lab_test_r16_short.png`, 3, 3, 1, px, 0))
|
|
}
|
|
|
|
test "a half float and a float read as the numbers they store" {
|
|
let b = buffer(8)
|
|
b[0] = 0; b[1] = 60 # half 1.0 = 0x3C00
|
|
b[2] = 0; b[3] = 192 # half -2.0 = 0xC000
|
|
b[4] = 0; b[5] = 0; b[6] = 128; b[7] = 63 # float 1.0 = 0x3F800000
|
|
expect_near(lab_f16_at(b, 0), 1.0, 0.0001)
|
|
expect_near(lab_f16_at(b, 2), -2.0, 0.0001)
|
|
expect_near(lab_f32_at(b, 4), 1.0, 0.0001)
|
|
let g = lab_px_rgba16f_hdr(b, 0, 1) # 1.0 -> 0.5 -> sRGB 188
|
|
expect_eq(g[0] & 255, 188)
|
|
}
|
|
|
|
test "a camera at a point looks back at it" (lab_st: mut LabState) {
|
|
lab_shots_reset(lab_st)
|
|
lab_shot_at(lab_st, "front", 0.0, 1.0, 0.0, 10.0, 0.0, 0.0)
|
|
lab_shot_at(lab_st, "side", 0.0, 1.0, 0.0, 10.0, 90.0, 30.0)
|
|
expect_eq(lab_shot_count(lab_st), 2)
|
|
expect_near(lab_st.lb_shot_pose[2], 10.0, 0.001) # front: 10 m out along +z
|
|
expect_near(lab_st.lb_shot_pose[5 + 0], 8.660, 0.01) # side: along +x, 30 degrees up
|
|
expect_near(lab_st.lb_shot_pose[5 + 1], 6.0, 0.01)
|
|
expect_near(lab_st.lb_shot_pose[5 + 4], -30.0, 0.001)
|
|
}
|
|
|
|
test "scenes are what the program added, in its order" {
|
|
expect_eq(LAB_COUNT, 2)
|
|
expect(lab_scene_names() == "one, two")
|
|
expect_eq(labscenes_find("two"), LAB_TWO)
|
|
}
|
|
}
|