diff --git a/src/common/image.cpp b/src/common/image.cpp index e86069318..bd5259b49 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -1,4 +1,5 @@ #include "image.h" +#include "byte_stream.h" #include "file_system.h" #include "log.h" #include "stb_image.h" @@ -46,6 +47,32 @@ bool LoadImageFromBuffer(Common::RGBA8Image* image, const void* buffer, std::siz return true; } +bool LoadImageFromStream(RGBA8Image* image, ByteStream* stream) +{ + stbi_io_callbacks iocb; + iocb.read = [](void* user, char* data, int size) { + return static_cast(static_cast(user)->Read(data, static_cast(size))); + }; + iocb.skip = [](void* user, int n) { static_cast(user)->SeekRelative(n); }; + iocb.eof = [](void* user) { + ByteStream* stream = static_cast(user); + return (stream->InErrorState() || stream->GetPosition() == stream->GetSize()) ? 1 : 0; + }; + + int width, height, file_channels; + u8* pixel_data = stbi_load_from_callbacks(&iocb, stream, &width, &height, &file_channels, 4); + if (!pixel_data) + { + const char* error_reason = stbi_failure_reason(); + Log_ErrorPrintf("Failed to load image from stream: %s", error_reason ? error_reason : "unknown error"); + return false; + } + + image->SetPixels(static_cast(width), static_cast(height), reinterpret_cast(pixel_data)); + stbi_image_free(pixel_data); + return true; +} + bool WriteImageToFile(const RGBA8Image& image, const char* filename) { const char* extension = std::strrchr(filename, '.'); diff --git a/src/common/image.h b/src/common/image.h index 23ba658b7..922df6b6b 100644 --- a/src/common/image.h +++ b/src/common/image.h @@ -6,6 +6,8 @@ #include #include +class ByteStream; + namespace Common { template class Image @@ -94,6 +96,7 @@ using RGBA8Image = Image; bool LoadImageFromFile(Common::RGBA8Image* image, const char* filename); bool LoadImageFromBuffer(Common::RGBA8Image* image, const void* buffer, std::size_t buffer_size); +bool LoadImageFromStream(Common::RGBA8Image* image, ByteStream* stream); bool WriteImageToFile(const Common::RGBA8Image& image, const char* filename); } // namespace Common \ No newline at end of file