image.bend
gralha-image@0.1.0.1 · 65 lines · 11 definitions
1
2import Base
3import gralha-text-scan@0.1.0.1/scan.bend as U
4
5type Color is Data:
6 Color{r: F32, g: F32, b: F32, a: F32}
7
8def clear() -> Color:
9 Color{0.0, 0.0, 0.0, 0.0}
10
11def rgba(r: F32, g: F32, b: F32, +a: F32) -> Color:
12 Color{(r * a : F32), (g * a : F32), (b * a : F32), a}
13
14
15
16type Pixels is Data:
17 Flat{color: Color}
18 Quad{tl: Pixels, tr: Pixels, bl: Pixels, br: Pixels}
19
20def color.same(a: Color, b: Color) -> Bool:
21 Color{ar, ag, ab, aa} = a
22 Color{br, bg, bb, ba} = b
23 F32.is_eq(ar, br) && F32.is_eq(ag, bg) && F32.is_eq(ab, bb) && F32.is_eq(aa, ba)
24
25def pixels.join(+a: Pixels, +b: Pixels, +c: Pixels, +d: Pixels) -> Pixels:
26 match a b c d:
27 case Flat{aa} Flat{bb} Flat{cc} Flat{dd}:
28 U.choose(Pixels, color.same(aa, bb) && color.same(aa, cc) && color.same(aa, dd), Flat{aa}, Quad{a, b, c, d})
29 case _ _ _ _: Quad{a, b, c, d}
30
31
32type Picture is Data:
33 Picture{width: U32, height: U32, depth: Nat, pixels: Pixels}
34
35def picture.blank() -> Picture:
36 Picture{0, 0, 0n, Flat{clear()}}
37
38@unsafe
39def pixels.get(xs: Pixels, +size: U32, +x: U32, +y: U32) -> Color:
40 match xs:
41 case Flat{c}: c
42 case Quad{a, b, c, d}:
43 +half = (size / 2 : U32)
44 pixels.get(U.choose(Pixels, U32.is_lt(y, half), U.choose(Pixels, U32.is_lt(x, half), a, b), U.choose(Pixels, U32.is_lt(x, half), c, d)), half, U32.mod(x, half), U32.mod(y, half))
45
46@unsafe
47def picture.depth(+size: U32, +side: U32, +depth: Nat) -> Nat:
48 U.branch(Nat, U32.is_ge(side, size), _ => depth, _ => picture.depth(size, (side * 2 : U32), 1n+depth))
49
50@unsafe
51def pixels.set(+pixels: Pixels, +depth: Nat, +x: U32, +y: U32, +col: Color) -> Pixels:
52 match pixels:
53 case Flat{c}:
54 match depth:
55 case 0n: Flat{col}
56 case 1n+d: pixels.set(Quad{Flat{c}, Flat{c}, Flat{c}, Flat{c}}, 1n+d, x, y, col)
57 case Quad{a, b, c, e}:
58 match depth:
59 case 0n: Flat{col}
60 case 1n+d:
61 +dd = d
62 +half = U32.shln(1, dd)
63 U.branch(Pixels, U32.is_lt(y, half),
64 _ => U.branch(Pixels, U32.is_lt(x, half), _ => pixels.join(pixels.set(a, dd, x, y, col), b, c, e), _ => pixels.join(a, pixels.set(b, dd, (x - half : U32), y, col), c, e)),
65 _ => U.branch(Pixels, U32.is_lt(x, half), _ => pixels.join(a, b, pixels.set(c, dd, x, (y - half : U32), col), e), _ => pixels.join(a, b, c, pixels.set(e, dd, (x - half : U32), (y - half : U32), col))))