TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
6 / 6
100.0%
Branches:
2 / 2
100.0%
Functions:
3 / 3
100.0%

raster/geotiff/tiff_format.h
Line Branch Exec Source
1 /// @file
2 /// @brief TIFF and GeoTIFF numbers shared by the GeoTIFF reader and writer.
3 #pragma once
4
5 #include "terraingen/raster/geo_transform.h"
6 #include "terraingen/raster/geotiff/geotiff.h"
7
8 #include <bit>
9 #include <cstddef>
10 #include <cstdint>
11 #include <optional>
12 #include <vector>
13
14 namespace terraingen::detail {
15
16 static_assert(std::endian::native == std::endian::little,
17 "The GeoTIFF reader and writer assume a little-endian host");
18
19 /// TIFF tags read or written.
20 enum Tag : std::uint16_t {
21 kImageWidth = 256,
22 kImageLength = 257,
23 kBitsPerSample = 258,
24 kCompression = 259,
25 kPhotometric = 262,
26 kStripOffsets = 273,
27 kSamplesPerPixel = 277,
28 kRowsPerStrip = 278,
29 kStripByteCounts = 279,
30 kPlanarConfiguration = 284,
31 kPredictor = 317,
32 kTileWidth = 322,
33 kTileLength = 323,
34 kTileOffsets = 324,
35 kTileByteCounts = 325,
36 kExtraSamples = 338,
37 kSampleFormat = 339,
38 kModelPixelScale = 33550,
39 kModelTiepoint = 33922,
40 kModelTransformation = 34264,
41 kGeoKeyDirectory = 34735,
42 kGeoDoubleParams = 34736,
43 kGeoAsciiParams = 34737,
44 kGdalMetadata = 42112,
45 kGdalNoData = 42113,
46 };
47
48 /// TIFF field types.
49 enum FieldType : std::uint16_t {
50 kByte = 1,
51 kAscii = 2,
52 kShort = 3,
53 kLong = 4,
54 kRational = 5,
55 kSByte = 6,
56 kUndefined = 7,
57 kSShort = 8,
58 kSLong = 9,
59 kSRational = 10,
60 kFloat = 11,
61 kDouble = 12,
62 kLong8 = 16,
63 kSLong8 = 17,
64 kIfd8 = 18,
65 };
66
67 /// Values of the Compression tag.
68 enum CompressionCode : std::uint16_t {
69 kCompressionNone = 1,
70 kCompressionLzw = 5,
71 kCompressionDeflate = 8,
72 kCompressionAdobeDeflate = 32946,
73 kCompressionPackBits = 32773,
74 };
75
76 /// GeoKey numbers from OGC 19-008r4.
77 enum GeoKey : std::uint16_t {
78 kGtModelTypeGeoKey = 1024,
79 kGtRasterTypeGeoKey = 1025,
80 kGeographicTypeGeoKey = 2048,
81 kGeogGeodeticDatumGeoKey = 2050,
82 kGeogAngularUnitsGeoKey = 2054,
83 kGeogEllipsoidGeoKey = 2056,
84 kGeogSemiMajorAxisGeoKey = 2057,
85 kGeogSemiMinorAxisGeoKey = 2058,
86 };
87
88 constexpr std::uint16_t kModelTypeGeographic = 2; ///< GTModelTypeGeoKey value.
89 constexpr std::uint16_t kRasterPixelIsArea = 1; ///< GTRasterTypeGeoKey value.
90 constexpr std::uint16_t kRasterPixelIsPoint = 2; ///< GTRasterTypeGeoKey value.
91 constexpr std::uint16_t kUserDefined = 32767; ///< A user-defined CRS, datum or ellipsoid.
92 constexpr std::uint16_t kAngularDegree = 9102; ///< GeogAngularUnitsGeoKey value.
93
94 /// The size in bytes of one value of a TIFF field type code, or 0 for an unknown type.
95 std::size_t FieldSize(std::uint16_t type);
96
97 /// The compression a Compression tag value names, or nothing for a scheme this library does not
98 /// decode.
99 std::optional<TiffCompression> CompressionFromCode(std::uint64_t code);
100
101 /// The Compression tag value written for `compression`; Deflate is written as code 8.
102 std::uint16_t CompressionCodeOf(TiffCompression compression);
103
104 /// The sizes of IFD fields in classic TIFF or BigTIFF.
105 struct IfdFormat {
106 std::size_t countSize; ///< Size of the entry count before the entries.
107 std::size_t wordSize; ///< Size of a value count, an inline value and an offset.
108
109 /// The format of classic TIFF (`bigTiff` false) or BigTIFF.
110 862 static constexpr IfdFormat For(bool bigTiff) {
111
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 847 times.
862 return bigTiff ? IfdFormat{8, 8} : IfdFormat{2, 4};
112 }
113
114 /// The size in bytes of one entry: tag, type, count and value or offset.
115 9467 constexpr std::size_t EntrySize() const {
116 9467 return 4 + 2 * wordSize;
117 }
118
119 /// The byte offset within an entry where its value or offset starts.
120 8912 constexpr std::size_t ValueAt() const {
121 8912 return 4 + wordSize;
122 }
123 };
124
125 /// One IFD entry with its value bytes, already read from wherever they are stored.
126 struct Entry {
127 std::uint16_t type = 0; ///< Field type (`FieldType`).
128 std::uint64_t count = 0; ///< Number of values.
129 std::vector<std::uint8_t> bytes; ///< The values, in the file's byte order.
130 };
131
132 /// `transform` shifted by half a pixel along both pixel axes.
133 /// @param sign +1 to shift forward, -1 back.
134 GeoTransform ShiftHalfPixel(const GeoTransform& transform, double sign);
135
136 } // namespace terraingen::detail
137