M color.ha => color.ha +13 -1
@@ 24,6 24,19 @@ export fn torgb(c: color, scale: f64) rgb = rgb {
b = (clamp(sqrtf64(c.b * scale), 0.0, 0.9999) * 256f64): int: u8,
};
+export fn fromrgb(c: rgb) color = {
+ let c = color {
+ r = c.r: i32: f64 / 256f64,
+ g = c.g: i32: f64 / 256f64,
+ b = c.b: i32: f64 / 256f64,
+ };
+ return color {
+ r = c.r * c.r,
+ g = c.g * c.g,
+ b = c.b * c.b,
+ };
+};
+
export fn lerp(c1: *const color, c2: *const color, t: f64) color = color {
r = (1.0 - t) * c1.r + t * c2.r,
g = (1.0 - t) * c1.g + t * c2.g,
@@ 38,4 51,3 @@ export fn sum_color(c1: *const color, c2: *const color) color = color {
export fn equal(c1: color, c2: color) bool =
c1.r == c2.r && c1.g == c2.g && c1.b == c2.b;
-
M image.ha => image.ha +63 -0
@@ 1,11 1,18 @@
+use bufio;
use fmt;
use io;
+use strconv;
+use strings;
def MAGIC: str = "P6";
def MAXVAL: u16 = 255;
export type image = [][]color;
+export type invalid = !void;
+
+export type error = !(invalid | io::error);
+
export fn image_create(width: size, height: size, init: color) image = {
let img: image = alloc([[]...], height);
for (let i = 0z; i < height; i += 1) {
@@ 35,6 42,62 @@ export fn write(h: io::handle, img: image, samples: u32) (size | io::error) = {
return ln;
};
+fn tonl(h: io::handle) ([]u8 | error) = match (bufio::scantok(h, '\n': u32: u8)?) {
+case io::EOF =>
+ yield invalid;
+case let buf: []u8 =>
+ yield buf;
+};
+
+export fn read(f: io::handle) (image | error) = {
+ let magic = strings::fromutf8(tonl(f)?);
+ if (magic != MAGIC) {
+ return invalid;
+ };
+ let w = match (strconv::stoz(strings::fromutf8(tonl(f)?))) {
+ case let sz: size =>
+ yield sz;
+ case =>
+ return invalid;
+ };
+ let h = match (strconv::stoz(strings::fromutf8(tonl(f)?))) {
+ case let sz: size=>
+ yield sz;
+ case =>
+ return invalid;
+ };
+ match (strconv::stou(strings::fromutf8(tonl(f)?))) {
+ case let u: uint =>
+ if (u != MAXVAL) {
+ return invalid;
+ };
+ case =>
+ return invalid;
+ };
+
+ let img: image = alloc([[]...], h);
+ for (let i = h - 1; i < h; i -= 1) {
+ img[i] = alloc([color { ... }...], w);
+ for (let j = 0z; j < w; j += 1) {
+ let buf: [3]u8 = [0...];
+ match (io::read(f, buf)?) {
+ case let sz: size =>
+ if (sz != 3) {
+ return invalid;
+ };
+ img[i][j] = fromrgb(rgb {
+ r = buf[0],
+ g = buf[1],
+ b = buf[2],
+ });
+ case io::EOF =>
+ return invalid;
+ };
+ };
+ };
+ return img;
+};
+
@test fn image_create() void = {
let grey = C(0.5, 0.5, 0.5);
let img = image_create(10, 20, grey);