LCOV - code coverage report
Current view: directory - gcore - gdalcolortable.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 79 71 89.9 %
Date: 2010-01-09 Functions: 18 18 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdalcolortable.cpp 16573 2009-03-14 12:34:17Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Color table implementation.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  **********************************************************************
       9                 :  * Copyright (c) 2000, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_priv.h"
      31                 : 
      32                 : CPL_CVSID("$Id: gdalcolortable.cpp 16573 2009-03-14 12:34:17Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                           GDALColorTable()                           */
      36                 : /************************************************************************/
      37                 : 
      38                 : /**
      39                 :  * \brief Construct a new color table.
      40                 :  *
      41                 :  * This constructor is the same as the C GDALCreateColorTable() function.
      42                 :  *
      43                 :  * @param eInterpIn the interpretation to be applied to GDALColorEntry
      44                 :  * values. 
      45                 :  */
      46                 : 
      47             365 : GDALColorTable::GDALColorTable( GDALPaletteInterp eInterpIn )
      48                 : 
      49                 : {
      50             365 :     eInterp = eInterpIn;
      51             365 : }
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                        GDALCreateColorTable()                        */
      55                 : /************************************************************************/
      56                 : 
      57                 : /**
      58                 :  * \brief Construct a new color table.
      59                 :  *
      60                 :  * This function is the same as the C++ method GDALColorTable::GDALColorTable()
      61                 :  */
      62              14 : GDALColorTableH CPL_STDCALL GDALCreateColorTable( GDALPaletteInterp eInterp )
      63                 : 
      64                 : {
      65              14 :     return (GDALColorTableH) (new GDALColorTable( eInterp ));
      66                 : }
      67                 : 
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                          ~GDALColorTable()                           */
      71                 : /************************************************************************/
      72                 : 
      73                 : /**
      74                 :  * \brief Destructor.
      75                 :  *
      76                 :  * This descructor is the same as the C GDALDestroyColorTable() function.
      77                 :  */
      78                 : 
      79            2013 : GDALColorTable::~GDALColorTable()
      80                 : 
      81                 : {
      82            2013 : }
      83                 : 
      84                 : /************************************************************************/
      85                 : /*                       GDALDestroyColorTable()                        */
      86                 : /************************************************************************/
      87                 : 
      88                 : /**
      89                 :  * \brief Destroys a color table.
      90                 :  *
      91                 :  * This function is the same as the C++ method GDALColorTable::~GDALColorTable()
      92                 :  */
      93              27 : void CPL_STDCALL GDALDestroyColorTable( GDALColorTableH hTable )
      94                 : 
      95                 : {
      96              27 :     delete (GDALColorTable *) hTable;
      97              27 : }
      98                 : 
      99                 : /************************************************************************/
     100                 : /*                           GetColorEntry()                            */
     101                 : /************************************************************************/
     102                 : 
     103                 : /**
     104                 :  * \brief Fetch a color entry from table.
     105                 :  *
     106                 :  * This method is the same as the C function GDALGetColorEntry().
     107                 :  *
     108                 :  * @param i entry offset from zero to GetColorEntryCount()-1.
     109                 :  *
     110                 :  * @return pointer to internal color entry, or NULL if index is out of range.
     111                 :  */
     112                 : 
     113         1125128 : const GDALColorEntry *GDALColorTable::GetColorEntry( int i ) const
     114                 : 
     115                 : {
     116         1125128 :     if( i < 0 || i >= static_cast<int>(aoEntries.size()) )
     117               0 :         return NULL;
     118                 :     else
     119         1125128 :         return &aoEntries[i];
     120                 : }
     121                 : 
     122                 : /************************************************************************/
     123                 : /*                         GDALGetColorEntry()                          */
     124                 : /************************************************************************/
     125                 : 
     126                 : 
     127                 : /**
     128                 :  * \brief Fetch a color entry from table.
     129                 :  *
     130                 :  * This function is the same as the C++ method GDALColorTable::GetColorEntry()
     131                 :  */
     132                 : const GDALColorEntry * CPL_STDCALL 
     133              48 : GDALGetColorEntry( GDALColorTableH hTable, int i )
     134                 : 
     135                 : {
     136              48 :     VALIDATE_POINTER1( hTable, "GDALGetColorEntry", NULL );
     137                 : 
     138              48 :     return ((GDALColorTable *) hTable)->GetColorEntry( i );
     139                 : }
     140                 : 
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                         GetColorEntryAsRGB()                         */
     144                 : /************************************************************************/
     145                 : 
     146                 : /**
     147                 :  * \brief Fetch a table entry in RGB format.
     148                 :  *
     149                 :  * In theory this method should support translation of color palettes in
     150                 :  * non-RGB color spaces into RGB on the fly, but currently it only works
     151                 :  * on RGB color tables.
     152                 :  *
     153                 :  * This method is the same as the C function GDALGetColorEntryAsRGB().
     154                 :  *
     155                 :  * @param i entry offset from zero to GetColorEntryCount()-1.
     156                 :  *
     157                 :  * @param poEntry the existing GDALColorEntry to be overrwritten with the RGB
     158                 :  * values.
     159                 :  *
     160                 :  * @return TRUE on success, or FALSE if the conversion isn't supported.
     161                 :  */
     162                 : 
     163           71123 : int GDALColorTable::GetColorEntryAsRGB( int i, GDALColorEntry *poEntry ) const
     164                 : 
     165                 : {
     166           71123 :     if( eInterp != GPI_RGB || i < 0 || i >= static_cast<int>(aoEntries.size()) )
     167               0 :         return FALSE;
     168                 :     
     169           71123 :     *poEntry = aoEntries[i];
     170           71123 :     return TRUE;
     171                 : }
     172                 : 
     173                 : /************************************************************************/
     174                 : /*                       GDALGetColorEntryAsRGB()                       */
     175                 : /************************************************************************/
     176                 : 
     177                 : /**
     178                 :  * \brief Fetch a table entry in RGB format.
     179                 :  *
     180                 :  * This function is the same as the C++ method GDALColorTable::GetColorEntryAsRGB()
     181                 :  */
     182              24 : int CPL_STDCALL GDALGetColorEntryAsRGB( GDALColorTableH hTable, int i, 
     183                 :                             GDALColorEntry *poEntry )
     184                 : 
     185                 : {
     186              24 :     VALIDATE_POINTER1( hTable, "GDALGetColorEntryAsRGB", 0 );
     187              24 :     VALIDATE_POINTER1( poEntry, "GDALGetColorEntryAsRGB", 0 );
     188                 : 
     189              24 :     return ((GDALColorTable *) hTable)->GetColorEntryAsRGB( i, poEntry );
     190                 : }
     191                 : 
     192                 : /************************************************************************/
     193                 : /*                           SetColorEntry()                            */
     194                 : /************************************************************************/
     195                 : 
     196                 : /**
     197                 :  * \brief Set entry in color table.
     198                 :  *
     199                 :  * Note that the passed in color entry is copied, and no internal reference
     200                 :  * to it is maintained.  Also, the passed in entry must match the color
     201                 :  * interpretation of the table to which it is being assigned.
     202                 :  *
     203                 :  * The table is grown as needed to hold the supplied offset.  
     204                 :  *
     205                 :  * This function is the same as the C function GDALSetColorEntry().
     206                 :  *
     207                 :  * @param i entry offset from zero to GetColorEntryCount()-1.
     208                 :  * @param poEntry value to assign to table.
     209                 :  */
     210                 : 
     211          361408 : void GDALColorTable::SetColorEntry( int i, const GDALColorEntry * poEntry )
     212                 : 
     213                 : {
     214          361408 :     if( i < 0 )
     215               0 :         return;
     216                 :     
     217                 :     try
     218                 :     {
     219          361408 :         if( i >= static_cast<int>(aoEntries.size()) )
     220                 :         {
     221                 :             GDALColorEntry oBlack;
     222           20113 :             oBlack.c1 = oBlack.c2 = oBlack.c3 = oBlack.c4 = 0;
     223           20113 :             aoEntries.resize(i+1, oBlack);
     224                 :         }
     225                 :     
     226          361408 :         aoEntries[i] = *poEntry;
     227                 :     }
     228               0 :     catch(std::exception &e)
     229                 :     {
     230               0 :         CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
     231                 :     }
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                         GDALSetColorEntry()                          */
     236                 : /************************************************************************/
     237                 : 
     238                 : /**
     239                 :  * \brief Set entry in color table.
     240                 :  *
     241                 :  * This function is the same as the C++ method GDALColorTable::SetColorEntry()
     242                 :  */
     243              51 : void CPL_STDCALL GDALSetColorEntry( GDALColorTableH hTable, int i, 
     244                 :                         const GDALColorEntry * poEntry )
     245                 : 
     246                 : {
     247              51 :     VALIDATE_POINTER0( hTable, "GDALSetColorEntry" );
     248              51 :     VALIDATE_POINTER0( poEntry, "GDALSetColorEntry" );
     249                 : 
     250              51 :     ((GDALColorTable *) hTable)->SetColorEntry( i, poEntry );
     251                 : }
     252                 : 
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                               Clone()                                */
     256                 : /************************************************************************/
     257                 : 
     258                 : /**
     259                 :  * \brief Make a copy of a color table.
     260                 :  *
     261                 :  * This method is the same as the C function GDALCloneColorTable().
     262                 :  */
     263                 : 
     264            1649 : GDALColorTable *GDALColorTable::Clone() const
     265                 : 
     266                 : {
     267            1649 :   return new GDALColorTable(*this);
     268                 : }
     269                 : 
     270                 : /************************************************************************/
     271                 : /*                        GDALCloneColorTable()                         */
     272                 : /************************************************************************/
     273                 : 
     274                 : /**
     275                 :  * \brief Make a copy of a color table.
     276                 :  *
     277                 :  * This function is the same as the C++ method GDALColorTable::Clone()
     278                 :  */
     279               1 : GDALColorTableH CPL_STDCALL GDALCloneColorTable( GDALColorTableH hTable )
     280                 : 
     281                 : {
     282               1 :     VALIDATE_POINTER1( hTable, "GDALCloneColorTable", NULL );
     283                 : 
     284               1 :     return (GDALColorTableH) ((GDALColorTable *) hTable)->Clone();
     285                 : }
     286                 : 
     287                 : /************************************************************************/
     288                 : /*                         GetColorEntryCount()                         */
     289                 : /************************************************************************/
     290                 : 
     291                 : /**
     292                 :  * \brief Get number of color entries in table.
     293                 :  *
     294                 :  * This method is the same as the function GDALGetColorEntryCount().
     295                 :  *
     296                 :  * @return the number of color entries.
     297                 :  */
     298                 : 
     299          136113 : int GDALColorTable::GetColorEntryCount() const
     300                 : 
     301                 : {
     302          136113 :     return aoEntries.size();
     303                 : }
     304                 : 
     305                 : /************************************************************************/
     306                 : /*                       GDALGetColorEntryCount()                       */
     307                 : /************************************************************************/
     308                 : 
     309                 : /**
     310                 :  * \brief Get number of color entries in table.
     311                 :  *
     312                 :  * This function is the same as the C++ method GDALColorTable::GetColorEntryCount()
     313                 :  */
     314              34 : int CPL_STDCALL GDALGetColorEntryCount( GDALColorTableH hTable )
     315                 : 
     316                 : {
     317              34 :     VALIDATE_POINTER1( hTable, "GDALGetColorEntryCount", 0 );
     318                 : 
     319              34 :     return ((GDALColorTable *) hTable)->GetColorEntryCount();
     320                 : }
     321                 : 
     322                 : /************************************************************************/
     323                 : /*                      GetPaletteInterpretation()                      */
     324                 : /************************************************************************/
     325                 : 
     326                 : /**
     327                 :  * \brief Fetch palette interpretation.
     328                 :  *
     329                 :  * The returned value is used to interprete the values in the GDALColorEntry.
     330                 :  *
     331                 :  * This method is the same as the C function GDALGetPaletteInterpretation().
     332                 :  *
     333                 :  * @return palette interpretation enumeration value, usually GPI_RGB.
     334                 :  */
     335                 : 
     336               8 : GDALPaletteInterp GDALColorTable::GetPaletteInterpretation() const
     337                 : 
     338                 : {
     339               8 :     return eInterp;
     340                 : }
     341                 : 
     342                 : /************************************************************************/
     343                 : /*                    GDALGetPaltteInterpretation()                     */
     344                 : /************************************************************************/
     345                 : 
     346                 : /**
     347                 :  * \brief Fetch palette interpretation.
     348                 :  *
     349                 :  * This function is the same as the C++ method GDALColorTable::GetPaletteInterpretation()
     350                 :  */
     351                 : GDALPaletteInterp CPL_STDCALL 
     352               2 : GDALGetPaletteInterpretation( GDALColorTableH hTable )
     353                 : 
     354                 : {
     355               2 :     VALIDATE_POINTER1( hTable, "GDALGetPaletteInterpretation", GPI_Gray );
     356                 : 
     357               2 :     return ((GDALColorTable *) hTable)->GetPaletteInterpretation();
     358                 : }
     359                 : 
     360                 : /**
     361                 :  * \brief Create color ramp
     362                 :  *
     363                 :  * Automatically creates a color ramp from one color entry to
     364                 :  * another. It can be called several times to create multiples ramps
     365                 :  * in the same color table.
     366                 :  *
     367                 :  * This function is the same as the C function GDALCreateColorRamp().
     368                 :  *
     369                 :  * @param nStartIndex index to start the ramp on the color table [0..255]
     370                 :  * @param psStartColor a color entry value to start the ramp
     371                 :  * @param nEndIndex index to end the ramp on the color table [0..255]
     372                 :  * @param psEndColor a color entry value to end the ramp
     373                 :  * @return total number of entries, -1 to report error
     374                 :  */
     375                 : 
     376               1 : int GDALColorTable::CreateColorRamp(
     377                 :             int nStartIndex, const GDALColorEntry *psStartColor,
     378                 :             int nEndIndex, const GDALColorEntry *psEndColor )
     379                 : {
     380                 :     /* validate indexes */
     381                 : 
     382               1 :     if( nStartIndex < 0 || nStartIndex > 255 ||
     383                 :         nEndIndex < 0 || nEndIndex > 255 ||
     384                 :         nStartIndex > nEndIndex )
     385                 :     {
     386               0 :         return -1;
     387                 :     }
     388                 : 
     389                 :     /* validate color entries */
     390                 : 
     391               1 :     if( psStartColor == NULL || psEndColor == NULL )
     392                 :     {
     393               0 :         return -1;
     394                 :     }
     395                 : 
     396                 :     /* calculate number of colors in-between */
     397                 : 
     398               1 :     int nColors = nEndIndex - nStartIndex;
     399                 : 
     400                 :     /* set starting color */
     401                 : 
     402               1 :     SetColorEntry( nStartIndex, psStartColor );
     403                 : 
     404               1 :     if( nColors == 0 )
     405                 :     {
     406               0 :         return GetColorEntryCount(); /* it should not proceed */
     407                 :     }
     408                 : 
     409                 :     /* set ending color */
     410                 : 
     411               1 :     SetColorEntry( nEndIndex, psEndColor );
     412                 : 
     413                 :     /* calculate the slope of the linear transformation */
     414                 : 
     415                 :     double dfSlope1, dfSlope2, dfSlope3, dfSlope4;
     416                 : 
     417               1 :     dfSlope1 = ( psEndColor->c1 - psStartColor->c1 ) / (double) nColors;
     418               1 :     dfSlope2 = ( psEndColor->c2 - psStartColor->c2 ) / (double) nColors;
     419               1 :     dfSlope3 = ( psEndColor->c3 - psStartColor->c3 ) / (double) nColors;
     420               1 :     dfSlope4 = ( psEndColor->c4 - psStartColor->c4 ) / (double) nColors;
     421                 : 
     422                 :     /* loop through the new colors */
     423                 : 
     424               1 :     GDALColorEntry sColor = *psStartColor;
     425                 : 
     426                 :     int i;
     427                 : 
     428             255 :     for( i = 1; i < nColors; i++ )
     429                 :     {
     430             254 :         sColor.c1 = (short) ( i * dfSlope1 + (double) psStartColor->c1 );
     431             254 :         sColor.c2 = (short) ( i * dfSlope2 + (double) psStartColor->c2 );
     432             254 :         sColor.c3 = (short) ( i * dfSlope3 + (double) psStartColor->c3 );
     433             254 :         sColor.c4 = (short) ( i * dfSlope4 + (double) psStartColor->c4 );
     434                 : 
     435             254 :         SetColorEntry( nStartIndex + i, &sColor );
     436                 :     }
     437                 : 
     438                 :     /* return the total number of colors */
     439                 : 
     440               1 :     return GetColorEntryCount();
     441                 : }
     442                 : 
     443                 : /************************************************************************/
     444                 : /*                         GDALCreateColorRamp()                        */
     445                 : /************************************************************************/
     446                 : 
     447                 : /**
     448                 :  * \brief Create color ramp
     449                 :  *
     450                 :  * This function is the same as the C++ method GDALColorTable::CreateColorRamp()
     451                 :  */
     452                 : void CPL_STDCALL 
     453               1 : GDALCreateColorRamp( GDALColorTableH hTable, 
     454                 :             int nStartIndex, const GDALColorEntry *psStartColor,
     455                 :             int nEndIndex, const GDALColorEntry *psEndColor )
     456                 : {
     457               1 :     VALIDATE_POINTER0( hTable, "GDALCreateColorRamp" );
     458                 : 
     459                 :     ((GDALColorTable *) hTable)->CreateColorRamp( nStartIndex, psStartColor, 
     460               1 :                                                   nEndIndex, psEndColor );
     461                 : }

Generated by: LCOV version 1.7