mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
Common/Image: Add helper for loading from stream
This commit is contained in:
parent
3a7d9f1725
commit
0cdd1a70c0
|
@ -1,4 +1,5 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "byte_stream.h"
|
||||||
#include "file_system.h"
|
#include "file_system.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
@ -46,6 +47,32 @@ bool LoadImageFromBuffer(Common::RGBA8Image* image, const void* buffer, std::siz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadImageFromStream(RGBA8Image* image, ByteStream* stream)
|
||||||
|
{
|
||||||
|
stbi_io_callbacks iocb;
|
||||||
|
iocb.read = [](void* user, char* data, int size) {
|
||||||
|
return static_cast<int>(static_cast<ByteStream*>(user)->Read(data, static_cast<u32>(size)));
|
||||||
|
};
|
||||||
|
iocb.skip = [](void* user, int n) { static_cast<ByteStream*>(user)->SeekRelative(n); };
|
||||||
|
iocb.eof = [](void* user) {
|
||||||
|
ByteStream* stream = static_cast<ByteStream*>(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<u32>(width), static_cast<u32>(height), reinterpret_cast<const u32*>(pixel_data));
|
||||||
|
stbi_image_free(pixel_data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WriteImageToFile(const RGBA8Image& image, const char* filename)
|
bool WriteImageToFile(const RGBA8Image& image, const char* filename)
|
||||||
{
|
{
|
||||||
const char* extension = std::strrchr(filename, '.');
|
const char* extension = std::strrchr(filename, '.');
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class ByteStream;
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
template<typename PixelType>
|
template<typename PixelType>
|
||||||
class Image
|
class Image
|
||||||
|
@ -94,6 +96,7 @@ using RGBA8Image = Image<u32>;
|
||||||
|
|
||||||
bool LoadImageFromFile(Common::RGBA8Image* image, const char* filename);
|
bool LoadImageFromFile(Common::RGBA8Image* image, const char* filename);
|
||||||
bool LoadImageFromBuffer(Common::RGBA8Image* image, const void* buffer, std::size_t buffer_size);
|
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);
|
bool WriteImageToFile(const Common::RGBA8Image& image, const char* filename);
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
Loading…
Reference in a new issue