summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2024-12-17 20:56:01 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2024-12-17 20:56:01 +0100
commit0c97c2124e83b0bcf8719a62ce3704602ee66c38 (patch)
tree8f25e27dc986021bdc443ff140ff086849f5ad86
parent660e9467851978016db6c39157315b832c94f8fd (diff)
downloadzig-playground-0c97c2124e83b0bcf8719a62ce3704602ee66c38.tar.gz
zig-playground-0c97c2124e83b0bcf8719a62ce3704602ee66c38.zip
ppm: simple example to generate a ppm image
-rw-r--r--ppm/Makefile8
-rw-r--r--ppm/main.zig22
-rw-r--r--ppm/ppm.zig51
3 files changed, 81 insertions, 0 deletions
diff --git a/ppm/Makefile b/ppm/Makefile
new file mode 100644
index 0000000..031bfc6
--- /dev/null
+++ b/ppm/Makefile
@@ -0,0 +1,8 @@
+main: main.zig ppm.zig
+ zig run main.zig
+
+show:
+ nsxiv test.ppm
+
+clean:
+ $(RM) test.ppm
diff --git a/ppm/main.zig b/ppm/main.zig
new file mode 100644
index 0000000..6e1bb1b
--- /dev/null
+++ b/ppm/main.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+const ppm = @import("ppm.zig");
+
+pub fn main() !void {
+ var img = ppm.ppm(200, 200).init;
+ defer img.dump("test.ppm") catch unreachable;
+
+ for (img.row(10)) |*px| {
+ px.*.r = 255;
+ }
+ for (img.row(20)) |*px| {
+ px.*.g = 255;
+ }
+ for (img.row(30)) |*px| {
+ px.*.b = 255;
+ }
+
+ const white = ppm.Pixel{ .r = 255, .g = 255, .b = 255 };
+
+ img.set(100, 100, white);
+ img.set(199, 199, white);
+}
diff --git a/ppm/ppm.zig b/ppm/ppm.zig
new file mode 100644
index 0000000..8b89456
--- /dev/null
+++ b/ppm/ppm.zig
@@ -0,0 +1,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);
+ }
+ }
+ }
+ };
+}