From a4e716006aad9f1b23fdcff1d1db2d8c49418573 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Mon, 7 Oct 2024 17:18:30 +0300 Subject: [PATCH 1/2] implement getting image size without reading the whole image --- openVulkanoCpp/Image/ImageLoader.cpp | 6 ++++++ openVulkanoCpp/Image/ImageLoader.hpp | 3 +++ openVulkanoCpp/Image/ImageLoaderJpeg.cpp | 26 ++++++++++++++++++++++++ openVulkanoCpp/Image/ImageLoaderJpeg.hpp | 2 +- openVulkanoCpp/Image/ImageLoaderPng.cpp | 5 +++++ openVulkanoCpp/Image/ImageLoaderPng.hpp | 1 + 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Image/ImageLoader.cpp b/openVulkanoCpp/Image/ImageLoader.cpp index 624818e..c1b001a 100644 --- a/openVulkanoCpp/Image/ImageLoader.cpp +++ b/openVulkanoCpp/Image/ImageLoader.cpp @@ -60,4 +60,10 @@ namespace OpenVulkano::Image stbi_image_free(pixelData); return std::make_unique(std::move(result)); } + + bool IImageLoader::GetDimensionsInternal(const std::string& filename, int& width, int& height) + { + int channels; + return stbi_info(filename.c_str(), &width, &height, &channels); + } } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoader.hpp b/openVulkanoCpp/Image/ImageLoader.hpp index 1bc6b0f..3af4d86 100644 --- a/openVulkanoCpp/Image/ImageLoader.hpp +++ b/openVulkanoCpp/Image/ImageLoader.hpp @@ -21,5 +21,8 @@ namespace OpenVulkano::Image static std::unique_ptr loadData(const uint8_t* data, int size, int desiredChannels = 0); virtual std::unique_ptr loadFromFile(const std::string& filePath) = 0; virtual std::unique_ptr loadFromMemory(const std::vector& buffer) = 0; + virtual bool GetImageDimensions(const std::string& filename, int& width, int& height) = 0; + protected: + static bool GetDimensionsInternal(const std::string& filename, int& width, int& height); }; } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp index 4afd5f0..b7bd57e 100644 --- a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp @@ -31,6 +31,32 @@ namespace OpenVulkano::Image return loadJpeg(buffer.data(), buffer.size()); } + bool ImageLoaderJpeg::GetImageDimensions(const std::string& filename, int& width, int& height) + { +#if __has_include("turbojpeg.h") + auto image = Utils::ReadFile(filename); + tjhandle jpegDecompressor = tjInitDecompress(); + if (!jpegDecompressor) + { + Logger::FILESYS->error("Failed to read jpeg header. Error: {}", tjGetErrorStr()); + return false; + } + int size = 0, jpegSubsamp = 0; + int status = tjDecompressHeader2(jpegDecompressor, reinterpret_cast(image.Data()), image.Size(), + &width, &height, &jpegSubsamp); + if (status != 0) + { + Logger::FILESYS->error("Failed to read jpeg header. Error: {}", tjGetErrorStr()); + tjDestroy(jpegDecompressor); + return false; + } + tjDestroy(jpegDecompressor); + return true; +#else + return IImageLoader::GetDimensionsInternal(filename, width, height); +#endif + } + std::unique_ptr ImageLoaderJpeg::loadJpeg(const uint8_t* data, size_t size) { #if __has_include("turbojpeg.h") diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.hpp b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp index 5890ac9..a127b18 100644 --- a/openVulkanoCpp/Image/ImageLoaderJpeg.hpp +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp @@ -15,7 +15,7 @@ namespace OpenVulkano::Image public: std::unique_ptr loadFromFile(const std::string& filePath) override; std::unique_ptr loadFromMemory(const std::vector& buffer) override; - + bool GetImageDimensions(const std::string& filename, int& width, int& height) override; private: std::unique_ptr loadJpeg(const uint8_t* data, size_t size); }; diff --git a/openVulkanoCpp/Image/ImageLoaderPng.cpp b/openVulkanoCpp/Image/ImageLoaderPng.cpp index 0968e4f..462f0f8 100644 --- a/openVulkanoCpp/Image/ImageLoaderPng.cpp +++ b/openVulkanoCpp/Image/ImageLoaderPng.cpp @@ -22,4 +22,9 @@ namespace OpenVulkano::Image { return loadData(buffer.data(), static_cast(buffer.size())); } + + bool ImageLoaderPng::GetImageDimensions(const std::string& filename, int& width, int& height) + { + return GetDimensionsInternal(filename, width, height); + } } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderPng.hpp b/openVulkanoCpp/Image/ImageLoaderPng.hpp index 7b449cf..ef0181b 100644 --- a/openVulkanoCpp/Image/ImageLoaderPng.hpp +++ b/openVulkanoCpp/Image/ImageLoaderPng.hpp @@ -15,5 +15,6 @@ namespace OpenVulkano::Image public: std::unique_ptr loadFromFile(const std::string& filePath) override; std::unique_ptr loadFromMemory(const std::vector& buffer) override; + bool GetImageDimensions(const std::string& filename, int& width, int& height) override; }; } \ No newline at end of file From aaa8974006de2c27d974875156e69d1c3af38cb0 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Mon, 7 Oct 2024 17:46:34 +0300 Subject: [PATCH 2/2] change signature --- openVulkanoCpp/Image/ImageLoader.cpp | 10 ++++++++-- openVulkanoCpp/Image/ImageLoader.hpp | 4 ++-- openVulkanoCpp/Image/ImageLoaderJpeg.cpp | 13 +++++++------ openVulkanoCpp/Image/ImageLoaderJpeg.hpp | 2 +- openVulkanoCpp/Image/ImageLoaderPng.cpp | 4 ++-- openVulkanoCpp/Image/ImageLoaderPng.hpp | 2 +- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/openVulkanoCpp/Image/ImageLoader.cpp b/openVulkanoCpp/Image/ImageLoader.cpp index c1b001a..14c51e5 100644 --- a/openVulkanoCpp/Image/ImageLoader.cpp +++ b/openVulkanoCpp/Image/ImageLoader.cpp @@ -61,9 +61,15 @@ namespace OpenVulkano::Image return std::make_unique(std::move(result)); } - bool IImageLoader::GetDimensionsInternal(const std::string& filename, int& width, int& height) + Math::Vector2i IImageLoader::GetDimensionsInternal(const std::string& filename) { + Math::Vector2i res = {}; int channels; - return stbi_info(filename.c_str(), &width, &height, &channels); + if (!stbi_info(filename.c_str(), &res.x, &res.y, &channels)) + { + Logger::FILESYS->error("Failed to read image header of file {}", filename); + return Math::Vector2i{ -1, -1 }; + } + return res; } } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoader.hpp b/openVulkanoCpp/Image/ImageLoader.hpp index 3af4d86..d6340da 100644 --- a/openVulkanoCpp/Image/ImageLoader.hpp +++ b/openVulkanoCpp/Image/ImageLoader.hpp @@ -21,8 +21,8 @@ namespace OpenVulkano::Image static std::unique_ptr loadData(const uint8_t* data, int size, int desiredChannels = 0); virtual std::unique_ptr loadFromFile(const std::string& filePath) = 0; virtual std::unique_ptr loadFromMemory(const std::vector& buffer) = 0; - virtual bool GetImageDimensions(const std::string& filename, int& width, int& height) = 0; + virtual Math::Vector2i GetImageDimensions(const std::string& filename) = 0; protected: - static bool GetDimensionsInternal(const std::string& filename, int& width, int& height); + static Math::Vector2i GetDimensionsInternal(const std::string& filename); }; } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp index b7bd57e..1a9fe74 100644 --- a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp @@ -31,7 +31,7 @@ namespace OpenVulkano::Image return loadJpeg(buffer.data(), buffer.size()); } - bool ImageLoaderJpeg::GetImageDimensions(const std::string& filename, int& width, int& height) + Math::Vector2i ImageLoaderJpeg::GetImageDimensions(const std::string& filename) { #if __has_include("turbojpeg.h") auto image = Utils::ReadFile(filename); @@ -39,21 +39,22 @@ namespace OpenVulkano::Image if (!jpegDecompressor) { Logger::FILESYS->error("Failed to read jpeg header. Error: {}", tjGetErrorStr()); - return false; + return Math::Vector2i { -1, -1 }; } + Math::Vector2i res = {}; int size = 0, jpegSubsamp = 0; int status = tjDecompressHeader2(jpegDecompressor, reinterpret_cast(image.Data()), image.Size(), - &width, &height, &jpegSubsamp); + &res.x, &res.y, &jpegSubsamp); if (status != 0) { Logger::FILESYS->error("Failed to read jpeg header. Error: {}", tjGetErrorStr()); tjDestroy(jpegDecompressor); - return false; + return Math::Vector2i { -1, -1 }; } tjDestroy(jpegDecompressor); - return true; + return res; #else - return IImageLoader::GetDimensionsInternal(filename, width, height); + return IImageLoader::GetDimensionsInternal(filename); #endif } diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.hpp b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp index a127b18..8b5d87a 100644 --- a/openVulkanoCpp/Image/ImageLoaderJpeg.hpp +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp @@ -15,7 +15,7 @@ namespace OpenVulkano::Image public: std::unique_ptr loadFromFile(const std::string& filePath) override; std::unique_ptr loadFromMemory(const std::vector& buffer) override; - bool GetImageDimensions(const std::string& filename, int& width, int& height) override; + Math::Vector2i GetImageDimensions(const std::string& filename) override; private: std::unique_ptr loadJpeg(const uint8_t* data, size_t size); }; diff --git a/openVulkanoCpp/Image/ImageLoaderPng.cpp b/openVulkanoCpp/Image/ImageLoaderPng.cpp index 462f0f8..92900b9 100644 --- a/openVulkanoCpp/Image/ImageLoaderPng.cpp +++ b/openVulkanoCpp/Image/ImageLoaderPng.cpp @@ -23,8 +23,8 @@ namespace OpenVulkano::Image return loadData(buffer.data(), static_cast(buffer.size())); } - bool ImageLoaderPng::GetImageDimensions(const std::string& filename, int& width, int& height) + Math::Vector2i ImageLoaderPng::GetImageDimensions(const std::string& filename) { - return GetDimensionsInternal(filename, width, height); + return GetDimensionsInternal(filename); } } \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderPng.hpp b/openVulkanoCpp/Image/ImageLoaderPng.hpp index ef0181b..2ab52dc 100644 --- a/openVulkanoCpp/Image/ImageLoaderPng.hpp +++ b/openVulkanoCpp/Image/ImageLoaderPng.hpp @@ -15,6 +15,6 @@ namespace OpenVulkano::Image public: std::unique_ptr loadFromFile(const std::string& filePath) override; std::unique_ptr loadFromMemory(const std::vector& buffer) override; - bool GetImageDimensions(const std::string& filename, int& width, int& height) override; + Math::Vector2i GetImageDimensions(const std::string& filename) override; }; } \ No newline at end of file