LCOV - code coverage report
Current view: directory - gcore - gdalnodatavaluesmaskband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 116 105 90.5 %
Date: 2010-01-09 Functions: 4 4 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdalnodatavaluesmaskband.cpp 17757 2009-10-05 17:06:20Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALNoDataValuesMaskBand, a class implementing 
       6                 :  *           a default band mask based on the NODATA_VALUES metadata item.
       7                 :  *           A pixel is considered nodata in all bands if and only if all bands
       8                 :  *           match the corresponding value in the NODATA_VALUES tuple
       9                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot ogr>
      10                 :  *
      11                 :  ******************************************************************************
      12                 :  * Copyright (c) 2008, Even Rouault
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #include "gdal_priv.h"
      34                 : 
      35                 : CPL_CVSID("$Id: gdalnodatavaluesmaskband.cpp 17757 2009-10-05 17:06:20Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                   GDALNoDataValuesMaskBand()                         */
      39                 : /************************************************************************/
      40                 : 
      41              41 : GDALNoDataValuesMaskBand::GDALNoDataValuesMaskBand( GDALDataset* poDS )
      42                 : 
      43                 : {
      44              41 :     const char* pszNoDataValues = poDS->GetMetadataItem("NODATA_VALUES");
      45              41 :     char** papszNoDataValues = CSLTokenizeStringComplex(pszNoDataValues, " ", FALSE, FALSE);
      46                 : 
      47                 :     int i;
      48              41 :     padfNodataValues = (double*)CPLMalloc(sizeof(double) * poDS->GetRasterCount());
      49             164 :     for(i=0;i<poDS->GetRasterCount();i++)
      50                 :     {
      51             123 :         padfNodataValues[i] = atof(papszNoDataValues[i]);
      52                 :     }
      53                 : 
      54              41 :     CSLDestroy(papszNoDataValues);
      55                 : 
      56              41 :     this->poDS = poDS;
      57              41 :     nBand = 0;
      58                 : 
      59              41 :     nRasterXSize = poDS->GetRasterXSize();
      60              41 :     nRasterYSize = poDS->GetRasterYSize();
      61                 : 
      62              41 :     eDataType = GDT_Byte;
      63              41 :     poDS->GetRasterBand(1)->GetBlockSize( &nBlockXSize, &nBlockYSize );
      64              41 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                    ~GDALNoDataValuesMaskBand()                       */
      68                 : /************************************************************************/
      69                 : 
      70              82 : GDALNoDataValuesMaskBand::~GDALNoDataValuesMaskBand()
      71                 : 
      72                 : {
      73              41 :     CPLFree(padfNodataValues);
      74              82 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                             IReadBlock()                             */
      78                 : /************************************************************************/
      79                 : 
      80              20 : CPLErr GDALNoDataValuesMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff,
      81                 :                                          void * pImage )
      82                 : 
      83                 : {
      84                 :     int iBand;
      85                 :     GDALDataType eWrkDT;
      86                 :   
      87                 : /* -------------------------------------------------------------------- */
      88                 : /*      Decide on a working type.                                       */
      89                 : /* -------------------------------------------------------------------- */
      90              20 :     switch( poDS->GetRasterBand(1)->GetRasterDataType() ) 
      91                 :     {
      92                 :       case GDT_Byte:
      93              12 :         eWrkDT = GDT_Byte;
      94              12 :         break;
      95                 : 
      96                 :       case GDT_UInt16:
      97                 :       case GDT_UInt32:
      98               2 :         eWrkDT = GDT_UInt32;
      99               2 :         break;
     100                 : 
     101                 :       case GDT_Int16:
     102                 :       case GDT_Int32:
     103                 :       case GDT_CInt16:
     104                 :       case GDT_CInt32:
     105               2 :         eWrkDT = GDT_Int32;
     106               2 :         break;
     107                 : 
     108                 :       case GDT_Float32:
     109                 :       case GDT_CFloat32:
     110               2 :         eWrkDT = GDT_Float32;
     111               2 :         break;
     112                 :     
     113                 :       case GDT_Float64:
     114                 :       case GDT_CFloat64:
     115               2 :         eWrkDT = GDT_Float64;
     116               2 :         break;
     117                 :     
     118                 :       default:
     119                 :         CPLAssert( FALSE );
     120               0 :         eWrkDT = GDT_Float64;
     121                 :         break;
     122                 :     }
     123                 : 
     124                 : /* -------------------------------------------------------------------- */
     125                 : /*      Read the image data.                                            */
     126                 : /* -------------------------------------------------------------------- */
     127                 :     GByte *pabySrc;
     128                 :     CPLErr eErr;
     129                 : 
     130              20 :     int nBands = poDS->GetRasterCount();
     131              20 :     pabySrc = (GByte *) VSIMalloc3( nBands * GDALGetDataTypeSize(eWrkDT)/8, nBlockXSize, nBlockYSize );
     132              20 :     if (pabySrc == NULL)
     133                 :     {
     134                 :         CPLError( CE_Failure, CPLE_OutOfMemory,
     135               0 :                   "GDALNoDataValuesMaskBand::IReadBlock: Out of memory for buffer." );
     136               0 :         return CE_Failure;
     137                 :     }
     138                 : 
     139              20 :     int nXSizeRequest = nBlockXSize;
     140              20 :     if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize)
     141               0 :         nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize;
     142              20 :     int nYSizeRequest = nBlockYSize;
     143              20 :     if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize)
     144               0 :         nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize;
     145                 : 
     146              20 :     if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize)
     147                 :     {
     148                 :         /* memset the whole buffer to avoid Valgrind warnings in case we can't */
     149                 :         /* fetch a full block */
     150               0 :         memset(pabySrc, 0, nBands * GDALGetDataTypeSize(eWrkDT)/8 * nBlockXSize * nBlockYSize );
     151                 :     }
     152                 : 
     153              20 :     int nBlockOffsetPixels = nBlockXSize * nBlockYSize;
     154              20 :     int nBandOffsetByte = (GDALGetDataTypeSize(eWrkDT)/8) * nBlockXSize * nBlockYSize;
     155              80 :     for(iBand=0;iBand<nBands;iBand++)
     156                 :     {
     157                 :         eErr = poDS->GetRasterBand(iBand + 1)->RasterIO(
     158                 :                                    GF_Read,
     159                 :                                    nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize,
     160                 :                                    nXSizeRequest, nYSizeRequest,
     161                 :                                    pabySrc + iBand * nBandOffsetByte, nXSizeRequest, nYSizeRequest,
     162              60 :                                    eWrkDT, 0, nBlockXSize * (GDALGetDataTypeSize(eWrkDT)/8) );
     163              60 :         if( eErr != CE_None )
     164               0 :             return eErr;
     165                 :     }
     166                 : 
     167                 : /* -------------------------------------------------------------------- */
     168                 : /*      Process different cases.                                        */
     169                 : /* -------------------------------------------------------------------- */
     170                 :     int i;
     171              20 :     switch( eWrkDT )
     172                 :     {
     173                 :       case GDT_Byte:
     174                 :       {
     175              12 :           GByte* pabyNoData = (GByte*) CPLMalloc(nBands * sizeof(GByte));
     176              48 :           for(iBand=0;iBand<nBands;iBand++)
     177                 :           {
     178              36 :               pabyNoData[iBand] = (GByte)padfNodataValues[iBand];
     179                 :           }
     180                 : 
     181           27513 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     182                 :           {
     183           27501 :               int nCountNoData = 0;
     184          110004 :               for(iBand=0;iBand<nBands;iBand++)
     185                 :               {
     186           82503 :                   if( pabySrc[i + iBand * nBlockOffsetPixels] == pabyNoData[iBand] )
     187           62703 :                       nCountNoData ++;
     188                 :               }
     189           27501 :               if (nCountNoData == nBands)
     190           17601 :                   ((GByte *) pImage)[i] = 0;
     191                 :               else
     192            9900 :                   ((GByte *) pImage)[i] = 255;
     193                 :           }
     194                 : 
     195              12 :           CPLFree(pabyNoData);
     196                 :       }
     197              12 :       break;
     198                 : 
     199                 :       case GDT_UInt32:
     200                 :       {
     201               2 :           GUInt32* panNoData = (GUInt32*) CPLMalloc(nBands * sizeof(GUInt32));
     202               8 :           for(iBand=0;iBand<nBands;iBand++)
     203                 :           {
     204               6 :               panNoData[iBand] = (GUInt32)padfNodataValues[iBand];
     205                 :           }
     206                 : 
     207               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     208                 :           {
     209               2 :               int nCountNoData = 0;
     210               8 :               for(iBand=0;iBand<nBands;iBand++)
     211                 :               {
     212               6 :                   if( ((GUInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] )
     213               6 :                       nCountNoData ++;
     214                 :               }
     215               2 :               if (nCountNoData == nBands)
     216               2 :                   ((GByte *) pImage)[i] = 0;
     217                 :               else
     218               0 :                   ((GByte *) pImage)[i] = 255;
     219                 :           }
     220                 : 
     221               2 :           CPLFree(panNoData);
     222                 :       }
     223               2 :       break;
     224                 : 
     225                 :       case GDT_Int32:
     226                 :       {
     227               2 :           GInt32* panNoData = (GInt32*) CPLMalloc(nBands * sizeof(GInt32));
     228               8 :           for(iBand=0;iBand<nBands;iBand++)
     229                 :           {
     230               6 :               panNoData[iBand] = (GInt32)padfNodataValues[iBand];
     231                 :           }
     232                 : 
     233               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     234                 :           {
     235               2 :               int nCountNoData = 0;
     236               8 :               for(iBand=0;iBand<nBands;iBand++)
     237                 :               {
     238               6 :                   if( ((GInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] )
     239               6 :                       nCountNoData ++;
     240                 :               }
     241               2 :               if (nCountNoData == nBands)
     242               2 :                   ((GByte *) pImage)[i] = 0;
     243                 :               else
     244               0 :                   ((GByte *) pImage)[i] = 255;
     245                 :           }
     246                 : 
     247               2 :           CPLFree(panNoData);
     248                 :       }
     249               2 :       break;
     250                 : 
     251                 :       case GDT_Float32:
     252                 :       {
     253               2 :           float* pafNoData = (float*) CPLMalloc(nBands * sizeof(float));
     254               8 :           for(iBand=0;iBand<nBands;iBand++)
     255                 :           {
     256               6 :               pafNoData[iBand] = (float)padfNodataValues[iBand];
     257                 :           }
     258                 : 
     259               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     260                 :           {
     261               2 :               int nCountNoData = 0;
     262               8 :               for(iBand=0;iBand<nBands;iBand++)
     263                 :               {
     264               6 :                   if( ((float *)pabySrc)[i + iBand * nBlockOffsetPixels] == pafNoData[iBand] )
     265               6 :                       nCountNoData ++;
     266                 :               }
     267               2 :               if (nCountNoData == nBands)
     268               2 :                   ((GByte *) pImage)[i] = 0;
     269                 :               else
     270               0 :                   ((GByte *) pImage)[i] = 255;
     271                 :           }
     272                 : 
     273               2 :           CPLFree(pafNoData);
     274                 :       }
     275               2 :       break;
     276                 : 
     277                 :       case GDT_Float64:
     278                 :       {
     279               2 :           double* padfNoData = (double*) CPLMalloc(nBands * sizeof(double));
     280               8 :           for(iBand=0;iBand<nBands;iBand++)
     281                 :           {
     282               6 :               padfNoData[iBand] = (double)padfNodataValues[iBand];
     283                 :           }
     284                 : 
     285               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     286                 :           {
     287               2 :               int nCountNoData = 0;
     288               8 :               for(iBand=0;iBand<nBands;iBand++)
     289                 :               {
     290               6 :                   if( ((double *)pabySrc)[i + iBand * nBlockOffsetPixels] == padfNoData[iBand] )
     291               6 :                       nCountNoData ++;
     292                 :               }
     293               2 :               if (nCountNoData == nBands)
     294               2 :                   ((GByte *) pImage)[i] = 0;
     295                 :               else
     296               0 :                   ((GByte *) pImage)[i] = 255;
     297                 :           }
     298                 : 
     299               2 :           CPLFree(padfNoData);
     300                 :       }
     301                 :       break;
     302                 : 
     303                 :       default:
     304                 :         CPLAssert( FALSE );
     305                 :         break;
     306                 :     }
     307                 : 
     308              20 :     CPLFree( pabySrc );
     309                 : 
     310              20 :     return CE_None;
     311                 : }

Generated by: LCOV version 1.7