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 0 : MMRBand(MMRBand &&) = default;
70 : MMRBand &operator=(const MMRBand &) =
71 : delete; // I don't want to assign a MMRBand to another MMRBand (effc++)
72 : ~MMRBand();
73 :
74 : const CPLString GetRELFileName() const;
75 : CPLErr GetRasterBlock(int nXBlock, int nYBlock, void *pData, int nDataSize);
76 :
77 : void UpdateGeoTransform();
78 :
79 468 : int GetAssignedSubDataSet() const
80 : {
81 468 : return m_nAssignedSDS;
82 : }
83 :
84 163 : void AssignSubDataSet(int nAssignedSDSIn)
85 : {
86 163 : m_nAssignedSDS = nAssignedSDSIn;
87 163 : }
88 :
89 41 : const CPLString &GetBandName() const
90 : {
91 41 : return m_osBandName;
92 : }
93 :
94 123 : const CPLString &GetBandSection() const
95 : {
96 123 : return m_osBandSection;
97 : }
98 :
99 41 : const CPLString &GetRawBandFileName() const
100 : {
101 41 : return m_osRawBandFileName;
102 : }
103 :
104 112 : const CPLString &GetFriendlyDescription() const
105 : {
106 112 : return m_osFriendlyDescription;
107 : }
108 :
109 194 : MMDataType GeteMMNCDataType() const
110 : {
111 : // Gets not compressed data type
112 194 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_BYTE_RLE)
113 49 : return MMDataType::DATATYPE_AND_COMPR_BYTE;
114 145 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_INTEGER_RLE)
115 80 : return MMDataType::DATATYPE_AND_COMPR_INTEGER;
116 65 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_UINTEGER_RLE)
117 0 : return MMDataType::DATATYPE_AND_COMPR_UINTEGER;
118 65 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_LONG_RLE)
119 0 : return MMDataType::DATATYPE_AND_COMPR_LONG;
120 65 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_REAL_RLE)
121 0 : return MMDataType::DATATYPE_AND_COMPR_REAL;
122 65 : if (m_eMMDataType == MMDataType::DATATYPE_AND_COMPR_DOUBLE_RLE)
123 0 : return MMDataType::DATATYPE_AND_COMPR_DOUBLE;
124 65 : return m_eMMDataType;
125 : }
126 :
127 61 : MMDataType GeteMMDataType() const
128 : {
129 61 : return m_eMMDataType;
130 : }
131 :
132 61 : MMBytesPerPixel GeteMMBytesPerPixel() const
133 : {
134 61 : return m_eMMBytesPerPixel;
135 : }
136 :
137 35 : bool GetMinSet() const
138 : {
139 35 : return m_bMinSet;
140 : }
141 :
142 34 : double GetMin() const
143 : {
144 34 : return m_dfMin;
145 : }
146 :
147 108 : bool GetMaxSet() const
148 : {
149 108 : return m_bMaxSet;
150 : }
151 :
152 88 : double GetMax() const
153 : {
154 88 : return m_dfMax;
155 : }
156 :
157 3 : bool GetVisuMinSet() const
158 : {
159 3 : return m_bMinVisuSet;
160 : }
161 :
162 1038 : double GetVisuMin() const
163 : {
164 1038 : return m_dfVisuMin;
165 : }
166 :
167 3 : bool GetVisuMaxSet() const
168 : {
169 3 : return m_bMaxVisuSet;
170 : }
171 :
172 12 : double GetVisuMax() const
173 : {
174 12 : return m_dfVisuMax;
175 : }
176 :
177 191 : double GetBoundingBoxMinX() const
178 : {
179 191 : return m_dfBBMinX;
180 : }
181 :
182 177 : double GetBoundingBoxMaxX() const
183 : {
184 177 : return m_dfBBMaxX;
185 : }
186 :
187 165 : double GetBoundingBoxMinY() const
188 : {
189 165 : return m_dfBBMinY;
190 : }
191 :
192 165 : double GetBoundingBoxMaxY() const
193 : {
194 165 : return m_dfBBMaxY;
195 : }
196 :
197 792 : bool BandHasNoData() const
198 : {
199 792 : return m_bNoDataSet;
200 : }
201 :
202 268 : double GetNoDataValue() const
203 : {
204 268 : return m_dfNoData;
205 : }
206 :
207 334 : int GetWidth() const
208 : {
209 334 : return m_nWidth;
210 : }
211 :
212 316 : int GetHeight() const
213 : {
214 316 : return m_nHeight;
215 : }
216 :
217 61 : int GetBlockXSize() const
218 : {
219 61 : return m_nBlockXSize;
220 : }
221 :
222 61 : int GetBlockYSize() const
223 : {
224 61 : return m_nBlockYSize;
225 : }
226 :
227 108 : bool IsValid() const
228 : {
229 108 : return m_bIsValid;
230 : }
231 :
232 166 : CPLString GetColor_Const() const
233 : {
234 166 : return m_osColor_Const;
235 : }
236 :
237 313 : GDALColorEntry GetConstantColorRGB() const
238 : {
239 313 : return m_sConstantColorRGB;
240 : }
241 :
242 1 : bool ValidConstantColorRGB() const
243 : {
244 1 : return m_osValidColorConst;
245 : }
246 :
247 244 : CPLString GetColor_Paleta() const
248 : {
249 244 : return m_osColor_Paleta;
250 : }
251 :
252 143 : CPLString GetColor_TractamentVariable() const
253 : {
254 143 : return m_osColor_TractamentVariable;
255 : }
256 :
257 52 : CPLString GetTractamentVariable() const
258 : {
259 52 : return m_osTractamentVariable;
260 : }
261 :
262 46 : CPLString GetColor_EscalatColor() const
263 : {
264 46 : return m_osColor_EscalatColor;
265 : }
266 :
267 82 : CPLString GetColor_N_SimbolsALaTaula() const
268 : {
269 82 : return m_osColor_N_SimbolsALaTaula;
270 : }
271 :
272 48 : CPLString GetShortRATName() const
273 : {
274 48 : return m_osShortRATName;
275 : }
276 :
277 9 : CPLString GetAssociateREL() const
278 : {
279 9 : return m_osAssociateREL;
280 : }
281 :
282 61 : CPLString GetUnits() const
283 : {
284 61 : return m_osBandUnitType;
285 : }
286 :
287 100 : bool IsCategorical() const
288 : {
289 100 : return m_bIsCategorical;
290 : }
291 :
292 : GDALGeoTransform m_gt{}; // Bounding box for this band
293 :
294 : private:
295 : bool Get_ATTRIBUTE_DATA_or_OVERVIEW_ASPECTES_TECNICS_int(
296 : const CPLString &osSection, const char *pszKey, int *nValue,
297 : const char *pszErrorMessage);
298 : static bool GetDataTypeAndBytesPerPixel(const char *pszCompType,
299 : MMDataType *nCompressionType,
300 : MMBytesPerPixel *nBytesPerPixel);
301 : bool UpdateDataTypeFromREL(const CPLString osSection);
302 : bool UpdateColumnsNumberFromREL(const CPLString &osSection);
303 : bool UpdateRowsNumberFromREL(const CPLString &osSection);
304 : void UpdateNoDataValue(const CPLString &osSection);
305 : void UpdateBoundingBoxFromREL(const CPLString &osSection);
306 : void UpdateSimbolizationInfo(const CPLString &osSection);
307 : void UpdateRATInfo(const CPLString &osSection);
308 : void UpdateReferenceSystemFromREL();
309 : void UpdateMinMaxValuesFromREL(const CPLString &osSection);
310 : void UpdateUnitTypeValueFromREL(const CPLString &osSection);
311 : void UpdateMinMaxVisuValuesFromREL(const CPLString &osSection);
312 : void UpdateFriendlyDescriptionFromREL(const CPLString &osSection);
313 :
314 : template <typename TYPE>
315 : CPLErr UncompressRow(void *rowBuffer, size_t nCompressedRawSize);
316 : CPLErr GetBlockData(void *rowBuffer, size_t nCompressedRawSize);
317 : int PositionAtStartOfRowOffsetsInFile();
318 : bool FillRowOffsets();
319 : vsi_l_offset GetFileSize();
320 :
321 : bool m_bIsValid =
322 : false; // Determines if the created object is valid or not.
323 :
324 : VSILFILE *m_pfIMG = nullptr; // Point to IMG file (RAW data)
325 : MMRRel *m_pfRel = nullptr; // Rel where metadata is read from
326 :
327 : int m_nBlockXSize = 1;
328 : int m_nBlockYSize = 1;
329 :
330 : int m_nWidth = 0; // Number of columns
331 : int m_nHeight = 0; // Number of rows
332 :
333 : int m_nNRowsPerBlock = 1;
334 :
335 : // indexed-RLE format
336 : std::vector<vsi_l_offset> m_aFileOffsets{};
337 : vsi_l_offset m_nFileSize = 0; /* 0=unknown */
338 :
339 : // Assigned Subdataset for this band.
340 : int m_nAssignedSDS = 0;
341 :
342 : // Section in REL file that give information about the band
343 : CPLString m_osBandSection;
344 : // File name relative to REL file with banda data
345 : CPLString m_osRawBandFileName = "";
346 : // Friendly osRawBandFileName
347 : CPLString m_osBandFileName = "";
348 : // Name of the band documented in REL metadata file.
349 : CPLString m_osBandName = "";
350 : // Descripcion of the band, not the name
351 : CPLString m_osFriendlyDescription = "";
352 :
353 : MMDataType m_eMMDataType =
354 : static_cast<MMDataType>(MMDataType::DATATYPE_AND_COMPR_UNDEFINED);
355 : MMBytesPerPixel m_eMMBytesPerPixel = static_cast<MMBytesPerPixel>(
356 : MMBytesPerPixel::TYPE_BYTES_PER_PIXEL_UNDEFINED);
357 : int m_nDataTypeSizeBytes = 0;
358 :
359 : bool m_bIsCompressed = false;
360 : bool m_bIsCategorical = false;
361 :
362 : CPLString m_osBandUnitType = "";
363 :
364 : // Min and Max values from metadata: This value should correspond
365 : // to the actual minimum and maximum, not to an approximation.
366 : // However, MiraMon is proof to approximate values. The minimum
367 : // and maximum values are useful, for example, to properly scale
368 : // colors, etc.
369 : bool m_bMinSet = false;
370 : double m_dfMin = 0.0;
371 : bool m_bMaxSet = false;
372 : double m_dfMax = 0.0;
373 : // These values will be dfMin/dfMax if they don't exist in REL file
374 : bool m_bMinVisuSet = false;
375 : double m_dfVisuMin = 0.0; // Key Color_ValorColor_0 in COLOR_TEXT
376 : bool m_bMaxVisuSet = false;
377 : double m_dfVisuMax = 0.0; // Key Color_ValorColor_n_1 COLOR_TEXT
378 :
379 : CPLString m_osRefSystem = "";
380 :
381 : // Extent values of the band:
382 : // They always refer to extreme outer coordinates,
383 : // not to cell centers.
384 :
385 : double m_dfBBMinX = 0.0;
386 : double m_dfBBMinY = 0.0;
387 : double m_dfBBMaxX = 0.0;
388 : double m_dfBBMaxY = 0.0;
389 :
390 : // Nodata stuff
391 : bool m_bNoDataSet = false; // There is nodata?
392 : double m_dfNoData = 0.0; // Value of nodata
393 :
394 : // Color table information
395 : CPLString m_osColor_Const = "";
396 : GDALColorEntry m_sConstantColorRGB = {0, 0, 0, 255};
397 : bool m_osValidColorConst = false;
398 : CPLString m_osColor_Paleta = "";
399 : CPLString m_osColor_TractamentVariable = "";
400 : CPLString m_osTractamentVariable = "";
401 : CPLString m_osColor_EscalatColor = "";
402 : CPLString m_osColor_N_SimbolsALaTaula = "";
403 :
404 : // Attribute table information
405 : // Table name
406 : CPLString m_osShortRATName = "";
407 : // Field in the table that is used as VALUE
408 : CPLString m_osAssociateREL = "";
409 : };
410 :
411 : #endif /* ndef MM_BAND_INCLUDED */
|