Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: MiraMonRaster driver
4 : * Purpose: Implements MMRPalettes class: handles access to a DBF file
5 : * containing color information, which is then converted into
6 : * either a color table or an attribute table, depending on the
7 : * context.
8 : * Author: Abel Pau
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 2025, Xavier Pons
12 : *
13 : * SPDX-License-Identifier: MIT
14 : ****************************************************************************/
15 :
16 : #include "miramon_rel.h"
17 : #include "miramon_palettes.h"
18 :
19 : #include "../miramon_common/mm_gdal_functions.h" // For MMCheck_REL_FILE()
20 :
21 64 : MMRPalettes::MMRPalettes(MMRRel &fRel, const CPLString &osBandSectionIn)
22 64 : : m_pfRel(&fRel), m_osBandSection(osBandSectionIn)
23 : {
24 : // Is the palette a constant color? Then, which color is it?
25 64 : CPLString os_Color_Const;
26 64 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
27 97 : "Color_Const", os_Color_Const) &&
28 33 : EQUAL(os_Color_Const, "1"))
29 : {
30 2 : m_bIsConstantColor = true;
31 2 : if (CE_None != UpdateConstantColor())
32 0 : return; // The constant color indicated is wrong
33 2 : m_nRealNPaletteColors = 1;
34 2 : m_bIsValid = true;
35 2 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
36 2 : SetIsCategorical(true);
37 2 : return;
38 : }
39 :
40 : // Is this an authomatic palette or has a color table (dbf, pal,...)?
41 62 : CPLString os_Color_Paleta = "";
42 : ;
43 62 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
44 : "Color_Paleta", os_Color_Paleta))
45 : {
46 59 : if (EQUAL(os_Color_Paleta, "<Automatic>"))
47 32 : m_bIsAutomatic = true;
48 : }
49 :
50 : // Treatment of the color variable
51 62 : CPLString os_Color_TractamentVariable;
52 62 : if (!m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
53 : "Color_TractamentVariable",
54 93 : os_Color_TractamentVariable) ||
55 31 : os_Color_TractamentVariable.empty())
56 : {
57 62 : CPLString os_TractamentVariable;
58 31 : if (!m_pfRel->GetMetadataValue(SECTION_ATTRIBUTE_DATA,
59 : "TractamentVariable",
60 : os_TractamentVariable))
61 5 : os_TractamentVariable = "";
62 :
63 31 : if (EQUAL(os_TractamentVariable, "Categoric"))
64 26 : SetIsCategorical(true);
65 : else
66 5 : SetIsCategorical(false);
67 : }
68 : else
69 : {
70 31 : if (EQUAL(os_Color_TractamentVariable, "Categoric"))
71 26 : SetIsCategorical(true);
72 : else
73 5 : SetIsCategorical(false);
74 : }
75 :
76 62 : if (UpdateColorInfo() == CE_Failure)
77 0 : return;
78 :
79 62 : if (m_bIsAutomatic)
80 : {
81 : // How many "colors" are involved?
82 64 : CPLString os_Color_N_SimbolsALaTaula = "";
83 32 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
84 : "Color_N_SimbolsALaTaula",
85 : os_Color_N_SimbolsALaTaula))
86 : {
87 0 : GIntBig nBigVal = CPLAtoGIntBig(os_Color_N_SimbolsALaTaula);
88 0 : if (nBigVal >= INT_MAX)
89 0 : return;
90 0 : m_nRealNPaletteColors = m_nNPaletteColors =
91 : static_cast<int>(nBigVal);
92 0 : if (m_nNPaletteColors <= 0 || m_nNPaletteColors >= 256)
93 : {
94 0 : CPLError(CE_Failure, CPLE_AssertionFailed,
95 : "Invalid number of colors "
96 : "(Color_N_SimbolsALaTaula) in \"%s\".",
97 0 : m_pfRel->GetRELName().c_str());
98 0 : return;
99 : }
100 : }
101 : else
102 : {
103 32 : if (IsCategorical())
104 : {
105 : // Predefined color table: m_ThematicPalette
106 32 : if (CE_None != GetPaletteColors_Automatic())
107 0 : return;
108 : }
109 : else // No palette associated
110 0 : return;
111 : }
112 32 : m_bIsValid = true;
113 32 : return;
114 : }
115 :
116 : // If color is no automatic, from where we got this?
117 30 : CPLString osExtension = CPLGetExtensionSafe(os_Color_Paleta);
118 30 : if (osExtension.tolower() == "dbf")
119 : {
120 24 : if (CE_None != GetPaletteColors_DBF(os_Color_Paleta))
121 3 : return;
122 :
123 21 : m_bIsValid = true;
124 : }
125 10 : else if (osExtension.tolower() == "pal" || osExtension.tolower() == "p25" ||
126 4 : osExtension.tolower() == "p65")
127 : {
128 3 : if (CE_None != GetPaletteColors_PAL_P25_P65(os_Color_Paleta))
129 0 : return;
130 :
131 3 : m_bIsValid = true;
132 : }
133 : else
134 3 : return;
135 :
136 24 : m_nRealNPaletteColors = m_nNPaletteColors;
137 24 : if (HasNodata())
138 : {
139 6 : if (m_nNPaletteColors < 1)
140 0 : return;
141 6 : m_nNPaletteColors--;
142 : }
143 : else
144 : {
145 : // If palette doesn't have nodata let's set some index
146 18 : m_nNoDataPaletteIndex = m_nRealNPaletteColors;
147 : }
148 : }
149 :
150 64 : MMRPalettes::~MMRPalettes()
151 : {
152 64 : }
153 :
154 1213 : void MMRPalettes::AssignColorFromDBF(struct MM_DATA_BASE_XP &oColorTable,
155 : char *pzsRecord, char *pszField,
156 : MM_EXT_DBF_N_FIELDS &nRIndex,
157 : MM_EXT_DBF_N_FIELDS &nGIndex,
158 : MM_EXT_DBF_N_FIELDS &nBIndex,
159 : int nIPaletteIndex)
160 : {
161 : // RED
162 1213 : memcpy(pszField, pzsRecord + oColorTable.pField[nRIndex].AccumulatedBytes,
163 1213 : oColorTable.pField[nRIndex].BytesPerField);
164 1213 : pszField[oColorTable.pField[nRIndex].BytesPerField] = '\0';
165 1213 : m_aadfPaletteColors[0][nIPaletteIndex] = CPLAtof(pszField);
166 :
167 : // GREEN
168 1213 : memcpy(pszField, pzsRecord + oColorTable.pField[nGIndex].AccumulatedBytes,
169 1213 : oColorTable.pField[nGIndex].BytesPerField);
170 1213 : pszField[oColorTable.pField[nGIndex].BytesPerField] = '\0';
171 1213 : m_aadfPaletteColors[1][nIPaletteIndex] = CPLAtof(pszField);
172 :
173 : // BLUE
174 1213 : memcpy(pszField, pzsRecord + oColorTable.pField[nBIndex].AccumulatedBytes,
175 1213 : oColorTable.pField[nBIndex].BytesPerField);
176 1213 : pszField[oColorTable.pField[nBIndex].BytesPerField] = '\0';
177 1213 : m_aadfPaletteColors[2][nIPaletteIndex] = CPLAtof(pszField);
178 :
179 : // ALPHA
180 1213 : if (m_aadfPaletteColors[0][nIPaletteIndex] == -1 &&
181 1218 : m_aadfPaletteColors[1][nIPaletteIndex] == -1 &&
182 5 : m_aadfPaletteColors[2][nIPaletteIndex] == -1)
183 : {
184 : // Transparent (white or whatever color)
185 5 : m_aadfPaletteColors[0][nIPaletteIndex] = m_sNoDataColorRGB.c1;
186 5 : m_aadfPaletteColors[1][nIPaletteIndex] = m_sNoDataColorRGB.c2;
187 5 : m_aadfPaletteColors[2][nIPaletteIndex] = m_sNoDataColorRGB.c3;
188 5 : m_aadfPaletteColors[3][nIPaletteIndex] = m_sNoDataColorRGB.c4;
189 : }
190 : else
191 1208 : m_aadfPaletteColors[3][nIPaletteIndex] = 255;
192 1213 : }
193 :
194 23 : CPLErr MMRPalettes::GetPaletteColors_DBF_Indexes(
195 : struct MM_DATA_BASE_XP &oColorTable, MM_EXT_DBF_N_FIELDS &nClauSimbol,
196 : MM_EXT_DBF_N_FIELDS &nRIndex, MM_EXT_DBF_N_FIELDS &nGIndex,
197 : MM_EXT_DBF_N_FIELDS &nBIndex)
198 : {
199 23 : nClauSimbol = oColorTable.nFields;
200 23 : nRIndex = oColorTable.nFields;
201 23 : nGIndex = oColorTable.nFields;
202 23 : nBIndex = oColorTable.nFields;
203 :
204 121 : for (MM_EXT_DBF_N_FIELDS nIField = 0; nIField < oColorTable.nFields;
205 : nIField++)
206 : {
207 98 : if (EQUAL(oColorTable.pField[nIField].FieldName, "CLAUSIMBOL"))
208 22 : nClauSimbol = nIField;
209 76 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "R_COLOR"))
210 23 : nRIndex = nIField;
211 53 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "G_COLOR"))
212 23 : nGIndex = nIField;
213 30 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "B_COLOR"))
214 23 : nBIndex = nIField;
215 : }
216 :
217 23 : if (nClauSimbol == oColorTable.nFields || nRIndex == oColorTable.nFields ||
218 22 : nGIndex == oColorTable.nFields || nBIndex == oColorTable.nFields)
219 1 : return CE_Failure;
220 :
221 22 : return CE_None;
222 : }
223 :
224 : // Colors in a PAL, P25 or P65 format files
225 : // Updates nNPaletteColors
226 32 : CPLErr MMRPalettes::GetPaletteColors_Automatic()
227 : {
228 32 : m_nRealNPaletteColors = m_nNPaletteColors =
229 32 : static_cast<int>(m_ThematicPalette.size());
230 :
231 160 : for (int iColumn = 0; iColumn < 4; iColumn++)
232 : {
233 : try
234 : {
235 128 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
236 : }
237 0 : catch (std::bad_alloc &e)
238 : {
239 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
240 0 : return CE_Failure;
241 : }
242 : }
243 :
244 8224 : for (int nIndex = 0; nIndex < m_nRealNPaletteColors; nIndex++)
245 : {
246 : // Index of the color
247 :
248 : // RED
249 8192 : m_aadfPaletteColors[0][nIndex] = m_ThematicPalette[nIndex].c1;
250 :
251 : // GREEN
252 8192 : m_aadfPaletteColors[1][nIndex] = m_ThematicPalette[nIndex].c2;
253 :
254 : // BLUE
255 8192 : m_aadfPaletteColors[2][nIndex] = m_ThematicPalette[nIndex].c3;
256 :
257 : // ALPHA
258 8192 : m_aadfPaletteColors[3][nIndex] = m_ThematicPalette[nIndex].c4;
259 : }
260 :
261 32 : return CE_None;
262 : }
263 :
264 : // Updates nNPaletteColors
265 24 : CPLErr MMRPalettes::GetPaletteColors_DBF(const CPLString &os_Color_Paleta_DBF)
266 :
267 : {
268 : // Getting the full path name of the DBF
269 48 : CPLString osAux = CPLGetPathSafe(m_pfRel->GetRELNameChar());
270 : CPLString osColorTableFileName =
271 48 : CPLFormFilenameSafe(osAux.c_str(), os_Color_Paleta_DBF.c_str(), "");
272 :
273 : // Reading the DBF file
274 : struct MM_DATA_BASE_XP oColorTable;
275 24 : memset(&oColorTable, 0, sizeof(oColorTable));
276 :
277 24 : if (MM_ReadExtendedDBFHeaderFromFile(osColorTableFileName.c_str(),
278 : &oColorTable,
279 48 : m_pfRel->GetRELNameChar()))
280 : {
281 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
282 : "Invalid color table:"
283 : "\"%s\".",
284 : osColorTableFileName.c_str());
285 :
286 1 : return CE_Failure;
287 : }
288 :
289 : // Getting indices of fields that determine the colors.
290 : MM_EXT_DBF_N_FIELDS nClauSimbol, nRIndex, nGIndex, nBIndex;
291 23 : if (CE_Failure == GetPaletteColors_DBF_Indexes(oColorTable, nClauSimbol,
292 : nRIndex, nGIndex, nBIndex))
293 : {
294 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
295 : "Invalid color table:"
296 : "\"%s\".",
297 : osColorTableFileName.c_str());
298 :
299 1 : VSIFCloseL(oColorTable.pfDataBase);
300 1 : MM_ReleaseMainFields(&oColorTable);
301 1 : return CE_Failure;
302 : }
303 :
304 : // Checking the structure to be correct
305 22 : if (oColorTable.pField[nClauSimbol].BytesPerField == 0 ||
306 22 : oColorTable.pField[nRIndex].BytesPerField == 0 ||
307 22 : oColorTable.pField[nGIndex].BytesPerField == 0 ||
308 22 : oColorTable.pField[nBIndex].BytesPerField == 0 ||
309 22 : oColorTable.pField[nClauSimbol].FieldType != 'N' ||
310 21 : oColorTable.pField[nRIndex].FieldType != 'N' ||
311 21 : oColorTable.pField[nGIndex].FieldType != 'N' ||
312 21 : oColorTable.pField[nBIndex].FieldType != 'N')
313 : {
314 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
315 : "Invalid color table:"
316 : "\"%s\".",
317 : osColorTableFileName.c_str());
318 :
319 1 : VSIFCloseL(oColorTable.pfDataBase);
320 1 : MM_ReleaseMainFields(&oColorTable);
321 1 : return CE_Failure;
322 : }
323 :
324 : // Guessing or reading the number of colors of the palette.
325 21 : MM_ACCUMULATED_BYTES_TYPE_DBF nBufferSize = oColorTable.BytesPerRecord + 1;
326 21 : char *pzsRecord = static_cast<char *>(VSI_CALLOC_VERBOSE(1, nBufferSize));
327 21 : if (!pzsRecord)
328 : {
329 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
330 : "Out of memory allocating working buffer");
331 0 : VSIFCloseL(oColorTable.pfDataBase);
332 0 : MM_ReleaseMainFields(&oColorTable);
333 : }
334 21 : char *pszField = static_cast<char *>(VSI_CALLOC_VERBOSE(1, nBufferSize));
335 :
336 21 : if (!pszField)
337 : {
338 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
339 : "Out of memory allocating working buffer");
340 0 : VSIFree(pzsRecord);
341 0 : VSIFCloseL(oColorTable.pfDataBase);
342 0 : MM_ReleaseMainFields(&oColorTable);
343 : }
344 :
345 21 : m_nNPaletteColors = static_cast<int>(oColorTable.nRecords); // Safe cast
346 :
347 : // Checking the size of the palette.
348 21 : if (m_nNPaletteColors < 0 || m_nNPaletteColors > 65536)
349 : {
350 0 : m_nNPaletteColors = 0;
351 0 : CPLError(CE_Failure, CPLE_AppDefined,
352 : "Invalid number of colors: %d "
353 : "in color table \"%s\".",
354 : m_nNPaletteColors, osColorTableFileName.c_str());
355 :
356 0 : VSIFree(pszField);
357 0 : VSIFree(pzsRecord);
358 0 : VSIFCloseL(oColorTable.pfDataBase);
359 0 : MM_ReleaseMainFields(&oColorTable);
360 0 : return CE_Failure;
361 : }
362 :
363 : // Getting the memory to allocate the color values
364 105 : for (int iColumn = 0; iColumn < 4; iColumn++)
365 : {
366 : try
367 : {
368 84 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
369 : }
370 0 : catch (std::bad_alloc &e)
371 : {
372 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
373 0 : VSIFree(pszField);
374 0 : VSIFree(pzsRecord);
375 0 : VSIFCloseL(oColorTable.pfDataBase);
376 0 : MM_ReleaseMainFields(&oColorTable);
377 0 : return CE_Failure;
378 : }
379 : }
380 :
381 21 : VSIFSeekL(oColorTable.pfDataBase, oColorTable.FirstRecordOffset, SEEK_SET);
382 : /*
383 : Each record's CLAUSIMBOL field doesn't match a pixel value present in the raster,
384 : and it's used only for discovering nodata value (blanc value).
385 : The list of values is used to map every value in a color using:
386 : - Direct assignation: mode used in categorical modes but possible in continuous.
387 : - Linear scaling
388 : - Logarithmic scaling
389 : */
390 1234 : for (int nIPaletteColors = 0; nIPaletteColors < m_nNPaletteColors;
391 : nIPaletteColors++)
392 : {
393 2426 : if (oColorTable.BytesPerRecord !=
394 1213 : VSIFReadL(pzsRecord, sizeof(unsigned char),
395 1213 : oColorTable.BytesPerRecord, oColorTable.pfDataBase))
396 : {
397 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
398 : osColorTableFileName.c_str());
399 0 : VSIFree(pszField);
400 0 : VSIFree(pzsRecord);
401 0 : VSIFCloseL(oColorTable.pfDataBase);
402 0 : MM_ReleaseMainFields(&oColorTable);
403 0 : return CE_Failure;
404 : }
405 :
406 : // Nodata identification
407 1213 : memcpy(pszField,
408 1213 : pzsRecord + oColorTable.pField[nClauSimbol].AccumulatedBytes,
409 1213 : oColorTable.pField[nClauSimbol].BytesPerField);
410 1213 : pszField[oColorTable.pField[nClauSimbol].BytesPerField] = '\0';
411 2426 : CPLString osField = pszField;
412 1213 : osField.replaceAll(" ", "");
413 1213 : if (osField.empty()) // Nodata value
414 : {
415 6 : m_bHasNodata = true;
416 6 : m_nNoDataPaletteIndex = nIPaletteColors;
417 : }
418 :
419 1213 : AssignColorFromDBF(oColorTable, pzsRecord, pszField, nRIndex, nGIndex,
420 : nBIndex, nIPaletteColors);
421 : }
422 :
423 21 : VSIFree(pszField);
424 21 : VSIFree(pzsRecord);
425 21 : VSIFCloseL(oColorTable.pfDataBase);
426 21 : MM_ReleaseMainFields(&oColorTable);
427 :
428 21 : return CE_None;
429 : }
430 :
431 : // Colors in a PAL, P25 or P65 format files
432 : // Updates nNPaletteColors
433 : CPLErr
434 3 : MMRPalettes::GetPaletteColors_PAL_P25_P65(const CPLString &os_Color_Paleta_DBF)
435 :
436 : {
437 6 : CPLString osAux = CPLGetPathSafe(m_pfRel->GetRELNameChar());
438 : CPLString osColorTableFileName =
439 6 : CPLFormFilenameSafe(osAux.c_str(), os_Color_Paleta_DBF.c_str(), "");
440 :
441 : // This kind of palette has not NoData color.
442 : //bHasNodata = false;
443 :
444 6 : CPLString osExtension = CPLGetExtensionSafe(os_Color_Paleta_DBF);
445 3 : int nNReadPaletteColors = 0;
446 3 : m_nNPaletteColors = 0;
447 :
448 3 : if (osExtension.tolower() == "pal")
449 1 : m_nNPaletteColors = 64;
450 2 : else if (osExtension.tolower() == "p25")
451 1 : m_nNPaletteColors = 256;
452 1 : else if (osExtension.tolower() == "p65")
453 1 : m_nNPaletteColors = 65536;
454 : else
455 0 : return CE_None;
456 :
457 15 : for (int iColumn = 0; iColumn < 4; iColumn++)
458 : {
459 : try
460 : {
461 12 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
462 : }
463 0 : catch (std::bad_alloc &e)
464 : {
465 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
466 0 : return CE_Failure;
467 : }
468 : }
469 :
470 3 : VSILFILE *fpColorTable = VSIFOpenL(osColorTableFileName, "rt");
471 3 : if (!fpColorTable)
472 : {
473 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
474 : osColorTableFileName.c_str());
475 0 : return CE_Failure;
476 : }
477 :
478 3 : nNReadPaletteColors = 0;
479 : const char *pszLine;
480 51 : while ((pszLine = CPLReadLineL(fpColorTable)) != nullptr)
481 : {
482 : // Ignore empty lines
483 48 : if (pszLine[0] == '\0')
484 0 : continue;
485 :
486 48 : const CPLStringList aosTokens(CSLTokenizeString2(pszLine, " \t", 0));
487 48 : if (aosTokens.size() != 4)
488 : {
489 0 : VSIFCloseL(fpColorTable);
490 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
491 : osColorTableFileName.c_str());
492 0 : return CE_Failure;
493 : }
494 :
495 : // Index of the color
496 : // papszTokens[0] is ignored;
497 :
498 : // RED
499 48 : m_aadfPaletteColors[0][nNReadPaletteColors] = CPLAtof(aosTokens[1]);
500 :
501 : // GREEN
502 48 : m_aadfPaletteColors[1][nNReadPaletteColors] = CPLAtof(aosTokens[2]);
503 :
504 : // BLUE
505 48 : m_aadfPaletteColors[2][nNReadPaletteColors] = CPLAtof(aosTokens[3]);
506 :
507 : // ALPHA
508 48 : m_aadfPaletteColors[3][nNReadPaletteColors] = 255.0;
509 48 : nNReadPaletteColors++;
510 : }
511 :
512 : // Filling the rest of colors.
513 3 : for (int nIColorIndex = nNReadPaletteColors;
514 65811 : nIColorIndex < m_nNPaletteColors; nIColorIndex++)
515 : {
516 65808 : m_aadfPaletteColors[0][nNReadPaletteColors] = m_sDefaultColorRGB.c1;
517 65808 : m_aadfPaletteColors[1][nNReadPaletteColors] = m_sDefaultColorRGB.c2;
518 65808 : m_aadfPaletteColors[2][nNReadPaletteColors] = m_sDefaultColorRGB.c3;
519 65808 : m_aadfPaletteColors[3][nNReadPaletteColors] = m_sDefaultColorRGB.c4;
520 65808 : nNReadPaletteColors++;
521 : }
522 :
523 3 : if (nNReadPaletteColors != m_nNPaletteColors)
524 : {
525 0 : VSIFCloseL(fpColorTable);
526 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
527 : osColorTableFileName.c_str());
528 0 : return CE_Failure;
529 : }
530 :
531 3 : VSIFCloseL(fpColorTable);
532 :
533 3 : return CE_None;
534 : }
535 :
536 62 : CPLErr MMRPalettes::UpdateColorInfo()
537 : {
538 124 : CPLString os_Color_EscalatColor;
539 62 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
540 : "Color_EscalatColor",
541 67 : os_Color_EscalatColor) &&
542 5 : !os_Color_EscalatColor.empty())
543 : {
544 5 : if (os_Color_EscalatColor.compare("AssigDirecta") == 0)
545 2 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
546 3 : else if (os_Color_EscalatColor.compare("DespOrigen") == 0)
547 0 : m_ColorScaling = ColorTreatment::ORIGIN_DISPLACEMENT;
548 3 : else if (os_Color_EscalatColor.compare("lineal") == 0)
549 3 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
550 0 : else if (os_Color_EscalatColor.compare("log_10") == 0)
551 0 : m_ColorScaling = ColorTreatment::LOG_10_SCALING;
552 0 : else if (os_Color_EscalatColor.compare("IntervalsUsuari") == 0)
553 0 : m_ColorScaling = ColorTreatment::USER_INTERVALS;
554 : }
555 : else
556 : {
557 57 : if (IsCategorical())
558 52 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
559 : else
560 5 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
561 : }
562 :
563 62 : if (m_ColorScaling == ColorTreatment::DEFAULT_SCALING)
564 0 : return CE_Failure;
565 62 : return CE_None;
566 : }
567 :
568 2 : CPLErr MMRPalettes::UpdateConstantColor()
569 : {
570 : // Example: Color_Smb=(255,0,255)
571 4 : CPLString os_Color_Smb;
572 2 : if (!m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
573 : "Color_Smb", os_Color_Smb))
574 0 : return CE_None;
575 :
576 2 : os_Color_Smb.replaceAll(" ", "");
577 4 : if (!os_Color_Smb.empty() && os_Color_Smb.size() >= 7 &&
578 4 : os_Color_Smb[0] == '(' && os_Color_Smb[os_Color_Smb.size() - 1] == ')')
579 : {
580 2 : os_Color_Smb.replaceAll("(", "");
581 2 : os_Color_Smb.replaceAll(")", "");
582 2 : const CPLStringList aosTokens(CSLTokenizeString2(os_Color_Smb, ",", 0));
583 2 : if (CSLCount(aosTokens) != 3)
584 : {
585 0 : CPLError(CE_Failure, CPLE_AppDefined,
586 : "Invalid constant color: \"%s\"",
587 0 : m_pfRel->GetRELNameChar());
588 0 : return CE_Failure;
589 : }
590 :
591 : int nIColor0;
592 2 : if (1 != sscanf(aosTokens[0], "%d", &nIColor0))
593 : {
594 0 : CPLError(CE_Failure, CPLE_AppDefined,
595 : "Invalid constant color: \"%s\"",
596 0 : m_pfRel->GetRELNameChar());
597 0 : return CE_Failure;
598 : }
599 :
600 : int nIColor1;
601 2 : if (1 != sscanf(aosTokens[1], "%d", &nIColor1))
602 : {
603 0 : CPLError(CE_Failure, CPLE_AppDefined,
604 : "Invalid constant color: \"%s\"",
605 0 : m_pfRel->GetRELNameChar());
606 0 : return CE_Failure;
607 : }
608 :
609 : int nIColor2;
610 2 : if (1 != sscanf(aosTokens[2], "%d", &nIColor2))
611 : {
612 0 : CPLError(CE_Failure, CPLE_AppDefined,
613 : "Invalid constant color: \"%s\"",
614 0 : m_pfRel->GetRELNameChar());
615 0 : return CE_Failure;
616 : }
617 :
618 2 : SetConstantColorRGB(static_cast<short>(nIColor0),
619 : static_cast<short>(nIColor1),
620 : static_cast<short>(nIColor2));
621 : }
622 2 : return CE_None;
623 : }
|