LCOV - code coverage report
Current view: top level - frmts/miramon - miramon_palettes.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 204 266 76.7 %
Date: 2025-09-10 17:48:50 Functions: 8 8 100.0 %

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

Generated by: LCOV version 1.14