LCOV - code coverage report
Current view: top level - frmts/kea - kearat.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 489 643 76.0 %
Date: 2025-10-21 22:35:35 Functions: 31 37 83.8 %

          Line data    Source code
       1             : /*
       2             :  *  kearat.cpp
       3             :  *
       4             :  *  Created by Pete Bunting on 01/08/2012.
       5             :  *  Copyright 2012 LibKEA. All rights reserved.
       6             :  *
       7             :  *  This file is part of LibKEA.
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  *
      11             :  */
      12             : 
      13             : #include "kearat.h"
      14             : 
      15         405 : KEARasterAttributeTable::KEARasterAttributeTable(
      16         405 :     kealib::KEAAttributeTable *poKEATable, KEARasterBand *poBand)
      17             : {
      18         405 :     this->m_hMutex = CPLCreateMutex();
      19         405 :     CPLReleaseMutex(this->m_hMutex);
      20         457 :     for (size_t nColumnIndex = 0;
      21         457 :          nColumnIndex < poKEATable->getMaxGlobalColIdx(); nColumnIndex++)
      22             :     {
      23          52 :         kealib::KEAATTField sKEAField;
      24             :         try
      25             :         {
      26          52 :             sKEAField = poKEATable->getField(nColumnIndex);
      27             :         }
      28           0 :         catch (const kealib::KEAATTException &)
      29             :         {
      30             :             // pKEATable->getField raised exception because we have a missing
      31             :             // column
      32           0 :             continue;
      33             :         }
      34          52 :         m_aoFields.push_back(std::move(sKEAField));
      35             :     }
      36         405 :     m_poKEATable = poKEATable;
      37         405 :     m_poBand = poBand;
      38         405 : }
      39             : 
      40         810 : KEARasterAttributeTable::~KEARasterAttributeTable()
      41             : {
      42             :     // can't just delete thanks to Windows
      43         405 :     kealib::KEAAttributeTable::destroyAttributeTable(m_poKEATable);
      44         405 :     CPLDestroyMutex(m_hMutex);
      45         405 :     m_hMutex = nullptr;
      46         810 : }
      47             : 
      48           1 : GDALDefaultRasterAttributeTable *KEARasterAttributeTable::Clone() const
      49             : {
      50           1 :     const int nColCount = GetColumnCount();
      51           1 :     if (nColCount > 0 && GetRowCount() > RAT_MAX_ELEM_FOR_CLONE / nColCount)
      52           0 :         return nullptr;
      53             : 
      54           2 :     auto poRAT = std::make_unique<GDALDefaultRasterAttributeTable>();
      55             : 
      56          11 :     for (int iCol = 0; iCol < (int)m_aoFields.size(); iCol++)
      57             :     {
      58          10 :         const auto &sName = m_aoFields[iCol].name;
      59          10 :         const auto &sUsage = m_aoFields[iCol].usage;
      60             :         GDALRATFieldUsage eGDALUsage;
      61          10 :         if (sUsage == "PixelCount")
      62           1 :             eGDALUsage = GFU_PixelCount;
      63           9 :         else if (sUsage == "Name")
      64           1 :             eGDALUsage = GFU_Name;
      65           8 :         else if (sUsage == "Red")
      66           1 :             eGDALUsage = GFU_Red;
      67           7 :         else if (sUsage == "Green")
      68           1 :             eGDALUsage = GFU_Green;
      69           6 :         else if (sUsage == "Blue")
      70           1 :             eGDALUsage = GFU_Blue;
      71           5 :         else if (sUsage == "Alpha")
      72           1 :             eGDALUsage = GFU_Alpha;
      73             :         else
      74             :         {
      75             :             // don't recognise any other special names - generic column
      76           4 :             eGDALUsage = GFU_Generic;
      77             :         }
      78             : 
      79          10 :         const GDALRATFieldType eGDALType = GetTypeOfCol(iCol);
      80          10 :         poRAT->CreateColumn(sName.c_str(), eGDALType, eGDALUsage);
      81          10 :         poRAT->SetRowCount(static_cast<int>(m_poKEATable->getSize()));
      82             : 
      83          10 :         if (m_poKEATable->getSize() == 0)
      84           0 :             continue;
      85             : 
      86          10 :         switch (eGDALType)
      87             :         {
      88           4 :             case GFT_Integer:
      89             :             {
      90           4 :                 int *panColData = (int *)VSI_MALLOC2_VERBOSE(
      91             :                     sizeof(int), m_poKEATable->getSize());
      92           4 :                 if (panColData == nullptr)
      93             :                 {
      94           0 :                     return nullptr;
      95             :                 }
      96             : 
      97           4 :                 if ((const_cast<KEARasterAttributeTable *>(this))
      98           8 :                         ->ValuesIO(GF_Read, iCol, 0,
      99           4 :                                    static_cast<int>(m_poKEATable->getSize()),
     100           4 :                                    panColData) != CE_None)
     101             :                 {
     102           0 :                     CPLFree(panColData);
     103           0 :                     return nullptr;
     104             :                 }
     105             : 
     106           8 :                 for (int iRow = 0; iRow < (int)m_poKEATable->getSize(); iRow++)
     107             :                 {
     108           4 :                     poRAT->SetValue(iRow, iCol, panColData[iRow]);
     109             :                 }
     110           4 :                 CPLFree(panColData);
     111           4 :                 break;
     112             :             }
     113             : 
     114           2 :             case GFT_Real:
     115             :             {
     116           2 :                 double *padfColData = (double *)VSI_MALLOC2_VERBOSE(
     117             :                     sizeof(double), m_poKEATable->getSize());
     118           2 :                 if (padfColData == nullptr)
     119             :                 {
     120           0 :                     return nullptr;
     121             :                 }
     122           2 :                 if ((const_cast<KEARasterAttributeTable *>(this))
     123           4 :                         ->ValuesIO(GF_Read, iCol, 0,
     124           2 :                                    static_cast<int>(m_poKEATable->getSize()),
     125           2 :                                    padfColData) != CE_None)
     126             :                 {
     127           0 :                     CPLFree(padfColData);
     128           0 :                     return nullptr;
     129             :                 }
     130             : 
     131           4 :                 for (int iRow = 0; iRow < (int)m_poKEATable->getSize(); iRow++)
     132             :                 {
     133           2 :                     poRAT->SetValue(iRow, iCol, padfColData[iRow]);
     134             :                 }
     135           2 :                 CPLFree(padfColData);
     136           2 :                 break;
     137             :             }
     138             : 
     139           3 :             case GFT_String:
     140             :             {
     141           3 :                 char **papszColData = (char **)VSI_MALLOC2_VERBOSE(
     142             :                     sizeof(char *), m_poKEATable->getSize());
     143           3 :                 if (papszColData == nullptr)
     144             :                 {
     145           0 :                     return nullptr;
     146             :                 }
     147             : 
     148           3 :                 if ((const_cast<KEARasterAttributeTable *>(this))
     149           6 :                         ->ValuesIO(GF_Read, iCol, 0,
     150           3 :                                    static_cast<int>(m_poKEATable->getSize()),
     151           3 :                                    papszColData) != CE_None)
     152             :                 {
     153           0 :                     CPLFree(papszColData);
     154           0 :                     return nullptr;
     155             :                 }
     156             : 
     157           6 :                 for (int iRow = 0; iRow < (int)m_poKEATable->getSize(); iRow++)
     158             :                 {
     159           3 :                     poRAT->SetValue(iRow, iCol, papszColData[iRow]);
     160           3 :                     CPLFree(papszColData[iRow]);
     161             :                 }
     162           3 :                 CPLFree(papszColData);
     163           3 :                 break;
     164             :             }
     165             : 
     166           1 :             case GFT_Boolean:
     167             :             {
     168           1 :                 bool *pabColData = (bool *)VSI_MALLOC2_VERBOSE(
     169             :                     sizeof(bool), m_poKEATable->getSize());
     170           1 :                 if (pabColData == nullptr)
     171             :                 {
     172           0 :                     return nullptr;
     173             :                 }
     174             : 
     175           1 :                 if ((const_cast<KEARasterAttributeTable *>(this))
     176           2 :                         ->ValuesIO(GF_Read, iCol, 0,
     177           1 :                                    static_cast<int>(m_poKEATable->getSize()),
     178           1 :                                    pabColData) != CE_None)
     179             :                 {
     180           0 :                     CPLFree(pabColData);
     181           0 :                     return nullptr;
     182             :                 }
     183             : 
     184           2 :                 for (int iRow = 0; iRow < (int)m_poKEATable->getSize(); iRow++)
     185             :                 {
     186           1 :                     poRAT->SetValue(iRow, iCol, pabColData[iRow]);
     187             :                 }
     188           1 :                 CPLFree(pabColData);
     189           1 :                 break;
     190             :             }
     191             : 
     192           0 :             case GFT_DateTime:
     193             :             case GFT_WKBGeometry:
     194           0 :                 CPLAssert(false);
     195             :                 break;
     196             :         }
     197             :     }
     198             : 
     199           1 :     poRAT->SetTableType(this->GetTableType());
     200             : 
     201           1 :     return poRAT.release();
     202             : }
     203             : 
     204         112 : int KEARasterAttributeTable::GetColumnCount() const
     205             : {
     206         112 :     return (int)m_aoFields.size();
     207             : }
     208             : 
     209          97 : const char *KEARasterAttributeTable::GetNameOfCol(int nCol) const
     210             : {
     211          97 :     if ((nCol < 0) || (nCol >= (int)m_aoFields.size()))
     212           2 :         return nullptr;
     213             : 
     214          95 :     return m_aoFields[nCol].name.c_str();
     215             : }
     216             : 
     217          49 : GDALRATFieldUsage KEARasterAttributeTable::GetUsageOfCol(int nCol) const
     218             : {
     219          49 :     if ((nCol < 0) || (nCol >= (int)m_aoFields.size()))
     220           2 :         return GFU_Generic;
     221             : 
     222             :     GDALRATFieldUsage eGDALUsage;
     223          47 :     std::string keausage = m_aoFields[nCol].usage;
     224             : 
     225          47 :     if (keausage == "PixelCount")
     226           3 :         eGDALUsage = GFU_PixelCount;
     227          44 :     else if (keausage == "Name")
     228           3 :         eGDALUsage = GFU_Name;
     229          41 :     else if (keausage == "Red")
     230           8 :         eGDALUsage = GFU_Red;
     231          33 :     else if (keausage == "Green")
     232           8 :         eGDALUsage = GFU_Green;
     233          25 :     else if (keausage == "Blue")
     234           8 :         eGDALUsage = GFU_Blue;
     235          17 :     else if (keausage == "Alpha")
     236           8 :         eGDALUsage = GFU_Alpha;
     237             :     else
     238             :     {
     239             :         // don't recognise any other special names - generic column
     240           9 :         eGDALUsage = GFU_Generic;
     241             :     }
     242             : 
     243          47 :     return eGDALUsage;
     244             : }
     245             : 
     246          73 : GDALRATFieldType KEARasterAttributeTable::GetTypeOfCol(int nCol) const
     247             : {
     248          73 :     if ((nCol < 0) || (nCol >= (int)m_aoFields.size()))
     249           2 :         return GFT_Integer;
     250             : 
     251             :     GDALRATFieldType eGDALType;
     252          71 :     switch (m_aoFields[nCol].dataType)
     253             :     {
     254           5 :         case kealib::kea_att_bool:
     255           5 :             eGDALType = GFT_Boolean;
     256           5 :             break;
     257          40 :         case kealib::kea_att_int:
     258          40 :             eGDALType = GFT_Integer;
     259          40 :             break;
     260          11 :         case kealib::kea_att_float:
     261          11 :             eGDALType = GFT_Real;
     262          11 :             break;
     263          15 :         case kealib::kea_att_string:
     264          15 :             eGDALType = GFT_String;
     265          15 :             break;
     266           0 :         default:
     267           0 :             eGDALType = GFT_Integer;
     268           0 :             break;
     269             :     }
     270          71 :     return eGDALType;
     271             : }
     272             : 
     273           7 : int KEARasterAttributeTable::GetColOfUsage(GDALRATFieldUsage eUsage) const
     274             : {
     275             :     unsigned int i;
     276             : 
     277          14 :     std::string keausage;
     278           7 :     switch (eUsage)
     279             :     {
     280           1 :         case GFU_PixelCount:
     281           1 :             keausage = "PixelCount";
     282           1 :             break;
     283           1 :         case GFU_Name:
     284           1 :             keausage = "Name";
     285           1 :             break;
     286           1 :         case GFU_Red:
     287           1 :             keausage = "Red";
     288           1 :             break;
     289           1 :         case GFU_Green:
     290           1 :             keausage = "Green";
     291           1 :             break;
     292           1 :         case GFU_Blue:
     293           1 :             keausage = "Blue";
     294           1 :             break;
     295           1 :         case GFU_Alpha:
     296           1 :             keausage = "Alpha";
     297           1 :             break;
     298           1 :         default:
     299           1 :             keausage = "Generic";
     300           1 :             break;
     301             :     }
     302             : 
     303          28 :     for (i = 0; i < m_aoFields.size(); i++)
     304             :     {
     305          28 :         if (m_aoFields[i].usage == keausage)
     306           7 :             return i;
     307             :     }
     308           0 :     return -1;
     309             : }
     310             : 
     311         484 : int KEARasterAttributeTable::GetRowCount() const
     312             : {
     313         484 :     return (int)m_poKEATable->getSize();
     314             : }
     315             : 
     316           7 : const char *KEARasterAttributeTable::GetValueAsString(int iRow,
     317             :                                                       int iField) const
     318             : {
     319             :     /// Let ValuesIO do the work.
     320             :     char *apszStrList[1];
     321           7 :     if ((const_cast<KEARasterAttributeTable *>(this))
     322           7 :             ->ValuesIO(GF_Read, iField, iRow, 1, apszStrList) != CE_None)
     323             :     {
     324           3 :         return "";
     325             :     }
     326             : 
     327             :     const_cast<KEARasterAttributeTable *>(this)->osWorkingResult =
     328           4 :         apszStrList[0];
     329           4 :     CPLFree(apszStrList[0]);
     330             : 
     331           4 :     return osWorkingResult;
     332             : }
     333             : 
     334          31 : int KEARasterAttributeTable::GetValueAsInt(int iRow, int iField) const
     335             : {
     336             :     // Let ValuesIO do the work.
     337          31 :     int nValue = 0;
     338          31 :     if ((const_cast<KEARasterAttributeTable *>(this))
     339          31 :             ->ValuesIO(GF_Read, iField, iRow, 1, &nValue) != CE_None)
     340             :     {
     341           3 :         return 0;
     342             :     }
     343             : 
     344          28 :     return nValue;
     345             : }
     346             : 
     347           7 : double KEARasterAttributeTable::GetValueAsDouble(int iRow, int iField) const
     348             : {
     349             :     // Let ValuesIO do the work.
     350           7 :     double dfValue = 0.0;
     351           7 :     if ((const_cast<KEARasterAttributeTable *>(this))
     352           7 :             ->ValuesIO(GF_Read, iField, iRow, 1, &dfValue) != CE_None)
     353             :     {
     354           3 :         return 0;
     355             :     }
     356             : 
     357           4 :     return dfValue;
     358             : }
     359             : 
     360           5 : bool KEARasterAttributeTable::GetValueAsBoolean(int iRow, int iField) const
     361             : {
     362             :     // Let ValuesIO do the work.
     363           5 :     bool bValue = false;
     364           5 :     if ((const_cast<KEARasterAttributeTable *>(this))
     365           5 :             ->ValuesIO(GF_Read, iField, iRow, 1, &bValue) != CE_None)
     366             :     {
     367           3 :         return false;
     368             :     }
     369             : 
     370           2 :     return bValue;
     371             : }
     372             : 
     373           5 : GDALRATDateTime KEARasterAttributeTable::GetValueAsDateTime(int iRow,
     374             :                                                             int iField) const
     375             : {
     376             :     // Let ValuesIO do the work.
     377           5 :     GDALRATDateTime value;
     378           5 :     const_cast<KEARasterAttributeTable *>(this)->ValuesIO(GF_Read, iField, iRow,
     379             :                                                           1, &value);
     380           5 :     return value;
     381             : }
     382             : 
     383             : const GByte *
     384           5 : KEARasterAttributeTable::GetValueAsWKBGeometry(int iRow, int iField,
     385             :                                                size_t &nWKBSize) const
     386             : {
     387             :     // Let ValuesIO do the work.
     388           5 :     GByte *pabyWKB = nullptr;
     389           5 :     const_cast<KEARasterAttributeTable *>(this)->ValuesIO(
     390             :         GF_Read, iField, iRow, 1, &pabyWKB, &nWKBSize);
     391           5 :     if (nWKBSize)
     392           1 :         m_abyCachedWKB.assign(pabyWKB, pabyWKB + nWKBSize);
     393           5 :     VSIFree(pabyWKB);
     394           5 :     return nWKBSize ? m_abyCachedWKB.data() : nullptr;
     395             : }
     396             : 
     397           6 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField,
     398             :                                          const char *pszValue)
     399             : {
     400             :     // Let ValuesIO do the work.
     401           6 :     char *apszValues[1] = {const_cast<char *>(pszValue)};
     402          12 :     return ValuesIO(GF_Write, iField, iRow, 1, apszValues);
     403             : }
     404             : 
     405           6 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField, double dfValue)
     406             : {
     407             :     // Let ValuesIO do the work.
     408           6 :     return ValuesIO(GF_Write, iField, iRow, 1, &dfValue);
     409             : }
     410             : 
     411          42 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField, int nValue)
     412             : {
     413             :     // Let ValuesIO do the work.
     414          42 :     return ValuesIO(GF_Write, iField, iRow, 1, &nValue);
     415             : }
     416             : 
     417           4 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField, bool bValue)
     418             : {
     419             :     // Let ValuesIO do the work.
     420           4 :     return ValuesIO(GF_Write, iField, iRow, 1, &bValue);
     421             : }
     422             : 
     423           4 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField,
     424             :                                          const GDALRATDateTime &sDateTime)
     425             : {
     426             :     // Let ValuesIO do the work.
     427           4 :     return ValuesIO(GF_Write, iField, iRow, 1,
     428           4 :                     const_cast<GDALRATDateTime *>(&sDateTime));
     429             : }
     430             : 
     431           4 : CPLErr KEARasterAttributeTable::SetValue(int iRow, int iField,
     432             :                                          const void *pabyWKB, size_t nWKBSize)
     433             : {
     434             :     // Let ValuesIO do the work.
     435           4 :     const GByte **ppabyWKB = reinterpret_cast<const GByte **>(&pabyWKB);
     436           4 :     return ValuesIO(GF_Write, iField, iRow, 1, const_cast<GByte **>(ppabyWKB),
     437           4 :                     &nWKBSize);
     438             : }
     439             : 
     440          33 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
     441             :                                          int iStartRow, int iLength,
     442             :                                          double *pdfData)
     443             : {
     444             :     /*if( ( eRWFlag == GF_Write ) && ( this->eAccess == GA_ReadOnly ) )
     445             :     {
     446             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     447             :             "Dataset not open in update mode");
     448             :         return CE_Failure;
     449             :     }*/
     450          66 :     CPLMutexHolderD(&m_hMutex);
     451             : 
     452          33 :     if (iField < 0 || iField >= (int)m_aoFields.size())
     453             :     {
     454           1 :         CPLError(CE_Failure, CPLE_AppDefined, "iField (%d) out of range.",
     455             :                  iField);
     456             : 
     457           1 :         return CE_Failure;
     458             :     }
     459             : 
     460          32 :     if (iStartRow < 0 || (iStartRow + iLength) > (int)m_poKEATable->getSize())
     461             :     {
     462           2 :         CPLError(CE_Failure, CPLE_AppDefined,
     463             :                  "iStartRow (%d) + iLength(%d) out of range.", iStartRow,
     464             :                  iLength);
     465             : 
     466           2 :         return CE_Failure;
     467             :     }
     468             : 
     469          30 :     switch (m_aoFields[iField].dataType)
     470             :     {
     471           3 :         case kealib::kea_att_bool:
     472             :         case kealib::kea_att_int:
     473             :         {
     474             :             // allocate space for ints
     475           3 :             int *panColData = (int *)VSI_MALLOC2_VERBOSE(iLength, sizeof(int));
     476           3 :             if (panColData == nullptr)
     477             :             {
     478           0 :                 return CE_Failure;
     479             :             }
     480             : 
     481           3 :             if (eRWFlag == GF_Write)
     482             :             {
     483             :                 // copy the application supplied doubles to ints
     484           4 :                 for (int i = 0; i < iLength; i++)
     485           2 :                     panColData[i] = static_cast<int>(pdfData[i]);
     486             :             }
     487             : 
     488             :             // do the ValuesIO as ints
     489             :             CPLErr eVal =
     490           3 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, panColData);
     491           3 :             if (eVal != CE_None)
     492             :             {
     493           0 :                 CPLFree(panColData);
     494           0 :                 return eVal;
     495             :             }
     496             : 
     497           3 :             if (eRWFlag == GF_Read)
     498             :             {
     499             :                 // copy them back to doubles
     500           2 :                 for (int i = 0; i < iLength; i++)
     501           1 :                     pdfData[i] = panColData[i];
     502             :             }
     503             : 
     504           3 :             CPLFree(panColData);
     505             :         }
     506           3 :         break;
     507          23 :         case kealib::kea_att_float:
     508             :         {
     509             :             try
     510             :             {
     511          23 :                 if (eRWFlag == GF_Read)
     512          15 :                     m_poKEATable->getFloatFields(
     513          15 :                         iStartRow, iLength, m_aoFields[iField].idx, pdfData);
     514             :                 else
     515           8 :                     m_poKEATable->setFloatFields(
     516           8 :                         iStartRow, iLength, m_aoFields[iField].idx, pdfData);
     517             :             }
     518           0 :             catch (kealib::KEAException &e)
     519             :             {
     520           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     521           0 :                          "Failed to read/write attribute table: %s", e.what());
     522           0 :                 return CE_Failure;
     523             :             }
     524             :         }
     525          23 :         break;
     526           4 :         case kealib::kea_att_string:
     527             :         {
     528             :             // allocate space for string pointers
     529             :             char **papszColData =
     530           4 :                 (char **)VSI_MALLOC2_VERBOSE(iLength, sizeof(char *));
     531           4 :             if (papszColData == nullptr)
     532             :             {
     533           0 :                 return CE_Failure;
     534             :             }
     535             : 
     536           4 :             if (eRWFlag == GF_Write)
     537             :             {
     538             :                 // copy the application supplied doubles to strings
     539           6 :                 for (int i = 0; i < iLength; i++)
     540             :                 {
     541           3 :                     osWorkingResult.Printf("%.16g", pdfData[i]);
     542           3 :                     papszColData[i] = CPLStrdup(osWorkingResult);
     543             :                 }
     544             :             }
     545             : 
     546             :             // do the ValuesIO as strings
     547             :             CPLErr eVal =
     548           4 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, papszColData);
     549           4 :             if (eVal != CE_None)
     550             :             {
     551           0 :                 if (eRWFlag == GF_Write)
     552             :                 {
     553           0 :                     for (int i = 0; i < iLength; i++)
     554           0 :                         CPLFree(papszColData[i]);
     555             :                 }
     556           0 :                 CPLFree(papszColData);
     557           0 :                 return eVal;
     558             :             }
     559             : 
     560           4 :             if (eRWFlag == GF_Read)
     561             :             {
     562             :                 // copy them back to doubles
     563           2 :                 for (int i = 0; i < iLength; i++)
     564           1 :                     pdfData[i] = CPLAtof(papszColData[i]);
     565             :             }
     566             : 
     567             :             // either we allocated them for write, or they were allocated
     568             :             // by ValuesIO on read
     569           8 :             for (int i = 0; i < iLength; i++)
     570           4 :                 CPLFree(papszColData[i]);
     571             : 
     572           4 :             CPLFree(papszColData);
     573             :         }
     574           4 :         break;
     575           0 :         default:
     576           0 :             break;
     577             :     }
     578          30 :     return CE_None;
     579             : }
     580             : 
     581          16 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
     582             :                                          int iStartRow, int iLength,
     583             :                                          bool *pbData)
     584             : {
     585             :     /*if( ( eRWFlag == GF_Write ) && ( this->eAccess == GA_ReadOnly ) )
     586             :     {
     587             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     588             :             "Dataset not open in update mode");
     589             :         return CE_Failure;
     590             :     }*/
     591          32 :     CPLMutexHolderD(&m_hMutex);
     592             : 
     593          16 :     if (iField < 0 || iField >= (int)m_aoFields.size())
     594             :     {
     595           1 :         CPLError(CE_Failure, CPLE_AppDefined, "iField (%d) out of range.",
     596             :                  iField);
     597             : 
     598           1 :         return CE_Failure;
     599             :     }
     600             : 
     601          15 :     if (iStartRow < 0 || (iStartRow + iLength) > (int)m_poKEATable->getSize())
     602             :     {
     603           2 :         CPLError(CE_Failure, CPLE_AppDefined,
     604             :                  "iStartRow (%d) + iLength(%d) out of range.", iStartRow,
     605             :                  iLength);
     606             : 
     607           2 :         return CE_Failure;
     608             :     }
     609             : 
     610          13 :     switch (m_aoFields[iField].dataType)
     611             :     {
     612           9 :         case kealib::kea_att_bool:
     613             :         {
     614             :             try
     615             :             {
     616           9 :                 if (eRWFlag == GF_Read)
     617           4 :                     m_poKEATable->getBoolFields(iStartRow, iLength,
     618           4 :                                                 m_aoFields[iField].idx, pbData);
     619             :                 else
     620           5 :                     m_poKEATable->setBoolFields(iStartRow, iLength,
     621           5 :                                                 m_aoFields[iField].idx, pbData);
     622             :             }
     623           0 :             catch (kealib::KEAException &e)
     624             :             {
     625           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     626           0 :                          "Failed to read/write attribute table: %s", e.what());
     627           0 :                 return CE_Failure;
     628             :             }
     629             :         }
     630           9 :         break;
     631           0 :         case kealib::kea_att_int:
     632             :         {
     633             :             // need to convert to/from int64_t
     634             :             int64_t *panColData =
     635           0 :                 (int64_t *)VSI_MALLOC2_VERBOSE(iLength, sizeof(int64_t));
     636           0 :             if (panColData == nullptr)
     637             :             {
     638           0 :                 return CE_Failure;
     639             :             }
     640             : 
     641           0 :             if (eRWFlag == GF_Write)
     642             :             {
     643             :                 // copy the application supplied bools to int64t
     644           0 :                 for (int i = 0; i < iLength; i++)
     645           0 :                     panColData[i] = pbData[i];
     646             :             }
     647             : 
     648             :             try
     649             :             {
     650           0 :                 if (eRWFlag == GF_Read)
     651           0 :                     m_poKEATable->getIntFields(
     652           0 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     653             :                 else
     654           0 :                     m_poKEATable->setIntFields(
     655           0 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     656             :             }
     657           0 :             catch (kealib::KEAException &e)
     658             :             {
     659             :                 // fprintf(stderr,"Failed to read/write attribute table: %s %d
     660             :                 // %d %ld\n", e.what(), iStartRow, iLength,
     661             :                 // m_poKEATable->getSize() );
     662           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     663           0 :                          "Failed to read/write attribute table: %s", e.what());
     664           0 :                 return CE_Failure;
     665             :             }
     666             : 
     667           0 :             if (eRWFlag == GF_Read)
     668             :             {
     669             :                 // copy them back to bools
     670           0 :                 for (int i = 0; i < iLength; i++)
     671           0 :                     pbData[i] = panColData[i] != 0;
     672             :             }
     673           0 :             CPLFree(panColData);
     674             :         }
     675           0 :         break;
     676           2 :         case kealib::kea_att_float:
     677             :         {
     678             :             // allocate space for doubles
     679             :             double *padfColData =
     680           2 :                 (double *)VSI_MALLOC2_VERBOSE(iLength, sizeof(double));
     681           2 :             if (padfColData == nullptr)
     682             :             {
     683           0 :                 return CE_Failure;
     684             :             }
     685             : 
     686           2 :             if (eRWFlag == GF_Write)
     687             :             {
     688             :                 // copy the application supplied ints to doubles
     689           2 :                 for (int i = 0; i < iLength; i++)
     690           1 :                     padfColData[i] = pbData[i];
     691             :             }
     692             : 
     693             :             // do the ValuesIO as doubles
     694             :             CPLErr eVal =
     695           2 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, padfColData);
     696           2 :             if (eVal != CE_None)
     697             :             {
     698           0 :                 CPLFree(padfColData);
     699           0 :                 return eVal;
     700             :             }
     701             : 
     702           2 :             if (eRWFlag == GF_Read)
     703             :             {
     704             :                 // copy them back to ints
     705           2 :                 for (int i = 0; i < iLength; i++)
     706           1 :                     pbData[i] = padfColData[i] != 0;
     707             :             }
     708             : 
     709           2 :             CPLFree(padfColData);
     710             :         }
     711           2 :         break;
     712           2 :         case kealib::kea_att_string:
     713             :         {
     714             :             // allocate space for string pointers
     715             :             char **papszColData =
     716           2 :                 (char **)VSI_MALLOC2_VERBOSE(iLength, sizeof(char *));
     717           2 :             if (papszColData == nullptr)
     718             :             {
     719           0 :                 return CE_Failure;
     720             :             }
     721             : 
     722           2 :             if (eRWFlag == GF_Write)
     723             :             {
     724             :                 // copy the application supplied ints to strings
     725           4 :                 for (int i = 0; i < iLength; i++)
     726             :                 {
     727           2 :                     papszColData[i] = CPLStrdup(pbData[i] ? "true" : "false");
     728             :                 }
     729             :             }
     730             : 
     731             :             // do the ValuesIO as strings
     732             :             CPLErr eVal =
     733           2 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, papszColData);
     734           2 :             if (eVal != CE_None)
     735             :             {
     736           0 :                 if (eRWFlag == GF_Write)
     737             :                 {
     738           0 :                     for (int i = 0; i < iLength; i++)
     739           0 :                         CPLFree(papszColData[i]);
     740             :                 }
     741           0 :                 CPLFree(papszColData);
     742           0 :                 return eVal;
     743             :             }
     744             : 
     745           2 :             if (eRWFlag == GF_Read)
     746             :             {
     747             :                 // copy them back to ints
     748           0 :                 for (int i = 0; i < iLength; i++)
     749           0 :                     pbData[i] = CPLTestBool(papszColData[i]);
     750             :             }
     751             : 
     752             :             // either we allocated them for write, or they were allocated
     753             :             // by ValuesIO on read
     754           4 :             for (int i = 0; i < iLength; i++)
     755           2 :                 CPLFree(papszColData[i]);
     756             : 
     757           2 :             CPLFree(papszColData);
     758             :         }
     759           2 :         break;
     760           0 :         default:
     761           0 :             break;
     762             :     }
     763          13 :     return CE_None;
     764             : }
     765             : 
     766         102 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
     767             :                                          int iStartRow, int iLength,
     768             :                                          int *pnData)
     769             : {
     770             :     /*if( ( eRWFlag == GF_Write ) && ( this->eAccess == GA_ReadOnly ) )
     771             :     {
     772             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     773             :             "Dataset not open in update mode");
     774             :         return CE_Failure;
     775             :     }*/
     776         204 :     CPLMutexHolderD(&m_hMutex);
     777             : 
     778         102 :     if (iField < 0 || iField >= (int)m_aoFields.size())
     779             :     {
     780           1 :         CPLError(CE_Failure, CPLE_AppDefined, "iField (%d) out of range.",
     781             :                  iField);
     782             : 
     783           1 :         return CE_Failure;
     784             :     }
     785             : 
     786         101 :     if (iStartRow < 0 || (iStartRow + iLength) > (int)m_poKEATable->getSize())
     787             :     {
     788           2 :         CPLError(CE_Failure, CPLE_AppDefined,
     789             :                  "iStartRow (%d) + iLength(%d) out of range.", iStartRow,
     790             :                  iLength);
     791             : 
     792           2 :         return CE_Failure;
     793             :     }
     794             : 
     795          99 :     switch (m_aoFields[iField].dataType)
     796             :     {
     797           2 :         case kealib::kea_att_bool:
     798             :         {
     799             :             // need to convert to/from bools
     800             :             bool *panColData =
     801           2 :                 (bool *)VSI_MALLOC2_VERBOSE(iLength, sizeof(bool));
     802           2 :             if (panColData == nullptr)
     803             :             {
     804           0 :                 return CE_Failure;
     805             :             }
     806             : 
     807           2 :             if (eRWFlag == GF_Write)
     808             :             {
     809             :                 // copy the application supplied ints to bools
     810           4 :                 for (int i = 0; i < iLength; i++)
     811             :                 {
     812           2 :                     panColData[i] = (pnData[i] != 0);
     813             :                 }
     814             :             }
     815             : 
     816             :             try
     817             :             {
     818           2 :                 if (eRWFlag == GF_Read)
     819           0 :                     m_poKEATable->getBoolFields(
     820           0 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     821             :                 else
     822           2 :                     m_poKEATable->setBoolFields(
     823           2 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     824             :             }
     825           0 :             catch (kealib::KEAException &e)
     826             :             {
     827           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     828           0 :                          "Failed to read/write attribute table: %s", e.what());
     829           0 :                 return CE_Failure;
     830             :             }
     831             : 
     832           2 :             if (eRWFlag == GF_Read)
     833             :             {
     834             :                 // copy them back to ints
     835           0 :                 for (int i = 0; i < iLength; i++)
     836           0 :                     pnData[i] = panColData[i] ? 1 : 0;
     837             :             }
     838           2 :             CPLFree(panColData);
     839             :         }
     840           2 :         break;
     841          90 :         case kealib::kea_att_int:
     842             :         {
     843             :             // need to convert to/from int64_t
     844             :             int64_t *panColData =
     845          90 :                 (int64_t *)VSI_MALLOC2_VERBOSE(iLength, sizeof(int64_t));
     846          90 :             if (panColData == nullptr)
     847             :             {
     848           0 :                 return CE_Failure;
     849             :             }
     850             : 
     851          90 :             if (eRWFlag == GF_Write)
     852             :             {
     853             :                 // copy the application supplied ints to int64t
     854          86 :                 for (int i = 0; i < iLength; i++)
     855          43 :                     panColData[i] = pnData[i];
     856             :             }
     857             : 
     858             :             try
     859             :             {
     860          90 :                 if (eRWFlag == GF_Read)
     861          47 :                     m_poKEATable->getIntFields(
     862          47 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     863             :                 else
     864          43 :                     m_poKEATable->setIntFields(
     865          43 :                         iStartRow, iLength, m_aoFields[iField].idx, panColData);
     866             :             }
     867           0 :             catch (kealib::KEAException &e)
     868             :             {
     869             :                 // fprintf(stderr,"Failed to read/write attribute table: %s %d
     870             :                 // %d %ld\n", e.what(), iStartRow, iLength,
     871             :                 // m_poKEATable->getSize() );
     872           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     873           0 :                          "Failed to read/write attribute table: %s", e.what());
     874           0 :                 return CE_Failure;
     875             :             }
     876             : 
     877          90 :             if (eRWFlag == GF_Read)
     878             :             {
     879             :                 // copy them back to ints
     880         110 :                 for (int i = 0; i < iLength; i++)
     881          63 :                     pnData[i] = static_cast<int>(panColData[i]);
     882             :             }
     883          90 :             CPLFree(panColData);
     884             :         }
     885          90 :         break;
     886           3 :         case kealib::kea_att_float:
     887             :         {
     888             :             // allocate space for doubles
     889             :             double *padfColData =
     890           3 :                 (double *)VSI_MALLOC2_VERBOSE(iLength, sizeof(double));
     891           3 :             if (padfColData == nullptr)
     892             :             {
     893           0 :                 return CE_Failure;
     894             :             }
     895             : 
     896           3 :             if (eRWFlag == GF_Write)
     897             :             {
     898             :                 // copy the application supplied ints to doubles
     899           2 :                 for (int i = 0; i < iLength; i++)
     900           1 :                     padfColData[i] = pnData[i];
     901             :             }
     902             : 
     903             :             // do the ValuesIO as doubles
     904             :             CPLErr eVal =
     905           3 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, padfColData);
     906           3 :             if (eVal != CE_None)
     907             :             {
     908           0 :                 CPLFree(padfColData);
     909           0 :                 return eVal;
     910             :             }
     911             : 
     912           3 :             if (eRWFlag == GF_Read)
     913             :             {
     914             :                 // copy them back to ints
     915           4 :                 for (int i = 0; i < iLength; i++)
     916           2 :                     pnData[i] = static_cast<int>(padfColData[i]);
     917             :             }
     918             : 
     919           3 :             CPLFree(padfColData);
     920             :         }
     921           3 :         break;
     922           4 :         case kealib::kea_att_string:
     923             :         {
     924             :             // allocate space for string pointers
     925             :             char **papszColData =
     926           4 :                 (char **)VSI_MALLOC2_VERBOSE(iLength, sizeof(char *));
     927           4 :             if (papszColData == nullptr)
     928             :             {
     929           0 :                 return CE_Failure;
     930             :             }
     931             : 
     932           4 :             if (eRWFlag == GF_Write)
     933             :             {
     934             :                 // copy the application supplied ints to strings
     935           6 :                 for (int i = 0; i < iLength; i++)
     936             :                 {
     937           3 :                     osWorkingResult.Printf("%d", pnData[i]);
     938           3 :                     papszColData[i] = CPLStrdup(osWorkingResult);
     939             :                 }
     940             :             }
     941             : 
     942             :             // do the ValuesIO as strings
     943             :             CPLErr eVal =
     944           4 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, papszColData);
     945           4 :             if (eVal != CE_None)
     946             :             {
     947           0 :                 if (eRWFlag == GF_Write)
     948             :                 {
     949           0 :                     for (int i = 0; i < iLength; i++)
     950           0 :                         CPLFree(papszColData[i]);
     951             :                 }
     952           0 :                 CPLFree(papszColData);
     953           0 :                 return eVal;
     954             :             }
     955             : 
     956           4 :             if (eRWFlag == GF_Read)
     957             :             {
     958             :                 // copy them back to ints
     959           2 :                 for (int i = 0; i < iLength; i++)
     960           1 :                     pnData[i] = atoi(papszColData[i]);
     961             :             }
     962             : 
     963             :             // either we allocated them for write, or they were allocated
     964             :             // by ValuesIO on read
     965           8 :             for (int i = 0; i < iLength; i++)
     966           4 :                 CPLFree(papszColData[i]);
     967             : 
     968           4 :             CPLFree(papszColData);
     969             :         }
     970           4 :         break;
     971           0 :         default:
     972           0 :             break;
     973             :     }
     974          99 :     return CE_None;
     975             : }
     976             : 
     977          53 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
     978             :                                          int iStartRow, int iLength,
     979             :                                          char **papszStrList)
     980             : {
     981             :     /*if( ( eRWFlag == GF_Write ) && ( this->eAccess == GA_ReadOnly ) )
     982             :     {
     983             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
     984             :             "Dataset not open in update mode");
     985             :         return CE_Failure;
     986             :     }*/
     987         106 :     CPLMutexHolderD(&m_hMutex);
     988             : 
     989          53 :     if (iField < 0 || iField >= (int)m_aoFields.size())
     990             :     {
     991           3 :         CPLError(CE_Failure, CPLE_AppDefined, "iField (%d) out of range.",
     992             :                  iField);
     993             : 
     994           3 :         return CE_Failure;
     995             :     }
     996             : 
     997          50 :     if (iStartRow < 0 || (iStartRow + iLength) > (int)m_poKEATable->getSize())
     998             :     {
     999           6 :         CPLError(CE_Failure, CPLE_AppDefined,
    1000             :                  "iStartRow (%d) + iLength(%d) out of range.", iStartRow,
    1001             :                  iLength);
    1002             : 
    1003           6 :         return CE_Failure;
    1004             :     }
    1005             : 
    1006          44 :     switch (m_aoFields[iField].dataType)
    1007             :     {
    1008           3 :         case kealib::kea_att_bool:
    1009             :         {
    1010             :             // allocate space for bools
    1011             :             bool *pabColData =
    1012           3 :                 (bool *)VSI_MALLOC2_VERBOSE(iLength, sizeof(bool));
    1013           3 :             if (pabColData == nullptr)
    1014             :             {
    1015           0 :                 return CE_Failure;
    1016             :             }
    1017           3 :             if (eRWFlag == GF_Write)
    1018             :             {
    1019             :                 // convert user supplied strings to ints
    1020           6 :                 for (int i = 0; i < iLength; i++)
    1021           3 :                     pabColData[i] = CPLTestBool(papszStrList[i]);
    1022             :             }
    1023             : 
    1024             :             // call values IO to read/write ints
    1025             :             CPLErr eVal =
    1026           3 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, pabColData);
    1027           3 :             if (eVal != CE_None)
    1028             :             {
    1029           0 :                 CPLFree(pabColData);
    1030           0 :                 return eVal;
    1031             :             }
    1032             : 
    1033           3 :             if (eRWFlag == GF_Read)
    1034             :             {
    1035             :                 // convert ints back to strings
    1036           0 :                 for (int i = 0; i < iLength; i++)
    1037             :                 {
    1038           0 :                     papszStrList[i] =
    1039           0 :                         CPLStrdup(pabColData[i] ? "true" : "false");
    1040             :                 }
    1041             :             }
    1042           3 :             CPLFree(pabColData);
    1043             :         }
    1044           3 :         break;
    1045           2 :         case kealib::kea_att_int:
    1046             :         {
    1047             :             // allocate space for ints
    1048           2 :             int *panColData = (int *)VSI_MALLOC2_VERBOSE(iLength, sizeof(int));
    1049           2 :             if (panColData == nullptr)
    1050             :             {
    1051           0 :                 return CE_Failure;
    1052             :             }
    1053           2 :             if (eRWFlag == GF_Write)
    1054             :             {
    1055             :                 // convert user supplied strings to ints
    1056           2 :                 for (int i = 0; i < iLength; i++)
    1057           1 :                     panColData[i] = atoi(papszStrList[i]);
    1058             :             }
    1059             : 
    1060             :             // call values IO to read/write ints
    1061             :             CPLErr eVal =
    1062           2 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, panColData);
    1063           2 :             if (eVal != CE_None)
    1064             :             {
    1065           0 :                 CPLFree(panColData);
    1066           0 :                 return eVal;
    1067             :             }
    1068             : 
    1069           2 :             if (eRWFlag == GF_Read)
    1070             :             {
    1071             :                 // convert ints back to strings
    1072           2 :                 for (int i = 0; i < iLength; i++)
    1073             :                 {
    1074           1 :                     osWorkingResult.Printf("%d", panColData[i]);
    1075           1 :                     papszStrList[i] = CPLStrdup(osWorkingResult);
    1076             :                 }
    1077             :             }
    1078           2 :             CPLFree(panColData);
    1079             :         }
    1080           2 :         break;
    1081           7 :         case kealib::kea_att_float:
    1082             :         {
    1083             :             // allocate space for doubles
    1084             :             double *padfColData =
    1085           7 :                 (double *)VSI_MALLOC2_VERBOSE(iLength, sizeof(double));
    1086           7 :             if (padfColData == nullptr)
    1087             :             {
    1088           0 :                 return CE_Failure;
    1089             :             }
    1090             : 
    1091           7 :             if (eRWFlag == GF_Write)
    1092             :             {
    1093             :                 // convert user supplied strings to doubles
    1094           6 :                 for (int i = 0; i < iLength; i++)
    1095           3 :                     padfColData[i] = CPLAtof(papszStrList[i]);
    1096             :             }
    1097             : 
    1098             :             // call value IO to read/write doubles
    1099             :             CPLErr eVal =
    1100           7 :                 ValuesIO(eRWFlag, iField, iStartRow, iLength, padfColData);
    1101           7 :             if (eVal != CE_None)
    1102             :             {
    1103           0 :                 CPLFree(padfColData);
    1104           0 :                 return eVal;
    1105             :             }
    1106             : 
    1107           7 :             if (eRWFlag == GF_Read)
    1108             :             {
    1109             :                 // convert doubles back to strings
    1110           8 :                 for (int i = 0; i < iLength; i++)
    1111             :                 {
    1112           4 :                     osWorkingResult.Printf("%.16g", padfColData[i]);
    1113           4 :                     papszStrList[i] = CPLStrdup(osWorkingResult);
    1114             :                 }
    1115             :             }
    1116           7 :             CPLFree(padfColData);
    1117             :         }
    1118           7 :         break;
    1119          32 :         case kealib::kea_att_string:
    1120             :         {
    1121             :             try
    1122             :             {
    1123          32 :                 if (eRWFlag == GF_Read)
    1124             :                 {
    1125          28 :                     std::vector<std::string> aStrings;
    1126          14 :                     m_poKEATable->getStringFields(
    1127          14 :                         iStartRow, iLength, m_aoFields[iField].idx, &aStrings);
    1128          14 :                     for (std::vector<std::string>::size_type i = 0;
    1129          28 :                          i < aStrings.size(); i++)
    1130             :                     {
    1131             :                         // Copy using CPLStrdup so user can call CPLFree
    1132          14 :                         papszStrList[i] = CPLStrdup(aStrings[i].c_str());
    1133             :                     }
    1134             :                 }
    1135             :                 else
    1136             :                 {
    1137             :                     // need to convert to a vector first
    1138          36 :                     std::vector<std::string> aStrings;
    1139          36 :                     for (int i = 0; i < iLength; i++)
    1140             :                     {
    1141          18 :                         aStrings.push_back(papszStrList[i]);
    1142             :                     }
    1143          18 :                     m_poKEATable->setStringFields(
    1144          18 :                         iStartRow, iLength, m_aoFields[iField].idx, &aStrings);
    1145             :                 }
    1146             :             }
    1147           0 :             catch (kealib::KEAException &e)
    1148             :             {
    1149           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
    1150           0 :                          "Failed to read/write attribute table: %s", e.what());
    1151           0 :                 return CE_Failure;
    1152             :             }
    1153             :         }
    1154          32 :         break;
    1155           0 :         default:
    1156           0 :             break;
    1157             :     }
    1158          44 :     return CE_None;
    1159             : }
    1160             : 
    1161           9 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
    1162             :                                          int iStartRow, int iLength,
    1163             :                                          GDALRATDateTime *psDateTime)
    1164             : {
    1165           9 :     return ValuesIODateTimeFromIntoString(eRWFlag, iField, iStartRow, iLength,
    1166           9 :                                           psDateTime);
    1167             : }
    1168             : 
    1169           9 : CPLErr KEARasterAttributeTable::ValuesIO(GDALRWFlag eRWFlag, int iField,
    1170             :                                          int iStartRow, int iLength,
    1171             :                                          GByte **ppabyWKB, size_t *pnWKBSize)
    1172             : {
    1173           9 :     return ValuesIOWKBGeometryFromIntoString(eRWFlag, iField, iStartRow,
    1174           9 :                                              iLength, ppabyWKB, pnWKBSize);
    1175             : }
    1176             : 
    1177           0 : int KEARasterAttributeTable::ChangesAreWrittenToFile()
    1178             : {
    1179           0 :     return TRUE;
    1180             : }
    1181             : 
    1182           5 : void KEARasterAttributeTable::SetRowCount(int iCount)
    1183             : {
    1184             :     /*if( this->eAccess == GA_ReadOnly )
    1185             :     {
    1186             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
    1187             :             "Dataset not open in update mode");
    1188             :         return;
    1189             :     }*/
    1190             : 
    1191           5 :     if (iCount > (int)m_poKEATable->getSize())
    1192             :     {
    1193           3 :         m_poKEATable->addRows(iCount - m_poKEATable->getSize());
    1194             :     }
    1195             :     // can't shrink
    1196           5 : }
    1197             : 
    1198          18 : CPLErr KEARasterAttributeTable::CreateColumn(const char *pszFieldName,
    1199             :                                              GDALRATFieldType eFieldType,
    1200             :                                              GDALRATFieldUsage eFieldUsage)
    1201             : {
    1202             :     /*if( this->eAccess == GA_ReadOnly )
    1203             :     {
    1204             :         CPLError( CE_Failure, CPLE_NoWriteAccess,
    1205             :             "Dataset not open in update mode");
    1206             :         return CE_Failure;
    1207             :     }*/
    1208          36 :     CPLMutexHolderD(&m_hMutex);
    1209             : 
    1210          18 :     const char *strUsage = "Generic";
    1211          18 :     switch (eFieldUsage)
    1212             :     {
    1213           1 :         case GFU_PixelCount:
    1214           1 :             strUsage = "PixelCount";
    1215           1 :             eFieldType = GFT_Real;
    1216           1 :             break;
    1217           1 :         case GFU_Name:
    1218           1 :             strUsage = "Name";
    1219           1 :             eFieldType = GFT_String;
    1220           1 :             break;
    1221           3 :         case GFU_Red:
    1222           3 :             strUsage = "Red";
    1223           3 :             eFieldType = GFT_Integer;
    1224           3 :             break;
    1225           3 :         case GFU_Green:
    1226           3 :             strUsage = "Green";
    1227           3 :             eFieldType = GFT_Integer;
    1228           3 :             break;
    1229           3 :         case GFU_Blue:
    1230           3 :             strUsage = "Blue";
    1231           3 :             eFieldType = GFT_Integer;
    1232           3 :             break;
    1233           3 :         case GFU_Alpha:
    1234           3 :             strUsage = "Alpha";
    1235           3 :             eFieldType = GFT_Integer;
    1236           3 :             break;
    1237           4 :         default:
    1238             :             // leave as "Generic"
    1239           4 :             break;
    1240             :     }
    1241             : 
    1242             :     try
    1243             :     {
    1244          18 :         switch (eFieldType)
    1245             :         {
    1246          12 :             case GFT_Integer:
    1247          12 :                 m_poKEATable->addAttIntField(pszFieldName, 0, strUsage);
    1248          12 :                 break;
    1249             : 
    1250           1 :             case GFT_Boolean:
    1251           1 :                 m_poKEATable->addAttBoolField(pszFieldName, 0, strUsage);
    1252           1 :                 break;
    1253             : 
    1254           2 :             case GFT_Real:
    1255           2 :                 m_poKEATable->addAttFloatField(pszFieldName, 0, strUsage);
    1256           2 :                 break;
    1257             : 
    1258           3 :             case GFT_String:
    1259             :             case GFT_DateTime:
    1260             :             case GFT_WKBGeometry:
    1261           3 :                 m_poKEATable->addAttStringField(pszFieldName, "", strUsage);
    1262           3 :                 break;
    1263             :         }
    1264             : 
    1265             :         // assume we can just grab this now
    1266          18 :         m_aoFields.push_back(m_poKEATable->getField(pszFieldName));
    1267             :     }
    1268           0 :     catch (kealib::KEAException &e)
    1269             :     {
    1270           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Failed to add column: %s",
    1271           0 :                  e.what());
    1272           0 :         return CE_Failure;
    1273             :     }
    1274             : 
    1275          18 :     return CE_None;
    1276             : }
    1277             : 
    1278           0 : CPLErr KEARasterAttributeTable::SetLinearBinning(double ldfRow0Min,
    1279             :                                                  double ldfBinSize)
    1280             : {
    1281           0 :     size_t nRows = m_poKEATable->getSize();
    1282             : 
    1283           0 :     osWorkingResult.Printf("%.16g", ldfRow0Min);
    1284           0 :     m_poBand->SetMetadataItem("STATISTICS_HISTOMIN", osWorkingResult);
    1285           0 :     osWorkingResult.Printf("%.16g", (nRows - 1) * ldfBinSize + ldfRow0Min);
    1286           0 :     m_poBand->SetMetadataItem("STATISTICS_HISTOMAX", osWorkingResult);
    1287             : 
    1288             :     // STATISTICS_HISTONUMBINS now returned by metadata
    1289             : 
    1290           0 :     return CE_None;
    1291             : }
    1292             : 
    1293           0 : int KEARasterAttributeTable::GetLinearBinning(double *pdfRow0Min,
    1294             :                                               double *pdfBinSize) const
    1295             : {
    1296           0 :     const char *pszMin = m_poBand->GetMetadataItem("STATISTICS_HISTOMIN");
    1297           0 :     const char *pszMax = m_poBand->GetMetadataItem("STATISTICS_HISTOMAX");
    1298           0 :     if ((pszMin == nullptr) || (pszMax == nullptr))
    1299             :     {
    1300           0 :         return FALSE;
    1301             :     }
    1302           0 :     *pdfRow0Min = atof(pszMin);
    1303           0 :     *pdfBinSize = (atof(pszMax) - *pdfRow0Min) / (m_poKEATable->getSize() - 1);
    1304             : 
    1305           0 :     return TRUE;
    1306             : }
    1307             : 
    1308           0 : CPLXMLNode *KEARasterAttributeTable::Serialize() const
    1309             : {
    1310           0 :     const int nColCount = GetColumnCount();
    1311           0 :     if (nColCount > 0 && GetRowCount() > RAT_MAX_ELEM_FOR_CLONE / nColCount)
    1312           0 :         return nullptr;
    1313             : 
    1314           0 :     return GDALRasterAttributeTable::Serialize();
    1315             : }
    1316             : 
    1317           1 : GDALRATTableType KEARasterAttributeTable::GetTableType() const
    1318             : {
    1319           1 :     kealib::KEALayerType keaType = m_poBand->getLayerType();
    1320           1 :     if (keaType == kealib::kea_continuous)
    1321             :     {
    1322           1 :         return GRTT_ATHEMATIC;
    1323             :     }
    1324             :     else
    1325             :     {
    1326           0 :         return GRTT_THEMATIC;
    1327             :     }
    1328             : }
    1329             : 
    1330             : CPLErr
    1331           0 : KEARasterAttributeTable::SetTableType(const GDALRATTableType eInTableType)
    1332             : {
    1333           0 :     kealib::KEALayerType keaType = (eInTableType == GRTT_ATHEMATIC)
    1334           0 :                                        ? kealib::kea_continuous
    1335             :                                        : kealib::kea_thematic;
    1336             :     try
    1337             :     {
    1338           0 :         m_poBand->setLayerType(keaType);
    1339           0 :         return CE_None;
    1340             :     }
    1341           0 :     catch (const kealib::KEAIOException &)
    1342             :     {
    1343           0 :         return CE_Failure;
    1344             :     }
    1345             : }
    1346             : 
    1347           0 : void KEARasterAttributeTable::RemoveStatistics()
    1348             : {
    1349             :     // TODO ?
    1350           0 : }

Generated by: LCOV version 1.14