Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: MiraMonRaster driver
4 : * Purpose: Implements MMRBand class: This class manages the metadata of each
5 : * band to be processed. It is useful for maintaining a list of bands
6 : * and for determining the number of subdatasets that need to be
7 : * generated.
8 : * Author: Abel Pau
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 2025, Xavier Pons
12 : *
13 : * SPDX-License-Identifier: MIT
14 : ****************************************************************************/
15 :
16 : #ifndef MM_BAND_INCLUDED
17 : #define MM_BAND_INCLUDED
18 :
19 : #include <vector>
20 : #include <array>
21 :
22 : #include "miramon_rel.h"
23 : class MMRRel;
24 :
25 : /************************************************************************/
26 : /* MMRBand */
27 : /************************************************************************/
28 : enum class MMDataType
29 : {
30 : DATATYPE_AND_COMPR_UNDEFINED = -1,
31 : DATATYPE_AND_COMPR_MIN = 0,
32 : DATATYPE_AND_COMPR_STRING = 0,
33 : DATATYPE_AND_COMPR_BIT = 1,
34 : DATATYPE_AND_COMPR_BIT_VELL = 2, // Not supported
35 : DATATYPE_AND_COMPR_BYTE = 3,
36 : DATATYPE_AND_COMPR_INTEGER = 4,
37 : DATATYPE_AND_COMPR_UINTEGER = 5,
38 : DATATYPE_AND_COMPR_LONG = 6,
39 : DATATYPE_AND_COMPR_INTEGER_ASCII = 7,
40 : DATATYPE_AND_COMPR_REAL = 8,
41 : DATATYPE_AND_COMPR_DOUBLE = 9,
42 : DATATYPE_AND_COMPR_REAL_ASCII = 10,
43 : DATATYPE_AND_COMPR_BYTE_RLE = 11,
44 : DATATYPE_AND_COMPR_INTEGER_RLE = 12,
45 : DATATYPE_AND_COMPR_UINTEGER_RLE = 13,
46 : DATATYPE_AND_COMPR_LONG_RLE = 14,
47 : DATATYPE_AND_COMPR_REAL_RLE = 15,
48 : DATATYPE_AND_COMPR_DOUBLE_RLE = 16,
49 : DATATYPE_AND_COMPR_MAX = 16
50 : };
51 :
52 : enum class MMBytesPerPixel
53 : {
54 : TYPE_BYTES_PER_PIXEL_UNDEFINED = -1,
55 : TYPE_BYTES_PER_PIXEL_STRING = 0,
56 : TYPE_BYTES_PER_PIXEL_BIT = 0,
57 : TYPE_BYTES_PER_PIXEL_BYTE_I_RLE = 1,
58 : TYPE_BYTES_PER_PIXEL_INTEGER_I_RLE = 2,
59 : TYPE_BYTES_PER_PIXEL_LONG_REAL_I_RLE = 4,
60 : TYPE_BYTES_PER_PIXEL_DOUBLE_I_RLE = 8
61 : };
62 :
63 : class MMRBand final
64 : {
65 : public:
66 : MMRBand(MMRRel &pfRel, const CPLString &osSection);
67 : MMRBand(const MMRBand &) =
68 : delete; // I don't want to construct a MMRBand from another MMRBand (effc++)
69 : MMRBand &operator=(const MMRBand &) =
70 : delete; // I don't want to assign a MMRBand to another MMRBand (effc++)
71 : ~MMRBand();
72 :
73 : const CPLString GetRELFileName() const;
74 : CPLErr GetRasterBlock(int nXBlock, int nYBlock, void *pData, int nDataSize);
75 :
76 : void UpdateGeoTransform();
77 :
78 54 : int GetAssignedSubDataSet() const
79 : {
80 54 : return m_nAssignedSDS;
81 : }
82 :
83 144 : void AssignSubDataSet(int nAssignedSDSIn)
84 : {
85 144 : m_nAssignedSDS = nAssignedSDSIn;
86 144 : }
87 :
88 18 : const CPLString &GetBandName() const
89 : {
90 18 : return m_osBandName;
91 : }
92 :
93 63 : const CPLString &GetBandSection() const
94 : {
95 63 : return m_osBandSection;
96 : }
97 :
98 18 : const CPLString &GetRawBandFileName() const
99 : {
100 18 : return m_osRawBandFileName;
101 : }
102 :
103 116 : const CPLString &GetFriendlyDescription() const
104 : {
105 116 : return m_osFriendlyDescription;
106 : }
107 :
108 63 : MMDataType GeteMMDataType() const
109 : {
110 63 : return m_eMMDataType;
111 : }
112 :
113 63 : MMBytesPerPixel GeteMMBytesPerPixel() const
114 : {
115 63 : return m_eMMBytesPerPixel;
116 : }
117 :
118 35 : bool GetMinSet() const
119 : {
120 35 : return m_bMinSet;
121 : }
122 :
123 34 : double GetMin() const
124 : {
125 34 : return m_dfMin;
126 : }
127 :
128 35 : bool GetMaxSet() const
129 : {
130 35 : return m_bMaxSet;
131 : }
132 :
133 34 : double GetMax() const
134 : {
135 34 : return m_dfMax;
136 : }
137 :
138 5 : bool GetVisuMinSet() const
139 : {
140 5 : return m_bMinVisuSet;
141 : }
142 :
143 66576 : double GetVisuMin() const
144 : {
145 66576 : return m_dfVisuMin;
146 : }
147 :
148 5 : bool GetVisuMaxSet() const
149 : {
150 5 : return m_bMaxVisuSet;
151 : }
152 :
153 65549 : double GetVisuMax() const
154 : {
155 65549 : return m_dfVisuMax;
156 : }
157 :
158 87 : double GetBoundingBoxMinX() const
159 : {
160 87 : return m_dfBBMinX;
161 : }
162 :
163 87 : double GetBoundingBoxMaxX() const
164 : {
165 87 : return m_dfBBMaxX;
166 : }
167 :
168 87 : double GetBoundingBoxMinY() const
169 : {
170 87 : return m_dfBBMinY;
171 : }
172 :
173 87 : double GetBoundingBoxMaxY() const
174 : {
175 87 : return m_dfBBMaxY;
176 : }
177 :
178 66348 : bool BandHasNoData() const
179 : {
180 66348 : return m_bNoDataSet;
181 : }
182 :
183 278 : double GetNoDataValue() const
184 : {
185 278 : return m_dfNoData;
186 : }
187 :
188 150 : int GetWidth() const
189 : {
190 150 : return m_nWidth;
191 : }
192 :
193 150 : int GetHeight() const
194 : {
195 150 : return m_nHeight;
196 : }
197 :
198 63 : int GetBlockXSize() const
199 : {
200 63 : return m_nBlockXSize;
201 : }
202 :
203 63 : int GetBlockYSize() const
204 : {
205 63 : return m_nBlockYSize;
206 : }
207 :
208 87 : bool IsValid() const
209 : {
210 87 : return m_bIsValid;
211 : }
212 :
213 : GDALGeoTransform m_gt{}; // Bounding box for this band
214 :
215 : private:
216 : bool Get_ATTRIBUTE_DATA_or_OVERVIEW_ASPECTES_TECNICS_int(
217 : const CPLString &osSection, const char *pszKey, int *nValue,
218 : const char *pszErrorMessage);
219 : static bool GetDataTypeAndBytesPerPixel(const char *pszCompType,
220 : MMDataType *nCompressionType,
221 : MMBytesPerPixel *nBytesPerPixel);
222 : bool UpdateDataTypeFromREL(const CPLString osSection);
223 : bool UpdateColumnsNumberFromREL(const CPLString &osSection);
224 : bool UpdateRowsNumberFromREL(const CPLString &osSection);
225 : void UpdateNoDataValue(const CPLString &osSection);
226 : void UpdateBoundingBoxFromREL(const CPLString &osSection);
227 : void UpdateReferenceSystemFromREL();
228 : void UpdateMinMaxValuesFromREL(const CPLString &osSection);
229 : void UpdateMinMaxVisuValuesFromREL(const CPLString &osSection);
230 : void UpdateFriendlyDescriptionFromREL(const CPLString &osSection);
231 :
232 : template <typename TYPE>
233 : CPLErr UncompressRow(void *rowBuffer, size_t nCompressedRawSize);
234 : CPLErr GetBlockData(void *rowBuffer, size_t nCompressedRawSize);
235 : int PositionAtStartOfRowOffsetsInFile();
236 : bool FillRowOffsets();
237 : vsi_l_offset GetFileSize();
238 :
239 : bool m_bIsValid =
240 : false; // Determines if the created object is valid or not.
241 :
242 : VSILFILE *m_pfIMG = nullptr; // Point to IMG file (RAW data)
243 : MMRRel *m_pfRel = nullptr; // Rel where metadata is read from
244 :
245 : int m_nBlockXSize = 1;
246 : int m_nBlockYSize = 1;
247 :
248 : int m_nWidth = 0; // Number of columns
249 : int m_nHeight = 0; // Number of rows
250 :
251 : int m_nNRowsPerBlock = 1;
252 :
253 : // indexed-RLE format
254 : std::vector<vsi_l_offset> m_aFileOffsets{};
255 : vsi_l_offset m_nFileSize = 0; /* 0=unknown */
256 :
257 : // Assigned Subdataset for this band.
258 : int m_nAssignedSDS = 0;
259 :
260 : // Section in REL file that give information about the band
261 : CPLString m_osBandSection;
262 : // File name relative to REL file with banda data
263 : CPLString m_osRawBandFileName = "";
264 : // Friendly osRawBandFileName
265 : CPLString m_osBandFileName = "";
266 : // Name of the band documented in REL metadata file.
267 : CPLString m_osBandName = "";
268 : // Descripcion of the band, not the name
269 : CPLString m_osFriendlyDescription = "";
270 :
271 : MMDataType m_eMMDataType =
272 : static_cast<MMDataType>(MMDataType::DATATYPE_AND_COMPR_UNDEFINED);
273 : MMBytesPerPixel m_eMMBytesPerPixel = static_cast<MMBytesPerPixel>(
274 : MMBytesPerPixel::TYPE_BYTES_PER_PIXEL_UNDEFINED);
275 : int m_nDataTypeSizeBytes = 0;
276 :
277 : bool m_bIsCompressed = false;
278 :
279 : // Min and Max values from metadata: This value should correspond
280 : // to the actual minimum and maximum, not to an approximation.
281 : // However, MiraMon is proof to approximate values. The minimum
282 : // and maximum values are useful, for example, to properly scale
283 : // colors, etc.
284 : bool m_bMinSet = false;
285 : double m_dfMin = 0.0;
286 : bool m_bMaxSet = false;
287 : double m_dfMax = 0.0;
288 : // These values will be dfMin/dfMax if they don't exist in REL file
289 : bool m_bMinVisuSet = false;
290 : double m_dfVisuMin = 0.0; // Key Color_ValorColor_0 in COLOR_TEXT
291 : bool m_bMaxVisuSet = false;
292 : double m_dfVisuMax = 0.0; // Key Color_ValorColor_n_1 COLOR_TEXT
293 :
294 : CPLString m_osRefSystem = "";
295 :
296 : // Extent values of the band:
297 : // They always refer to extreme outer coordinates,
298 : // not to cell centers.
299 :
300 : double m_dfBBMinX = 0.0;
301 : double m_dfBBMinY = 0.0;
302 : double m_dfBBMaxX = 0.0;
303 : double m_dfBBMaxY = 0.0;
304 :
305 : // Nodata stuff
306 : bool m_bNoDataSet = false; // There is nodata?
307 : double m_dfNoData = 0.0; // Value of nodata
308 : };
309 :
310 : #endif /* ndef MM_BAND_INCLUDED */
|