zig-glfw/src/Image.zig
Stephen Gutekanst 14ab07d5eb glfw: add Image type
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
2021-07-20 21:00:05 -07:00

82 lines
2.6 KiB
Zig

//! Image data
//!
//!
//! This describes a single 2D image. See the documentation for each related function what the
//! expected pixel format is.
//!
//! see also: cursor_custom, window_icon
//!
//! It may be .owned (e.g. in the case of an image initialized by you for passing into glfw) or not
//! .owned (e.g. in the case of one gotten via glfw) If it is .owned, deinit should be called to
//! free the memory. It is safe to call deinit even if not .owned.
const std = @import("std");
const testing = std.testing;
const mem = std.mem;
const c = @import("c.zig").c;
const Image = @This();
/// The width of this image, in pixels.
width: usize,
/// The height of this image, in pixels.
height: usize,
/// The pixel data of this image, arranged left-to-right, top-to-bottom.
pixels: []u8,
/// Whether or not the pixels data is owned by you (true) or GLFW (false).
owned: bool,
/// Initializes a new owned image with the given size and pixel_data_len of undefined .pixel values.
pub inline fn init(allocator: *mem.Allocator, width: usize, height: usize, pixel_data_len: usize) !Image {
const buf = try allocator.alloc(u8, pixel_data_len);
return Image{
.width = width,
.height = height,
.pixels = buf,
.owned = true,
};
}
/// Turns a GLFW / C image into the nicer Zig type, and sets `.owned = false`.
///
/// The length of pixel data must be supplied, as GLFW's image type does not itself describe the
/// number of bytes required per pixel / the length of the pixel data array.
///
/// The returned memory is valid for as long as the GLFW C memory is valid.
pub inline fn fromC(native: c.GLFWimage, pixel_data_len: usize) Image {
return Image{
.width = @intCast(usize, native.width),
.height = @intCast(usize, native.height),
.pixels = native.pixels[0..pixel_data_len],
.owned = false,
};
}
/// Turns the nicer Zig type into a GLFW / C image, for passing into GLFW C functions.
///
/// The returned memory is valid for as long as the Zig memory is valid.
pub inline fn toC(self: Image) c.GLFWimage {
return c.GLFWimage{
.width = @intCast(c_int, self.width),
.height = @intCast(c_int, self.height),
.pixels = &self.pixels[0],
};
}
/// Deinitializes the memory using the allocator iff `.owned = true`.
pub inline fn deinit(self: Image, allocator: *mem.Allocator) void {
if (self.owned) allocator.free(self.pixels);
}
test "conversion" {
const allocator = testing.allocator;
const image = try Image.init(allocator, 256, 256, 256 * 256 * 4);
defer image.deinit(allocator);
const glfw = image.toC();
_ = Image.fromC(glfw, image.width * image.height * 4);
}