LCOV - code coverage report
Current view: directory - gcore - gdalnodatamaskband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 95 79 83.2 %
Date: 2012-12-26 Functions: 7 4 57.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdalnodatamaskband.cpp 24299 2012-04-23 21:16:42Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALNoDataMaskBand, a class implementing all
       6                 :  *           a default band mask based on nodata values.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2007, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "gdal_priv.h"
      32                 : 
      33                 : CPL_CVSID("$Id: gdalnodatamaskband.cpp 24299 2012-04-23 21:16:42Z rouault $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                        GDALNoDataMaskBand()                          */
      37                 : /************************************************************************/
      38                 : 
      39             104 : GDALNoDataMaskBand::GDALNoDataMaskBand( GDALRasterBand *poParent )
      40                 : 
      41                 : {
      42             104 :     poDS = NULL;
      43             104 :     nBand = 0;
      44                 : 
      45             104 :     nRasterXSize = poParent->GetXSize();
      46             104 :     nRasterYSize = poParent->GetYSize();
      47                 : 
      48             104 :     eDataType = GDT_Byte;
      49             104 :     poParent->GetBlockSize( &nBlockXSize, &nBlockYSize );
      50                 : 
      51             104 :     this->poParent = poParent;
      52             104 :     dfNoDataValue = poParent->GetNoDataValue();
      53             104 : }
      54                 : 
      55                 : /************************************************************************/
      56                 : /*                       ~GDALNoDataMaskBand()                          */
      57                 : /************************************************************************/
      58                 : 
      59             104 : GDALNoDataMaskBand::~GDALNoDataMaskBand()
      60                 : 
      61                 : {
      62             104 : }
      63                 : 
      64                 : /************************************************************************/
      65                 : /*                             IReadBlock()                             */
      66                 : /************************************************************************/
      67                 : 
      68              24 : CPLErr GDALNoDataMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff,
      69                 :                                          void * pImage )
      70                 : 
      71                 : {
      72                 :     GDALDataType eWrkDT;
      73                 :   
      74                 : /* -------------------------------------------------------------------- */
      75                 : /*      Decide on a working type.                                       */
      76                 : /* -------------------------------------------------------------------- */
      77              24 :     switch( poParent->GetRasterDataType() ) 
      78                 :     {
      79                 :       case GDT_Byte:
      80               2 :         eWrkDT = GDT_Byte;
      81               2 :         break;
      82                 : 
      83                 :       case GDT_UInt16:
      84                 :       case GDT_UInt32:
      85               2 :         eWrkDT = GDT_UInt32;
      86               2 :         break;
      87                 : 
      88                 :       case GDT_Int16:
      89                 :       case GDT_Int32:
      90                 :       case GDT_CInt16:
      91                 :       case GDT_CInt32:
      92              16 :         eWrkDT = GDT_Int32;
      93              16 :         break;
      94                 : 
      95                 :       case GDT_Float32:
      96                 :       case GDT_CFloat32:
      97               2 :         eWrkDT = GDT_Float32;
      98               2 :         break;
      99                 :     
     100                 :       case GDT_Float64:
     101                 :       case GDT_CFloat64:
     102               2 :         eWrkDT = GDT_Float64;
     103               2 :         break;
     104                 :     
     105                 :       default:
     106               0 :         CPLAssert( FALSE );
     107               0 :         eWrkDT = GDT_Float64;
     108                 :         break;
     109                 :     }
     110                 : 
     111                 : /* -------------------------------------------------------------------- */
     112                 : /*      Read the image data.                                            */
     113                 : /* -------------------------------------------------------------------- */
     114                 :     GByte *pabySrc;
     115                 :     CPLErr eErr;
     116                 : 
     117              24 :     pabySrc = (GByte *) VSIMalloc3( GDALGetDataTypeSize(eWrkDT)/8, nBlockXSize, nBlockYSize );
     118              24 :     if (pabySrc == NULL)
     119                 :     {
     120                 :         CPLError( CE_Failure, CPLE_OutOfMemory,
     121               0 :                   "GDALNoDataMaskBand::IReadBlock: Out of memory for buffer." );
     122               0 :         return CE_Failure;
     123                 :     }
     124                 : 
     125                 : 
     126              24 :     int nXSizeRequest = nBlockXSize;
     127              24 :     if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize)
     128               0 :         nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize;
     129              24 :     int nYSizeRequest = nBlockYSize;
     130              24 :     if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize)
     131               0 :         nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize;
     132                 : 
     133              24 :     if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize)
     134                 :     {
     135                 :         /* memset the whole buffer to avoid Valgrind warnings in case we can't */
     136                 :         /* fetch a full block */
     137               0 :         memset(pabySrc, 0, GDALGetDataTypeSize(eWrkDT)/8 * nBlockXSize * nBlockYSize );
     138                 :     }
     139                 : 
     140                 :     eErr = poParent->RasterIO( GF_Read,
     141                 :                                nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize,
     142                 :                                nXSizeRequest, nYSizeRequest,
     143                 :                                pabySrc, nXSizeRequest, nYSizeRequest,
     144              24 :                                eWrkDT, 0, nBlockXSize * (GDALGetDataTypeSize(eWrkDT)/8) );
     145              24 :     if( eErr != CE_None )
     146                 :     {
     147               0 :         CPLFree(pabySrc);
     148               0 :         return eErr;
     149                 :     }
     150                 : 
     151              24 :     int bIsNoDataNan = CPLIsNan(dfNoDataValue);
     152                 : 
     153                 : /* -------------------------------------------------------------------- */
     154                 : /*      Process different cases.                                        */
     155                 : /* -------------------------------------------------------------------- */
     156                 :     int i;
     157              24 :     switch( eWrkDT )
     158                 :     {
     159                 :       case GDT_Byte:
     160                 :       {
     161               2 :           GByte byNoData = (GByte) dfNoDataValue;
     162                 : 
     163             403 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     164                 :           {
     165             401 :               if( pabySrc[i] == byNoData )
     166              58 :                   ((GByte *) pImage)[i] = 0;
     167                 :               else
     168             343 :                   ((GByte *) pImage)[i] = 255;
     169                 :           }
     170                 :       }
     171               2 :       break;
     172                 : 
     173                 :       case GDT_UInt32:
     174                 :       {
     175               2 :           GUInt32 nNoData = (GUInt32) dfNoDataValue;
     176                 : 
     177               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     178                 :           {
     179               2 :               if( ((GUInt32 *)pabySrc)[i] == nNoData )
     180               2 :                   ((GByte *) pImage)[i] = 0;
     181                 :               else
     182               0 :                   ((GByte *) pImage)[i] = 255;
     183                 :           }
     184                 :       }
     185               2 :       break;
     186                 : 
     187                 :       case GDT_Int32:
     188                 :       {
     189              16 :           GInt32 nNoData = (GInt32) dfNoDataValue;
     190                 : 
     191              88 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     192                 :           {
     193              72 :               if( ((GInt32 *)pabySrc)[i] == nNoData )
     194              18 :                   ((GByte *) pImage)[i] = 0;
     195                 :               else
     196              54 :                   ((GByte *) pImage)[i] = 255;
     197                 :           }
     198                 :       }
     199              16 :       break;
     200                 : 
     201                 :       case GDT_Float32:
     202                 :       {
     203               2 :           float fNoData = (float) dfNoDataValue;
     204                 : 
     205               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     206                 :           {
     207               2 :               float fVal =((float *)pabySrc)[i];
     208               2 :               if( bIsNoDataNan && CPLIsNan(fVal))
     209               0 :                   ((GByte *) pImage)[i] = 0;
     210               4 :               else if( ARE_REAL_EQUAL(fVal, fNoData) )
     211               2 :                   ((GByte *) pImage)[i] = 0;
     212                 :               else
     213               0 :                   ((GByte *) pImage)[i] = 255;
     214                 :           }
     215                 :       }
     216               2 :       break;
     217                 : 
     218                 :       case GDT_Float64:
     219                 :       {
     220               4 :           for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- )
     221                 :           {
     222               2 :               double dfVal =((double *)pabySrc)[i];
     223               2 :               if( bIsNoDataNan && CPLIsNan(dfVal))
     224               0 :                   ((GByte *) pImage)[i] = 0;
     225               4 :               else if( ARE_REAL_EQUAL(dfVal, dfNoDataValue) )
     226               2 :                   ((GByte *) pImage)[i] = 0;
     227                 :               else
     228               0 :                   ((GByte *) pImage)[i] = 255;
     229                 :           }
     230                 :       }
     231               2 :       break;
     232                 : 
     233                 :       default:
     234               0 :         CPLAssert( FALSE );
     235                 :         break;
     236                 :     }
     237                 : 
     238              24 :     CPLFree( pabySrc );
     239                 : 
     240              24 :     return CE_None;
     241                 : }
     242                 : 
     243                 : /************************************************************************/
     244                 : /*                             IRasterIO()                              */
     245                 : /************************************************************************/
     246                 : 
     247              62 : CPLErr GDALNoDataMaskBand::IRasterIO( GDALRWFlag eRWFlag,
     248                 :                                       int nXOff, int nYOff, int nXSize, int nYSize,
     249                 :                                       void * pData, int nBufXSize, int nBufYSize,
     250                 :                                       GDALDataType eBufType,
     251                 :                                       int nPixelSpace, int nLineSpace )
     252                 : {
     253                 :     /* Optimization in common use case (#4488) */
     254                 :     /* This avoids triggering the block cache on this band, which helps */
     255                 :     /* reducing the global block cache consumption */
     256              62 :     if (eRWFlag == GF_Read && eBufType == GDT_Byte &&
     257                 :         poParent->GetRasterDataType() == GDT_Byte &&
     258                 :         nXSize == nBufXSize && nYSize == nBufYSize &&
     259                 :         nPixelSpace == 1 && nLineSpace == nBufXSize)
     260                 :     {
     261                 :         CPLErr eErr = poParent->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize,
     262                 :                                           pData, nBufXSize, nBufYSize,
     263                 :                                           eBufType,
     264               5 :                                           nPixelSpace, nLineSpace );
     265               5 :         if (eErr != CE_None)
     266               0 :             return eErr;
     267                 : 
     268               5 :         GByte* pabyData = (GByte*) pData;
     269               5 :         GByte byNoData = (GByte) dfNoDataValue;
     270                 : 
     271            2005 :         for( int i = nBufXSize * nBufYSize - 1; i >= 0; i-- )
     272                 :         {
     273            2000 :             if( pabyData[i] == byNoData )
     274             100 :                 pabyData[i] = 0;
     275                 :             else
     276            1900 :                 pabyData[i] = 255;
     277                 :         }
     278               5 :         return CE_None;
     279                 :     }
     280                 : 
     281                 :     return GDALRasterBand::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
     282                 :                                       pData, nBufXSize, nBufYSize,
     283                 :                                       eBufType,
     284              57 :                                       nPixelSpace, nLineSpace );
     285                 : }

Generated by: LCOV version 1.7