From 9ce87e74273ee1ad08fd10968202bb866cbbe6e0 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Wed, 3 Dec 2025 01:02:03 +0100 Subject: [PATCH] Add TiffWrapper --- 3rdParty/CMakeLists.txt | 1 + openVulkanoCpp/CMakeLists.txt | 2 +- openVulkanoCpp/Image/TiffWrapper.hpp | 242 +++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 openVulkanoCpp/Image/TiffWrapper.hpp diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index 570d0af..926a23b 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -37,6 +37,7 @@ add_subdirectory(moodycamel_concurrentqueue) add_subdirectory(tinyusdz) add_subdirectory(dds_image) add_subdirectory(brotli) +add_subdirectory(libtiff) if (NOT IOS AND OPENVULKANO_ENABLE_CURL) add_subdirectory(curl) diff --git a/openVulkanoCpp/CMakeLists.txt b/openVulkanoCpp/CMakeLists.txt index ac456fc..7924fe9 100644 --- a/openVulkanoCpp/CMakeLists.txt +++ b/openVulkanoCpp/CMakeLists.txt @@ -75,7 +75,7 @@ if (IOS) ) endif () -target_link_libraries(openVulkanoCpp PUBLIC magic_enum brotlienc brotlidec yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense concurrentqueue units dds_image) +target_link_libraries(openVulkanoCpp PUBLIC magic_enum brotlienc brotlidec yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense concurrentqueue units dds_image tiff) if (OPENVULKANO_ENABLE_KTX) target_link_libraries(openVulkanoCpp PUBLIC ktx) endif () diff --git a/openVulkanoCpp/Image/TiffWrapper.hpp b/openVulkanoCpp/Image/TiffWrapper.hpp new file mode 100644 index 0000000..e45a69d --- /dev/null +++ b/openVulkanoCpp/Image/TiffWrapper.hpp @@ -0,0 +1,242 @@ +/* + * 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 + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" + +#include "Math/Math.hpp" +#include +#include + +namespace OpenVulkano +{ + class TiffWrapper final + { + TIFF* tiff = nullptr; + + public: + //region Base C++ wrapping + TiffWrapper() = default; + TiffWrapper(const std::filesystem::path& path) { Open(path); } + TiffWrapper(const TiffWrapper&) = delete; + TiffWrapper(TiffWrapper&& other) : tiff(other.tiff) { other.tiff = nullptr; } + ~TiffWrapper() { } + TiffWrapper& Open(const std::filesystem::path& path) + { + Close(); +#ifdef _WIN32 + tiff = TIFFOpenW(path.c_str(), "w"); +#else + tiff = TIFFOpen(path.c_str(), "w"); +#endif + return *this; + } + void Close() { if (tiff) TIFFClose(tiff); tiff = nullptr; } + operator TIFF*() { return tiff; } + TiffWrapper& operator =(const TiffWrapper&) = delete; + TiffWrapper& operator =(TiffWrapper&& other) { Close(); tiff = other.tiff; other.tiff = nullptr; return *this; } + //endregion + + //region TIFF functions + void Cleanup() { TIFFCleanup(tiff); } + bool Flush() { return TIFFFlush(tiff); } + bool FlushData() { return TIFFFlushData(tiff); } + + template + void SetField(uint32_t tag, Args&&... args) + { + TIFFSetField(tiff, tag, std::forward(args)...); + } + void UnsetField(uint32_t tag) { TIFFUnsetField(tiff, tag); } + [[nodiscard]] int GetField(const uint32_t tag) const { return TIFFGetField(tiff, tag); } + int VGetField(const uint32_t tag, va_list ap) { return TIFFVGetField(tiff, tag, ap); } + [[nodiscard]] int GetFieldDefaulted(const uint32_t tag) { return TIFFGetFieldDefaulted(tiff, tag); } + int VGetFieldDefaulted(const uint32_t tag, va_list ap) { return TIFFVGetFieldDefaulted(tiff, tag, ap); } + + int GetTagListCount() { return TIFFGetTagListCount(tiff); } + uint32_t GetTagListEntry(const int tagIndex) { return TIFFGetTagListEntry(tiff, tagIndex); } + + const TIFFField* FindField(const uint32_t tag, const TIFFDataType dt) { return TIFFFindField(tiff, tag, dt); } + const TIFFField* FieldWithTag(const uint32_t tag) { return TIFFFieldWithTag(tiff, tag); } + const TIFFField* FieldWithName(const char* tag) { return TIFFFieldWithName(tiff, tag); } + + TIFFTagMethods * AccessTagMethods() { return TIFFAccessTagMethods(tiff); } + void* GetClientInfo(const char* name) { return TIFFGetClientInfo(tiff, name); } + void SetClientInfo(void* data, const char* name) { TIFFSetClientInfo(tiff, data, name); } + + bool ReadDirectory() { return TIFFReadDirectory(tiff); } + bool ReadCustomDirectory(const uint64_t dirOffset, const TIFFFieldArray* infoArray) { + return TIFFReadCustomDirectory(tiff, dirOffset, infoArray); + } + bool ReadEXIFDirectory(const uint64_t dirOffset) { return TIFFReadEXIFDirectory(tiff, dirOffset); } + bool ReadGPSDirectory(const uint64_t dirOffset) { return TIFFReadGPSDirectory(tiff, dirOffset); } + + [[nodiscard]] uint64_t ScanlineSize64() const { return TIFFScanlineSize64(tiff); } + [[nodiscard]] tmsize_t ScanlineSize() const { return TIFFScanlineSize(tiff); } + [[nodiscard]] uint64_t RasterScanlineSize64() const { return TIFFRasterScanlineSize64(tiff); } + [[nodiscard]] tmsize_t RasterScanlineSize() const { return TIFFRasterScanlineSize(tiff); } + [[nodiscard]] uint64_t StripSize64() const { return TIFFStripSize64(tiff); } + [[nodiscard]] tmsize_t StripSize() const { return TIFFStripSize(tiff); } + [[nodiscard]] uint64_t RawStripSize64(const uint32_t strip) const { return TIFFRawStripSize64(tiff, strip); } + [[nodiscard]] tmsize_t RawStripSize(const uint32_t strip) const { return TIFFRawStripSize(tiff, strip); } + [[nodiscard]] uint64_t VStripSize64(const uint32_t numRows) const { return TIFFVStripSize64(tiff, numRows); } + [[nodiscard]] tmsize_t VStripSize(const uint32_t numRows) const { return TIFFVStripSize(tiff, numRows); } + [[nodiscard]] uint64_t TileRowSize64() const { return TIFFTileRowSize64(tiff); } + [[nodiscard]] tmsize_t TileRowSize() const { return TIFFTileRowSize(tiff); } + [[nodiscard]] uint64_t TileSize64() const { return TIFFTileSize64(tiff); } + [[nodiscard]] tmsize_t TileSize() const { return TIFFTileSize(tiff); } + [[nodiscard]] uint64_t VTileSize64(const uint32_t numRows) const { return TIFFVTileSize64(tiff, numRows); } + [[nodiscard]] tmsize_t VTileSize(const uint32_t numRows) const { return TIFFVTileSize(tiff, numRows); } + [[nodiscard]] uint32_t DefaultStripSize(unsigned int request) { return TIFFDefaultStripSize(tiff, request); } + [[nodiscard]] Math::Vector2ui DefaultTileSize() const + { + Math::Vector2ui res; + TIFFDefaultTileSize(tiff, &res.x, &res.y); + return res; + } + [[nodiscard]] int FileDescriptor() { return TIFFFileno(tiff); } + int SetFileDescriptor(int fd) { return TIFFSetFileno(tiff, fd); } + [[nodiscard]] thandle_t Clientdata() const { return TIFFClientdata(tiff); } + thandle_t SetClientdata(thandle_t newValue) { return TIFFSetClientdata(tiff, newValue); } + [[nodiscard]] int GetMode() const { return TIFFGetMode(tiff); } + int SetMode(int mode) { return TIFFSetMode(tiff, mode); } + [[nodiscard]] bool IsTiled() const { return TIFFIsTiled(tiff); } + [[nodiscard]] bool IsByteSwapped() const { return TIFFIsByteSwapped(tiff); } + [[nodiscard]] bool IsUpSampled() const { return TIFFIsUpSampled(tiff); } + [[nodiscard]] bool IsMSB2LSB() const { return TIFFIsMSB2LSB(tiff); } + [[nodiscard]] bool IsBigEndian() const { return TIFFIsBigEndian(tiff); } + [[nodiscard]] TIFFReadWriteProc GetReadProc() const { return TIFFGetReadProc(tiff); } + [[nodiscard]] TIFFReadWriteProc GetWriteProc() const { return TIFFGetWriteProc(tiff); } + [[nodiscard]] TIFFSeekProc GetSeekProc() const { return TIFFGetSeekProc(tiff); } + [[nodiscard]] TIFFCloseProc GetCloseProc() const { return TIFFGetCloseProc(tiff); } + [[nodiscard]] TIFFSizeProc GetSizeProc() const { return TIFFGetSizeProc(tiff); } + [[nodiscard]] TIFFMapFileProc GetMapFileProc() const { return TIFFGetMapFileProc(tiff); } + [[nodiscard]] TIFFUnmapFileProc GetUnmapFileProc() const { return TIFFGetUnmapFileProc(tiff); } + [[nodiscard]] uint32_t CurrentRow() const { return TIFFCurrentRow(tiff); } + [[nodiscard]] uint16_t CurrentDirectory() const { return TIFFCurrentDirectory(tiff); } + [[nodiscard]] uint16_t NumberOfDirectories() const { return TIFFNumberOfDirectories(tiff); } + [[nodiscard]] uint64_t CurrentDirOffset() const { return TIFFCurrentDirOffset(tiff); } + [[nodiscard]] uint32_t CurrentStrip() const { return TIFFCurrentStrip(tiff); } + [[nodiscard]] uint32_t CurrentTile() const { return TIFFCurrentTile(tiff); } + int ReadBufferSetup(void* bp, tmsize_t size) { + return TIFFReadBufferSetup(tiff, bp, size); + } + int WriteBufferSetup(void * bp, tmsize_t size) { + return TIFFWriteBufferSetup(tiff, bp, size); + } + int SetupStrips() const { return TIFFSetupStrips(tiff); } + int WriteCheck(int p0, const char * p1) { + return TIFFWriteCheck(tiff, p0, p1); + } + void FreeDirectory() { TIFFFreeDirectory(tiff); } + int CreateDirectory() { return TIFFCreateDirectory(tiff); } + int CreateCustomDirectory(const TIFFFieldArray * p0) { + return TIFFCreateCustomDirectory(tiff, p0); + } + int CreateEXIFDirectory() { return TIFFCreateEXIFDirectory(tiff); } + bool LastDirectory() { return TIFFLastDirectory(tiff); } + int SetDirectory(unsigned short int p0) { + return TIFFSetDirectory(tiff, p0); + } + int SetSubDirectory(uint64_t p0) { + return TIFFSetSubDirectory(tiff, p0); + } + int UnlinkDirectory(unsigned short int p0) { + return TIFFUnlinkDirectory(tiff, p0); + } + int WriteDirectory() { + return TIFFWriteDirectory(tiff); + } + int WriteCustomDirectory(uint64_t* dirOffset) { + return TIFFWriteCustomDirectory(tiff, dirOffset); + } + int CheckpointDirectory() { + return TIFFCheckpointDirectory(tiff); + } + int RewriteDirectory() { + return TIFFRewriteDirectory(tiff); + } + void PrintDirectory(FILE* file, long flags) { + TIFFPrintDirectory(tiff, file, flags); + } + int ReadScanline(void * buf, unsigned int row, unsigned short int sample) { + return TIFFReadScanline(tiff, buf, row, sample); + } + int WriteScanline(void * buf, unsigned int row, unsigned short int sample) { + return TIFFWriteScanline(tiff, buf, row, sample); + } + int ReadRGBAImage(uint32_t rwidth, uint32_t rheight, uint32_t* raster, int stop) { + return TIFFReadRGBAImage(tiff, rwidth, rheight, raster, stop); + } + int ReadRGBAImageOriented(uint32_t rwidth, uint32_t rheight, + uint32_t *raster, int orientation, int stop) { + return TIFFReadRGBAImageOriented(tiff, rwidth, rheight, raster, orientation, stop); + } + int ReadRGBAStrip(uint32_t row, uint32_t *raster) { + return TIFFReadRGBAStrip(tiff, row, raster); + } + int ReadRGBATile(uint32_t col, uint32_t row, uint32_t *raster) { + return TIFFReadRGBATile(tiff, col, row, raster); + } + int ReadRGBAStripExt(uint32_t row, uint32_t *raster, int stop_on_error) { + return TIFFReadRGBAStripExt(tiff, row, raster, stop_on_error); + } + int ReadRGBATileExt(uint32_t col, uint32_t row, uint32_t *raster, int stop_on_error) { + return TIFFReadRGBATileExt(tiff, col, row, raster, stop_on_error); + } + int RGBAImageOK(char p0[1024]) { + return TIFFRGBAImageOK(tiff, p0); + } + [[nodiscard]] std::string FileName() const { return TIFFFileName(tiff); } + uint32_t ComputeTile(unsigned int x, unsigned int y, unsigned int z, unsigned short int s) { + return TIFFComputeTile(tiff, x, y, z, s); + } + int CheckTile(unsigned int x, unsigned int y, unsigned int z, unsigned short int s) { + return TIFFCheckTile(tiff, x, y, z, s); + } + [[nodiscard]] uint32_t NumberOfTiles() const { return TIFFNumberOfTiles(tiff); } + tmsize_t ReadTile(void * buf, unsigned int x, unsigned int y, unsigned int z, unsigned short int s) { + return TIFFReadTile(tiff, buf, x, y, z, s); + } + tmsize_t WriteTile(void * buf, unsigned int x, unsigned int y, unsigned int z, unsigned short int s) { + return TIFFWriteTile(tiff, buf, x, y, z, s); + } + uint32_t ComputeStrip(unsigned int p0, unsigned short int p1) { + return TIFFComputeStrip(tiff, p0, p1); + } + [[nodiscard]] uint32_t NumberOfStrips() const { return TIFFNumberOfStrips(tiff); } + tmsize_t ReadEncodedStrip(unsigned int strip, void * buf, tmsize_t size) { + return TIFFReadEncodedStrip(tiff, strip, buf, size); + } + tmsize_t ReadRawStrip(unsigned int strip, void * buf, tmsize_t size) { + return TIFFReadRawStrip(tiff, strip, buf, size); + } + tmsize_t ReadEncodedTile(unsigned int tile, void * buf, tmsize_t size) { + return TIFFReadEncodedTile(tiff, tile, buf, size); + } + tmsize_t ReadRawTile(unsigned int tile, void * buf, tmsize_t size) { + return TIFFReadRawTile(tiff, tile, buf, size); + } + tmsize_t WriteEncodedStrip(unsigned int strip, void * data, tmsize_t cc) { + return TIFFWriteEncodedStrip(tiff, strip, data, cc); + } + tmsize_t WriteRawStrip(unsigned int strip, void * data, tmsize_t cc) { + return TIFFWriteRawStrip(tiff, strip, data, cc); + } + tmsize_t WriteEncodedTile(unsigned int tile, void * data, tmsize_t cc) { + return TIFFWriteEncodedTile(tiff, tile, data, cc); + } + tmsize_t WriteRawTile(unsigned int tile, void * data, tmsize_t cc) { + return TIFFWriteRawTile(tiff, tile, data, cc); + } + void SetWriteOffset(const uint64_t offset) { TIFFSetWriteOffset(tiff, offset); } + //endregion + }; +} + +#pragma clang diagnostic pop \ No newline at end of file