diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-12-17 20:56:01 +0100 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-12-17 20:56:01 +0100 |
commit | 0c97c2124e83b0bcf8719a62ce3704602ee66c38 (patch) | |
tree | 8f25e27dc986021bdc443ff140ff086849f5ad86 | |
parent | 660e9467851978016db6c39157315b832c94f8fd (diff) | |
download | zig-playground-0c97c2124e83b0bcf8719a62ce3704602ee66c38.tar.gz zig-playground-0c97c2124e83b0bcf8719a62ce3704602ee66c38.zip |
ppm: simple example to generate a ppm image
-rw-r--r-- | ppm/Makefile | 8 | ||||
-rw-r--r-- | ppm/main.zig | 22 | ||||
-rw-r--r-- | ppm/ppm.zig | 51 |
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); + } + } + } + }; +} |