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,
382 21 : static_cast<vsi_l_offset>(oColorTable.FirstRecordOffset),
383 : SEEK_SET);
384 : /*
385 : Each record's CLAUSIMBOL field doesn't match a pixel value present in the raster,
386 : and it's used only for discovering nodata value (blanc value).
387 : The list of values is used to map every value in a color using:
388 : - Direct assignation: mode used in categorical modes but possible in continuous.
389 : - Linear scaling
390 : - Logarithmic scaling
391 : */
392 1234 : for (int nIPaletteColors = 0; nIPaletteColors < m_nNPaletteColors;
393 : nIPaletteColors++)
394 : {
395 2426 : if (oColorTable.BytesPerRecord !=
396 1213 : VSIFReadL(pzsRecord, sizeof(unsigned char),
397 1213 : oColorTable.BytesPerRecord, oColorTable.pfDataBase))
398 : {
399 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
400 : osColorTableFileName.c_str());
401 0 : VSIFree(pszField);
402 0 : VSIFree(pzsRecord);
403 0 : VSIFCloseL(oColorTable.pfDataBase);
404 0 : MM_ReleaseMainFields(&oColorTable);
405 0 : return CE_Failure;
406 : }
407 :
408 : // Nodata identification
409 1213 : memcpy(pszField,
410 1213 : pzsRecord + oColorTable.pField[nClauSimbol].AccumulatedBytes,
411 1213 : oColorTable.pField[nClauSimbol].BytesPerField);
412 1213 : pszField[oColorTable.pField[nClauSimbol].BytesPerField] = '\0';
413 2426 : CPLString osField = pszField;
414 1213 : osField.replaceAll(" ", "");
415 1213 : if (osField.empty()) // Nodata value
416 : {
417 6 : m_bHasNodata = true;
418 6 : m_nNoDataPaletteIndex = nIPaletteColors;
419 : }
420 :
421 1213 : AssignColorFromDBF(oColorTable, pzsRecord, pszField, nRIndex, nGIndex,
422 : nBIndex, nIPaletteColors);
423 : }
424 :
425 21 : VSIFree(pszField);
426 21 : VSIFree(pzsRecord);
427 21 : VSIFCloseL(oColorTable.pfDataBase);
428 21 : MM_ReleaseMainFields(&oColorTable);
429 :
430 21 : return CE_None;
431 : }
432 :
433 : // Colors in a PAL, P25 or P65 format files
434 : // Updates nNPaletteColors
435 : CPLErr
436 3 : MMRPalettes::GetPaletteColors_PAL_P25_P65(const CPLString &os_Color_Paleta_DBF)
437 :
438 : {
439 6 : CPLString osAux = CPLGetPathSafe(m_pfRel->GetRELNameChar());
440 : CPLString osColorTableFileName =
441 6 : CPLFormFilenameSafe(osAux.c_str(), os_Color_Paleta_DBF.c_str(), "");
442 :
443 : // This kind of palette has not NoData color.
444 : //bHasNodata = false;
445 :
446 6 : CPLString osExtension = CPLGetExtensionSafe(os_Color_Paleta_DBF);
447 3 : int nNReadPaletteColors = 0;
448 3 : m_nNPaletteColors = 0;
449 :
450 3 : if (osExtension.tolower() == "pal")
451 1 : m_nNPaletteColors = 64;
452 2 : else if (osExtension.tolower() == "p25")
453 1 : m_nNPaletteColors = 256;
454 1 : else if (osExtension.tolower() == "p65")
455 1 : m_nNPaletteColors = 65536;
456 : else
457 0 : return CE_None;
458 :
459 15 : for (int iColumn = 0; iColumn < 4; iColumn++)
460 : {
461 : try
462 : {
463 12 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
464 : }
465 0 : catch (std::bad_alloc &e)
466 : {
467 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
468 0 : return CE_Failure;
469 : }
470 : }
471 :
472 3 : VSILFILE *fpColorTable = VSIFOpenL(osColorTableFileName, "rt");
473 3 : if (!fpColorTable)
474 : {
475 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
476 : osColorTableFileName.c_str());
477 0 : return CE_Failure;
478 : }
479 :
480 3 : nNReadPaletteColors = 0;
481 : const char *pszLine;
482 51 : while ((pszLine = CPLReadLineL(fpColorTable)) != nullptr)
483 : {
484 : // Ignore empty lines
485 48 : if (pszLine[0] == '\0')
486 0 : continue;
487 :
488 48 : const CPLStringList aosTokens(CSLTokenizeString2(pszLine, " \t", 0));
489 48 : if (aosTokens.size() != 4)
490 : {
491 0 : VSIFCloseL(fpColorTable);
492 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
493 : osColorTableFileName.c_str());
494 0 : return CE_Failure;
495 : }
496 :
497 : // Index of the color
498 : // papszTokens[0] is ignored;
499 :
500 : // RED
501 48 : m_aadfPaletteColors[0][nNReadPaletteColors] = CPLAtof(aosTokens[1]);
502 :
503 : // GREEN
504 48 : m_aadfPaletteColors[1][nNReadPaletteColors] = CPLAtof(aosTokens[2]);
505 :
506 : // BLUE
507 48 : m_aadfPaletteColors[2][nNReadPaletteColors] = CPLAtof(aosTokens[3]);
508 :
509 : // ALPHA
510 48 : m_aadfPaletteColors[3][nNReadPaletteColors] = 255.0;
511 48 : nNReadPaletteColors++;
512 : }
513 :
514 : // Filling the rest of colors.
515 3 : for (int nIColorIndex = nNReadPaletteColors;
516 65811 : nIColorIndex < m_nNPaletteColors; nIColorIndex++)
517 : {
518 65808 : m_aadfPaletteColors[0][nNReadPaletteColors] = m_sDefaultColorRGB.c1;
519 65808 : m_aadfPaletteColors[1][nNReadPaletteColors] = m_sDefaultColorRGB.c2;
520 65808 : m_aadfPaletteColors[2][nNReadPaletteColors] = m_sDefaultColorRGB.c3;
521 65808 : m_aadfPaletteColors[3][nNReadPaletteColors] = m_sDefaultColorRGB.c4;
522 65808 : nNReadPaletteColors++;
523 : }
524 :
525 3 : if (nNReadPaletteColors != m_nNPaletteColors)
526 : {
527 0 : VSIFCloseL(fpColorTable);
528 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
529 : osColorTableFileName.c_str());
530 0 : return CE_Failure;
531 : }
532 :
533 3 : VSIFCloseL(fpColorTable);
534 :
535 3 : return CE_None;
536 : }
537 :
538 62 : CPLErr MMRPalettes::UpdateColorInfo()
539 : {
540 124 : CPLString os_Color_EscalatColor;
541 62 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
542 : "Color_EscalatColor",
543 67 : os_Color_EscalatColor) &&
544 5 : !os_Color_EscalatColor.empty())
545 : {
546 5 : if (os_Color_EscalatColor.compare("AssigDirecta") == 0)
547 2 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
548 3 : else if (os_Color_EscalatColor.compare("DespOrigen") == 0)
549 0 : m_ColorScaling = ColorTreatment::ORIGIN_DISPLACEMENT;
550 3 : else if (os_Color_EscalatColor.compare("lineal") == 0)
551 3 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
552 0 : else if (os_Color_EscalatColor.compare("log_10") == 0)
553 0 : m_ColorScaling = ColorTreatment::LOG_10_SCALING;
554 0 : else if (os_Color_EscalatColor.compare("IntervalsUsuari") == 0)
555 0 : m_ColorScaling = ColorTreatment::USER_INTERVALS;
556 : }
557 : else
558 : {
559 57 : if (IsCategorical())
560 52 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
561 : else
562 5 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
563 : }
564 :
565 62 : if (m_ColorScaling == ColorTreatment::DEFAULT_SCALING)
566 0 : return CE_Failure;
567 62 : return CE_None;
568 : }
569 :
570 2 : CPLErr MMRPalettes::UpdateConstantColor()
571 : {
572 : // Example: Color_Smb=(255,0,255)
573 4 : CPLString os_Color_Smb;
574 2 : if (!m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
575 : "Color_Smb", os_Color_Smb))
576 0 : return CE_None;
577 :
578 2 : os_Color_Smb.replaceAll(" ", "");
579 4 : if (!os_Color_Smb.empty() && os_Color_Smb.size() >= 7 &&
580 4 : os_Color_Smb[0] == '(' && os_Color_Smb[os_Color_Smb.size() - 1] == ')')
581 : {
582 2 : os_Color_Smb.replaceAll("(", "");
583 2 : os_Color_Smb.replaceAll(")", "");
584 2 : const CPLStringList aosTokens(CSLTokenizeString2(os_Color_Smb, ",", 0));
585 2 : if (CSLCount(aosTokens) != 3)
586 : {
587 0 : CPLError(CE_Failure, CPLE_AppDefined,
588 : "Invalid constant color: \"%s\"",
589 0 : m_pfRel->GetRELNameChar());
590 0 : return CE_Failure;
591 : }
592 :
593 : int nIColor0;
594 2 : if (1 != sscanf(aosTokens[0], "%d", &nIColor0))
595 : {
596 0 : CPLError(CE_Failure, CPLE_AppDefined,
597 : "Invalid constant color: \"%s\"",
598 0 : m_pfRel->GetRELNameChar());
599 0 : return CE_Failure;
600 : }
601 :
602 : int nIColor1;
603 2 : if (1 != sscanf(aosTokens[1], "%d", &nIColor1))
604 : {
605 0 : CPLError(CE_Failure, CPLE_AppDefined,
606 : "Invalid constant color: \"%s\"",
607 0 : m_pfRel->GetRELNameChar());
608 0 : return CE_Failure;
609 : }
610 :
611 : int nIColor2;
612 2 : if (1 != sscanf(aosTokens[2], "%d", &nIColor2))
613 : {
614 0 : CPLError(CE_Failure, CPLE_AppDefined,
615 : "Invalid constant color: \"%s\"",
616 0 : m_pfRel->GetRELNameChar());
617 0 : return CE_Failure;
618 : }
619 :
620 2 : SetConstantColorRGB(static_cast<short>(nIColor0),
621 : static_cast<short>(nIColor1),
622 : static_cast<short>(nIColor2));
623 : }
624 2 : return CE_None;
625 : }
|