#pragma once #include #include #include #include #include #include #include namespace kuiper { namespace resource { struct image_error { std::string_view message; }; class image { public: image(std::uint32_t width, std::uint32_t height, std::uint32_t n_channels, const std::uint8_t* data, std::size_t len) : m_width(width), m_height(height), m_channels(n_channels), m_data(data, data + len) {} image() = default; ~image() = default; image(const image& other) = default; image& operator=(const image& other) = default; image(image&& other) noexcept = default; image& operator=(image&& other) noexcept = default; static image make_blank(std::uint32_t width, std::uint32_t height, std::uint32_t n_channels) noexcept; static std::expected from_path(const std::filesystem::path& path, std::uint8_t num_channels = 4) noexcept; static std::expected from_memory(const std::uint8_t* data, std::size_t len, std::uint8_t num_channels = 4) noexcept; std::uint32_t width() const noexcept { return m_width; } std::uint32_t height() const noexcept { return m_height; } glm::uvec2 dimensions() const noexcept { return {m_width, m_height}; } std::uint32_t channels() const noexcept { return m_channels; } const std::vector& pixel_data() const noexcept { return m_data; } std::vector& pixel_data_mut() noexcept { return m_data; } void resize(std::uint32_t width, std::uint32_t height) noexcept; private: std::uint32_t m_width {0}; std::uint32_t m_height {0}; std::uint32_t m_channels {0}; std::vector m_data {}; }; } // namespace resource } // namespace kuiper