From b572da31ac62fcf3962246a363b75cc1155fae55 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Tue, 16 Jul 2024 18:47:35 +0300 Subject: [PATCH 1/2] Image && ImageLoaderJpeg classes --- openVulkanoCpp/Image/Image.hpp | 28 +++++++++ openVulkanoCpp/Image/ImageLoader.hpp | 24 ++++++++ openVulkanoCpp/Image/ImageLoaderJpeg.cpp | 72 ++++++++++++++++++++++++ openVulkanoCpp/Image/ImageLoaderJpeg.hpp | 22 ++++++++ 4 files changed, 146 insertions(+) create mode 100644 openVulkanoCpp/Image/Image.hpp create mode 100644 openVulkanoCpp/Image/ImageLoader.hpp create mode 100644 openVulkanoCpp/Image/ImageLoaderJpeg.cpp create mode 100644 openVulkanoCpp/Image/ImageLoaderJpeg.hpp diff --git a/openVulkanoCpp/Image/Image.hpp b/openVulkanoCpp/Image/Image.hpp new file mode 100644 index 0000000..b440de3 --- /dev/null +++ b/openVulkanoCpp/Image/Image.hpp @@ -0,0 +1,28 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Data/Containers/Array.hpp" +#include "Math/Math.hpp" +#include "Scene/DataFormat.hpp" + +namespace OpenVulkano::Image +{ + enum class ImageFileType + { + JPEG, + PNG, + BMP, + }; + + struct Image + { + Math::Vector3ui resolution; + DataFormat dataFormat; + Array data; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoader.hpp b/openVulkanoCpp/Image/ImageLoader.hpp new file mode 100644 index 0000000..d3a288f --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoader.hpp @@ -0,0 +1,24 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Image.hpp" +#include +#include +#include + +namespace OpenVulkano::Image +{ + class IImageLoader + { + public: + virtual ~IImageLoader() = default; + + virtual std::unique_ptr loadFromFile(const std::string& filePath) = 0; + virtual std::unique_ptr loadFromMemory(const std::vector& buffer) = 0; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp new file mode 100644 index 0000000..703fb24 --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp @@ -0,0 +1,72 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ImageLoaderJpeg.hpp" +#include +#include +#include + +#if __has_include("turbojpeg.h") + #include +#else + #define STB_IMAGE_IMPLEMENTATION + #include +#endif + +namespace OpenVulkano::Image +{ + std::unique_ptr ImageLoaderJpeg::loadFromFile(const std::string& filePath) + { + std::ifstream file(filePath, std::ios::binary); + if (!file) { throw std::runtime_error("Could not open file: " + filePath); } + std::vector buffer((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + return loadJpeg(buffer.data(), buffer.size()); + } + + std::unique_ptr ImageLoaderJpeg::loadFromMemory(const std::vector& buffer) + { + return loadJpeg(buffer.data(), buffer.size()); + } + + std::unique_ptr ImageLoaderJpeg::loadJpeg(const uint8_t* data, size_t size) + { + Image result; + + int rows, cols; +#if __has_include("turbojpeg.h") + { + unsigned char* compressedImage = const_cast(data); + + int jpegSubsamp; + tjhandle jpegDecompressor = tjInitDecompress(); + tjDecompressHeader2(jpegDecompressor, compressedImage, size, &cols, &rows, &jpegSubsamp); + + const int channels = 4; + result.data = OpenVulkano::Array(cols * rows * channels); + result.dataFormat = OpenVulkano::DataFormat::R8G8B8A8_UINT; + + tjDecompress2(jpegDecompressor, compressedImage, size, result.data.Data(), cols, 0 /*pitch*/, rows, + TJPF_RGBA, TJFLAG_FASTDCT); + tjDestroy(jpegDecompressor); + } +#else + { + int channels; + uint8_t* pixelData = stbi_load_from_memory(data, size, &cols, &rows, &channels, 3); + result.data = OpenVulkano::Array(cols * rows * channels); + result.dataFormat = channels == 3 ? OpenVulkano::DataFormat::R8G8B8_UINT : + OpenVulkano::DataFormat::R8G8B8A8_UINT; + std::memcpy(result.data.Data(), pixelData, result.data.Size()); + stbi_image_free(pixelData); + } +#endif + result.resolution.x = cols; + result.resolution.y = rows; + result.resolution.z = 1; + + return std::make_unique(result); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.hpp b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp new file mode 100644 index 0000000..5890ac9 --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.hpp @@ -0,0 +1,22 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ImageLoader.hpp" + +namespace OpenVulkano::Image +{ + class ImageLoaderJpeg : public IImageLoader + { + public: + std::unique_ptr loadFromFile(const std::string& filePath) override; + std::unique_ptr loadFromMemory(const std::vector& buffer) override; + + private: + std::unique_ptr loadJpeg(const uint8_t* data, size_t size); + }; +} \ No newline at end of file From 91a81c1e9c0a2b659fb7f93373f92a16fea7f9c9 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Tue, 16 Jul 2024 21:40:24 +0300 Subject: [PATCH 2/2] Moving result struct instead of copying --- openVulkanoCpp/Image/ImageLoaderJpeg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp index 703fb24..f9daec4 100644 --- a/openVulkanoCpp/Image/ImageLoaderJpeg.cpp +++ b/openVulkanoCpp/Image/ImageLoaderJpeg.cpp @@ -67,6 +67,6 @@ namespace OpenVulkano::Image result.resolution.y = rows; result.resolution.z = 1; - return std::make_unique(result); + return std::make_unique(std::move(result)); } } \ No newline at end of file