const std = @import("std");
const assert = std.debug.assert;

extern fn zig_stbi_load_from_memory(buffer: [*]const u8, len: i32, x: ?*i32, y: ?*i32, comp: ?*i32, req_comp: i32) callconv(.C) ?[*]u8;
extern fn zig_stbi_image_free(buffer: ?*anyopaque) callconv(.C) void;

pub const Image = struct {
    width: u32,
    height: u32,
    rgba: []u8,

    pub fn deinit(self: Image) void {
        zig_stbi_image_free(self.rgba.ptr);
    }
};

pub fn load(buffer: []const u8) !Image {
    var width: i32 = 0;
    var height: i32 = 0;
    const image_rgba = zig_stbi_load_from_memory(buffer.ptr, @intCast(buffer.len), &width, &height, null, 4);
    if (image_rgba == null) {
        return error.PNGDecode;
    }
    errdefer zig_stbi_image_free(image_rgba);

    const byte_count: u32 = @intCast(width * height * 4);
    return Image{ .width = @intCast(width), .height = @intCast(height), .rgba = image_rgba.?[0..byte_count] };
}
