glfw: add Image type

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2021-07-20 21:00:05 -07:00
parent 2b75b13123
commit 4f1c6d1b58
2 changed files with 84 additions and 0 deletions

82
glfw/src/Image.zig Normal file
View file

@ -0,0 +1,82 @@
//! 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);
}

View file

@ -12,6 +12,7 @@ pub const gamepad_axis = @import("gamepad_axis.zig");
pub const gamepad_button = @import("gamepad_button.zig"); pub const gamepad_button = @import("gamepad_button.zig");
pub const GammaRamp = @import("GammaRamp.zig"); pub const GammaRamp = @import("GammaRamp.zig");
pub const hat = @import("hat.zig"); pub const hat = @import("hat.zig");
pub const Image = @import("Image.zig");
pub const joystick = @import("joystick.zig"); pub const joystick = @import("joystick.zig");
pub const key = @import("key.zig"); pub const key = @import("key.zig");
pub const mod = @import("mod.zig"); pub const mod = @import("mod.zig");
@ -142,6 +143,7 @@ test "version" {
// Reference these so the tests in these files get pulled in / ran. // Reference these so the tests in these files get pulled in / ran.
_ = Monitor; _ = Monitor;
_ = GammaRamp; _ = GammaRamp;
_ = Image;
_ = VideoMode; _ = VideoMode;
_ = Window; _ = Window;