diff --git a/example/src/main.cpp b/example/src/main.cpp index 6f24584..7d3a4be 100644 --- a/example/src/main.cpp +++ b/example/src/main.cpp @@ -18,11 +18,13 @@ int main(int argc, char* argv[]) { file->map_file(L"Z:/Root/Local/NanakoDisk/涩图/可爱偷猴计划/东风谷早苗/57092520_p1.jpg"); mirage_stb_image image; - image.load(file->get_data(), file->get_size()); + image.init(file->get_data(), file->get_size()); - // auto accessor = pixel_factory::create_image_accessor(SG_PIXELFORMAT_RGBA8, file->get_data(), x, y); - // auto pixel_format = accessor->get_pixel_format(); - // pixel_factory::destroy_image_accessor(accessor); + auto heap = image.load(); + auto pixel_format = heap->info.get_pixel_format(); + + auto accessor = pixel_factory::create_image_accessor(pixel_format, heap->data, heap->info.width, heap->info.height); + pixel_factory::destroy_image_accessor(accessor); auto window = std::make_shared(); window->create_window(800, 600, L"Hello, World!"); diff --git a/src/mirage_stb_image/mirage_stb_image.cpp b/src/mirage_stb_image/mirage_stb_image.cpp index 4480948..17e03b7 100644 --- a/src/mirage_stb_image/mirage_stb_image.cpp +++ b/src/mirage_stb_image/mirage_stb_image.cpp @@ -1,26 +1,96 @@ -// -// Created by 46944 on 25-3-25. -// - #include "mirage_stb_image.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -bool mirage_stb_image::load(void* in_data, int32_t in_size) { - auto buffer = static_cast(in_data); +sg_pixel_format stb_image_info::get_pixel_format() const { + // 根据通道数和是否HDR选择合适的像素格式 + if (is_hdr) { + switch (channels) { + case 1: + return SG_PIXELFORMAT_R32F; + case 2: + return SG_PIXELFORMAT_RG32F; + case 3: + case 4: + return SG_PIXELFORMAT_RGBA32F; + default: + return SG_PIXELFORMAT_RGBA32F; + } + } - int x, y, channels; + // 16位图像 + if (is_16_bit) { + switch (channels) { + case 1: + return SG_PIXELFORMAT_R16; + case 2: + return SG_PIXELFORMAT_RG16; + case 3: + case 4: + return SG_PIXELFORMAT_RGBA16; + default: + return SG_PIXELFORMAT_RGBA16; + } + } - stbi_info_from_memory(buffer, in_size, &x, &y, &channels); - bool is_16_bit = stbi_is_16_bit_from_memory(buffer, in_size); - bool is_hdr = stbi_is_hdr_from_memory(buffer, in_size); - // stbi_load_from_memory(); - // stbi_load_16_from_memory(); - // stbi_loadf_from_memory(); - - return true; + // 8位图像 + switch (channels) { + case 1: + return SG_PIXELFORMAT_R8; + case 2: + return SG_PIXELFORMAT_RG8; + case 3: + case 4: + return SG_PIXELFORMAT_RGBA8; + default: + return SG_PIXELFORMAT_RGBA8; + } } -bool mirage_stb_image::load(void* in_data, int32_t in_size, sg_pixel_format in_format) { - return false; +void mirage_stb_image::init(void* in_data, int32_t in_size) { + data_ = static_cast(in_data); + size_ = in_size; +} + +stb_image_info mirage_stb_image::get_info() const { + stb_image_info info{}; + stbi_info_from_memory(data_, size_, &info.width, &info.height, &info.channels); + info.is_hdr = is_hdr(); + info.is_16_bit = is_16_bit(); + return info; +} + +bool mirage_stb_image::is_hdr() const { + return stbi_is_hdr_from_memory(data_, size_); +} + +bool mirage_stb_image::is_16_bit() const { + return stbi_is_16_bit_from_memory(data_, size_); +} + +float* mirage_stb_image::load_hdr() const { + int width, height, channels; + return stbi_loadf_from_memory(data_, size_, &width, &height, &channels, 4); +} + +uint16_t* mirage_stb_image::load_16_bit() const { + int width, height, channels; + return stbi_load_16_from_memory(data_, size_, &width, &height, &channels, 4); +} + +uint8_t* mirage_stb_image::load_8_bit() const { + int width, height, channels; + return stbi_load_from_memory(data_, size_, &width, &height, &channels, 4); +} + +std::shared_ptr mirage_stb_image::load() const { + auto heap = std::make_shared(); + heap->info = get_info(); + if (is_hdr()) + heap->data = load_hdr(); + else if (is_16_bit()) + heap->data = load_16_bit(); + else + heap->data = load_8_bit(); + return heap; } diff --git a/src/mirage_stb_image/mirage_stb_image.h b/src/mirage_stb_image/mirage_stb_image.h index 8a7d7ee..662d527 100644 --- a/src/mirage_stb_image/mirage_stb_image.h +++ b/src/mirage_stb_image/mirage_stb_image.h @@ -1,12 +1,45 @@ #pragma once #include +#include #include "sokol_gfx.h" +#include "stb_image.h" + +struct stb_image_info { + int32_t width; + int32_t height; + int32_t channels; + bool is_hdr; + bool is_16_bit; + + [[nodiscard]] sg_pixel_format get_pixel_format() const; +}; + +struct stb_heap_image { + stb_image_info info; + void* data; + + ~stb_heap_image() { + if (data) + stbi_image_free(data); + } +}; class mirage_stb_image { public: - bool load(void* in_data, int32_t in_size); - bool load(void* in_data, int32_t in_size, sg_pixel_format in_format); + void init(void* in_data, int32_t in_size); + + [[nodiscard]] stb_image_info get_info() const; + [[nodiscard]] bool is_hdr() const; + [[nodiscard]] bool is_16_bit() const; + + [[nodiscard]] float* load_hdr() const; + [[nodiscard]] uint16_t* load_16_bit() const; + [[nodiscard]] uint8_t* load_8_bit() const; + [[nodiscard]] std::shared_ptr load() const; + private: + stbi_uc* data_{}; + int32_t size_{}; };