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