summaryrefslogtreecommitdiff
path: root/ppm/ppm.zig
blob: 8b89456efe4c2616abbacb7e4ae7b7922b1367ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const std = @import("std");
const assert = std.debug.assert;

pub const Pixel = extern struct {
    r: u8,
    g: u8,
    b: u8,
};

pub fn ppm(comptime xdim: u32, comptime ydim: u32) type {
    return struct {
        const Self = @This();

        /// Pixel data of the ppm image.
        px: [ydim][xdim]Pixel,

        /// Initial value of the `ppm` type.
        pub const init: Self = .{
            .px = undefined,
        };

        /// Set pixel data at `(x, y)`.
        pub fn set(self: *Self, x: u32, y: u32, px: Pixel) void {
            assert(x < xdim and y < ydim);
            self.px[x][y] = px;
        }

        /// Get slice of pixels for row `y`.
        pub fn row(self: *Self, y: u32) []Pixel {
            assert(y < ydim);
            return self.px[y][0..];
        }

        /// Write out image file with `name`.
        pub fn dump(self: *const Self, name: []const u8) !void {
            const f = try std.fs.cwd().createFile(name, .{ .truncate = true });
            defer f.close();

            const w = f.writer();
            // Write ppm header (in ascii):
            //  MAGIC XDIM YDIM MAX_COLOR_VALUE
            try w.print("P6 {} {} 255\n", .{ xdim, ydim });

            for (self.px) |curr_row| {
                for (curr_row) |px| {
                    try w.writeStruct(px);
                }
            }
        }
    };
}