/* * 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 TiffCompression { public: enum Compression: uint8_t { UNKNOWN = 0, NONE, LZW, JPEG, DEFLATE, ZSTD }; TiffCompression() : compression(NONE) {} TiffCompression(Compression compression) : compression(compression) {} TiffCompression(const TiffCompression&) = default; TiffCompression(TiffCompression&&) = default; TiffCompression& operator =(const Compression comp) { compression = comp; return *this; } TiffCompression& operator =(const TiffCompression&) = default; TiffCompression& operator =(TiffCompression&&) = default; [[nodiscard]] uint16_t GetTiffType() const { switch (compression) { case LZW: return COMPRESSION_LZW; case JPEG: return COMPRESSION_JPEG; case DEFLATE: return COMPRESSION_DEFLATE; case ZSTD: return COMPRESSION_ZSTD; default: break; } return COMPRESSION_NONE; } static TiffCompression FromTiffType(const uint16_t comp) { switch (comp) { case COMPRESSION_NONE: return NONE; case COMPRESSION_LZW: return LZW; case COMPRESSION_JPEG: return JPEG; case COMPRESSION_DEFLATE: return DEFLATE; case COMPRESSION_ZSTD: return ZSTD; } return UNKNOWN; } private: Compression compression; }; 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); } //region TIFF fields template void SetField(uint32_t tag, Args&&... args) { TIFFSetField(tiff, tag, std::forward(args)...); } void UnsetField(uint32_t tag) { TIFFUnsetField(tiff, tag); } template bool GetField(const uint32_t tag, Args&&... args) const { return TIFFGetField(tiff, tag, std::forward(args)...); } 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); } //endregion [[nodiscard]] int GetTagListCount() const { return TIFFGetTagListCount(tiff); } [[nodiscard]] uint32_t GetTagListEntry(const int tagIndex) const { return TIFFGetTagListEntry(tiff, tagIndex); } [[nodiscard]] const TIFFField* FindField(const uint32_t tag, const TIFFDataType dt) { return TIFFFindField(tiff, tag, dt); } [[nodiscard]] const TIFFField* FieldWithTag(const uint32_t tag) { return TIFFFieldWithTag(tiff, tag); } [[nodiscard]] const TIFFField* FieldWithName(const char* tag) { return TIFFFieldWithName(tiff, tag); } [[nodiscard]] TIFFTagMethods* AccessTagMethods() const { return TIFFAccessTagMethods(tiff); } [[nodiscard]] void* GetClientInfo(const char* name) const { 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(uint32_t 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, uint32_t row, unsigned short int sample) { return TIFFReadScanline(tiff, buf, row, sample); } int WriteScanline(void * buf, uint32_t 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(uint32_t x, uint32_t y, uint32_t z, unsigned short int s) { return TIFFComputeTile(tiff, x, y, z, s); } int CheckTile(uint32_t x, uint32_t y, uint32_t 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, uint32_t x, uint32_t y, uint32_t z, unsigned short int s) { return TIFFReadTile(tiff, buf, x, y, z, s); } tmsize_t WriteTile(void* buf, uint32_t x, uint32_t y, uint32_t z = 0, uint16_t s = 0) { return TIFFWriteTile(tiff, buf, x, y, z, s); } uint32_t ComputeStrip(uint32_t row, uint16_t sample) { return TIFFComputeStrip(tiff, row, sample); } [[nodiscard]] uint32_t NumberOfStrips() const { return TIFFNumberOfStrips(tiff); } tmsize_t ReadEncodedStrip(uint32_t strip, void* buf, tmsize_t size) { return TIFFReadEncodedStrip(tiff, strip, buf, size); } tmsize_t ReadRawStrip(uint32_t strip, void* buf, tmsize_t size) { return TIFFReadRawStrip(tiff, strip, buf, size); } tmsize_t ReadEncodedTile(uint32_t tile, void* buf, tmsize_t size) { return TIFFReadEncodedTile(tiff, tile, buf, size); } tmsize_t ReadRawTile(uint32_t tile, void* buf, tmsize_t size) { return TIFFReadRawTile(tiff, tile, buf, size); } tmsize_t WriteEncodedStrip(uint32_t strip, void* data, tmsize_t cc) { return TIFFWriteEncodedStrip(tiff, strip, data, cc); } tmsize_t WriteRawStrip(uint32_t strip, void* data, tmsize_t cc) { return TIFFWriteRawStrip(tiff, strip, data, cc); } tmsize_t WriteEncodedTile(uint32_t tile, void* data, tmsize_t cc) { return TIFFWriteEncodedTile(tiff, tile, data, cc); } tmsize_t WriteRawTile(uint32_t tile, void* data, tmsize_t cc) { return TIFFWriteRawTile(tiff, tile, data, cc); } void SetWriteOffset(const uint64_t offset) { TIFFSetWriteOffset(tiff, offset); } //endregion //region Convenience TIFF field functions //TODO get defaults void SetResolution(const Math::Vector2ui& resolution) { SetField(TIFFTAG_IMAGEWIDTH, resolution.x); SetField(TIFFTAG_IMAGELENGTH, resolution.y); } void SetTileResolution(const Math::Vector2ui& resolution) { SetField(TIFFTAG_TILEWIDTH, resolution.x); SetField(TIFFTAG_TILELENGTH, resolution.y); } [[nodiscard]] Math::Vector2ui GetResolution() const { Math::Vector2ui resolution; GetField(TIFFTAG_IMAGEWIDTH, &resolution.x); GetField(TIFFTAG_IMAGELENGTH, &resolution.y); return resolution; } [[nodiscard]] Math::Vector2ui GetTileResolution() const { Math::Vector2ui resolution; GetField(TIFFTAG_TILEWIDTH, &resolution.x); GetField(TIFFTAG_TILELENGTH, &resolution.y); return resolution; } void SetCompression(const TiffCompression compression) { SetField(TIFFTAG_COMPRESSION, compression.GetTiffType()); } [[nodiscard]] TiffCompression GetCompression() const { uint16_t comp; GetField(TIFFTAG_COMPRESSION, &comp); return TiffCompression::FromTiffType(comp); } void SetResolutionUnit(const Math::Vector2f& scale, uint16_t type = RESUNIT_INCH) { SetField(TIFFTAG_RESOLUTIONUNIT, type); SetField(TIFFTAG_XRESOLUTION, scale.x); SetField(TIFFTAG_YRESOLUTION, scale.y); } //endregion }; } #pragma clang diagnostic pop