1 /*************************************************************************** 2 tiff.hxx - GDL TIFF library functions 3 ------------------- 4 begin : May 22 2018 5 copyright : (C) 2018 by Remi A. Solås 6 email : remi.solaas (at) edinsights.no 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef TIFF_HXX_CL 19 #define TIFF_HXX_CL 20 21 #include "includefirst.hpp" 22 #include "datatypes.hpp" 23 #include "envt.hpp" 24 25 #ifdef USE_GEOTIFF 26 # include <xtiffio.h> 27 # include <geotiff.h> 28 #else 29 # include <tiffio.h> 30 #endif 31 32 namespace lib 33 { 34 namespace TIFF 35 { 36 struct Directory 37 { 38 tdir_t index = 0; 39 uint32_t width = 0; 40 uint32_t height = 0; 41 uint32_t tileWidth = 0; 42 uint32_t tileHeight = 0; 43 uint16_t samplesPerPixel = 1; 44 uint16_t bitsPerSample = 1; 45 46 struct Position 47 { 48 float x = 0.f; 49 float y = 0.f; 50 } position; 51 52 struct Resolution 53 { 54 float x = 1.f; 55 float y = 1.f; 56 57 enum class Unit : uint16_t 58 { 59 None = 1, 60 Inches = 2, 61 Centimeters = 3, 62 } unit = Unit::Inches; 63 } resolution; 64 65 enum class Orientation : uint16_t 66 { 67 LeftToRightTopToBottom = 1, 68 RightToLeftTopToBottom = 2, 69 RightToLeftBottomToTop = 3, 70 LeftToRigthBottomToTop = 4, 71 TopToBottomLeftToRight = 5, 72 TopToBottomRigthToLeft = 6, 73 BottomToTopRightToLeft = 7, 74 BottomToTopLeftToRight = 8, 75 } orientation = Orientation::LeftToRightTopToBottom; 76 77 enum class SampleFormat : uint16_t 78 { 79 UnsignedInteger = 1, 80 SignedInteger = 2, 81 FloatingPoint = 3, 82 Untyped = 4, 83 ComplexInteger = 5, 84 ComplexFloatingPoint = 6, 85 } sampleFormat = SampleFormat::UnsignedInteger; 86 87 enum class PlanarConfig : uint16_t 88 { 89 Contiguous = 1, 90 Separate = 2, 91 } planarConfig = PlanarConfig::Contiguous; 92 93 enum class Photometric : uint16_t 94 { 95 MinIsWhite = 0, 96 MinIsBlack = 1, 97 RGB = 2, 98 Palette = 3, 99 TransparancyMask = 4, 100 Separated = 5, 101 YCBCR = 6, 102 CIELab = 8, 103 ICCLab = 9, 104 ITULab = 10, 105 ColorFilterArray = 32803, 106 CIELog2L = 32844, 107 CIELog2Luv = 32845, 108 } photometric = Photometric::MinIsWhite; 109 110 struct ColorMap 111 { 112 uint16_t* red; 113 uint16_t* green; 114 uint16_t* blue; 115 } colorMap = { 0 }; 116 117 const char* description = ""; 118 const char* name = ""; 119 const char* dateTime = ""; 120 121 DType PixelType() const; 122 }; 123 124 #ifdef USE_GEOTIFF 125 struct GeoKey 126 { 127 GeoKey() = default; 128 ~GeoKey(); 129 130 union 131 { 132 int8_t* b; 133 int16_t* i; 134 int32_t* l; 135 uint8_t* ub; 136 uint16_t* ui; 137 uint32_t* ul; 138 float* f; 139 double* d; 140 char* str; 141 void* ptr; 142 } value = { 0 }; 143 144 tagtype_t type = TYPE_UNKNOWN; 145 size_t count = 0; 146 }; 147 #endif 148 149 struct Rectangle 150 { 151 uint32_t x, y; 152 uint32_t w, h; 153 }; 154 155 class Handler 156 { 157 public: 158 Handler(); 159 ~Handler(); 160 161 bool Open(const char* file, const char* mode); 162 void Close(); 163 bool GetDirectory(tdir_t, Directory&) const; 164 uint16_t DirectoryCount() const; 165 uint16_t FileVersion() const; 166 BaseGDL* ReadImage(const Directory&, const Rectangle& = { 0 }); 167 168 template<typename... Ts> GetField(ttag_t tag,Ts &...vars) const169 bool GetField(ttag_t tag, Ts&... vars) const 170 { 171 return (tiff_ && TIFFGetField(tiff_, tag, &vars...)); 172 } 173 174 template<typename T> GetRequiredField(ttag_t tag,T & var) const175 void GetRequiredField(ttag_t tag, T& var) const 176 { 177 const TIFFField* field; 178 if(tiff_ && !TIFFGetField(tiff_, tag, &var)) { 179 if((field = TIFFFieldWithTag(tiff_, tag))) 180 throw TIFFFieldName(field); else throw tag; 181 } 182 } 183 184 #ifdef USE_GEOTIFF 185 BaseGDL* CreateGeoStructOrZero(tdir_t) const; 186 bool GetGeoKey(geokey_t, GeoKey&) const; 187 #endif 188 189 private: 190 ::TIFF* tiff_ = nullptr; 191 #ifdef USE_GEOTIFF 192 GTIF* gtif_ = nullptr; 193 #endif 194 TIFFErrorHandler defEH_ = nullptr; 195 TIFFErrorHandler defWH_ = nullptr; 196 uint16_t nDirs_ = 1; 197 uint16_t verNum_ = 0; 198 }; 199 } 200 201 BaseGDL* tiff_query(EnvT*); 202 BaseGDL* tiff_read(EnvT*); 203 } 204 205 #endif 206 207