Backlog/engine/core/image.zig

41 lines
1.5 KiB
Zig

// TODO --- this should become it's own engine library?
const std = @import("std");
const spng = @import("spng");
const core = @import("core.zig");
pub const PngContents = struct {
path: []const u8,
pixels: []u8,
size: core.Vector2u,
allocator: std.mem.Allocator,
pub fn init(allocator: std.mem.Allocator, filePath: []const u8) !@This() {
const pngFileContents = try core.loadFileAlloc(filePath, 1, allocator);
defer allocator.free(pngFileContents);
var decoder = try spng.SpngContext.newDecoder();
defer decoder.deinit();
try decoder.setBuffer(pngFileContents);
const header = try decoder.getHeader();
const imageSize = @as(usize, @intCast(header.width * header.height * 4));
core.graphics_log("loaded png {s}, dimensions={d}x{d}", .{ filePath, header.width, header.height });
const pixels: []u8 = try allocator.alloc(u8, imageSize);
const len = try decoder.decode(pixels, spng.SPNG_FMT_RGBA8, spng.SPNG_DECODE_TRNS);
try core.assertf(len == pixels.len, "decoded pixel size not buffer size {d} != {d}", .{ len, pixels.len });
return PngContents{
.path = try core.dupe(u8, allocator, filePath),
.pixels = pixels,
.size = .{ .x = header.width, .y = header.height },
.allocator = allocator,
};
}
pub fn deinit(self: *@This()) void {
self.allocator.free(self.path);
self.allocator.free(self.pixels);
}
};