LCOV - code coverage report
Current view: directory - frmts/vrt - vrtsourcedrasterband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 369 281 76.2 %
Date: 2011-12-18 Functions: 31 25 80.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: vrtsourcedrasterband.cpp 23574 2011-12-14 19:29:48Z rouault $
       3                 :  *
       4                 :  * Project:  Virtual GDAL Datasets
       5                 :  * Purpose:  Implementation of VRTSourcedRasterBand
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
      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 "vrtdataset.h"
      31                 : #include "cpl_minixml.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: vrtsourcedrasterband.cpp 23574 2011-12-14 19:29:48Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /* ==================================================================== */
      38                 : /*                          VRTSourcedRasterBand                        */
      39                 : /* ==================================================================== */
      40                 : /************************************************************************/
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                        VRTSourcedRasterBand()                        */
      44                 : /************************************************************************/
      45                 : 
      46             349 : VRTSourcedRasterBand::VRTSourcedRasterBand( GDALDataset *poDS, int nBand )
      47                 : 
      48                 : {
      49             349 :     Initialize( poDS->GetRasterXSize(), poDS->GetRasterYSize() );
      50                 : 
      51             349 :     this->poDS = poDS;
      52             349 :     this->nBand = nBand;
      53             349 : }
      54                 : 
      55                 : /************************************************************************/
      56                 : /*                        VRTSourcedRasterBand()                        */
      57                 : /************************************************************************/
      58                 : 
      59               0 : VRTSourcedRasterBand::VRTSourcedRasterBand( GDALDataType eType, 
      60               0 :                                             int nXSize, int nYSize )
      61                 : 
      62                 : {
      63               0 :     Initialize( nXSize, nYSize );
      64                 : 
      65               0 :     eDataType = eType;
      66               0 : }
      67                 : 
      68                 : /************************************************************************/
      69                 : /*                        VRTSourcedRasterBand()                        */
      70                 : /************************************************************************/
      71                 : 
      72             299 : VRTSourcedRasterBand::VRTSourcedRasterBand( GDALDataset *poDS, int nBand,
      73                 :                                             GDALDataType eType, 
      74             299 :                                             int nXSize, int nYSize )
      75                 : 
      76                 : {
      77             299 :     Initialize( nXSize, nYSize );
      78                 : 
      79             299 :     this->poDS = poDS;
      80             299 :     this->nBand = nBand;
      81                 : 
      82             299 :     eDataType = eType;
      83             299 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                             Initialize()                             */
      87                 : /************************************************************************/
      88                 : 
      89             648 : void VRTSourcedRasterBand::Initialize( int nXSize, int nYSize )
      90                 : 
      91                 : {
      92             648 :     VRTRasterBand::Initialize( nXSize, nYSize );
      93                 : 
      94             648 :     nSources = 0;
      95             648 :     papoSources = NULL;
      96             648 :     bEqualAreas = FALSE;
      97             648 :     bAntiRecursionFlag = FALSE;
      98             648 : }
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                       ~VRTSourcedRasterBand()                        */
     102                 : /************************************************************************/
     103                 : 
     104             648 : VRTSourcedRasterBand::~VRTSourcedRasterBand()
     105                 : 
     106                 : {
     107             648 :     CloseDependentDatasets();
     108             648 : }
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                             IRasterIO()                              */
     112                 : /************************************************************************/
     113                 : 
     114           10728 : CPLErr VRTSourcedRasterBand::IRasterIO( GDALRWFlag eRWFlag,
     115                 :                                  int nXOff, int nYOff, int nXSize, int nYSize,
     116                 :                                  void * pData, int nBufXSize, int nBufYSize,
     117                 :                                  GDALDataType eBufType,
     118                 :                                  int nPixelSpace, int nLineSpace )
     119                 : 
     120                 : {
     121                 :     int         iSource;
     122           10728 :     CPLErr      eErr = CE_None;
     123                 : 
     124           10728 :     if( eRWFlag == GF_Write )
     125                 :     {
     126                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     127               0 :                   "Writing through VRTSourcedRasterBand is not supported." );
     128               0 :         return CE_Failure;
     129                 :     }
     130                 :     
     131                 :     /* When using GDALProxyPoolDataset for sources, the recusion will not be */
     132                 :     /* detected at VRT opening but when doing RasterIO. As the proxy pool will */
     133                 :     /* return the already opened dataset, we can just test a member variable. */
     134           10728 :     if ( bAntiRecursionFlag )
     135                 :     {
     136                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     137                 :                   "VRTSourcedRasterBand::IRasterIO() called recursively on the same band. "
     138               0 :                   "It looks like the VRT is referencing itself." );
     139               0 :         return CE_Failure;
     140                 :     }
     141                 : 
     142                 : /* ==================================================================== */
     143                 : /*      Do we have overviews that would be appropriate to satisfy       */
     144                 : /*      this request?                                                   */
     145                 : /* ==================================================================== */
     146           10748 :     if( (nBufXSize < nXSize || nBufYSize < nYSize)
     147              20 :         && GetOverviewCount() > 0 )
     148                 :     {
     149               0 :         if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
     150                 :                               pData, nBufXSize, nBufYSize, 
     151                 :                               eBufType, nPixelSpace, nLineSpace ) == CE_None )
     152               0 :             return CE_None;
     153                 :     }
     154                 : 
     155                 : /* -------------------------------------------------------------------- */
     156                 : /*      Initialize the buffer to some background value. Use the         */
     157                 : /*      nodata value if available.                                      */
     158                 : /* -------------------------------------------------------------------- */
     159           10728 :     if ( nPixelSpace == GDALGetDataTypeSize(eBufType)/8 &&
     160                 :          (!bNoDataValueSet || (!CPLIsNan(dfNoDataValue) && dfNoDataValue == 0)) )
     161                 :     {
     162            9097 :         if (nLineSpace == nBufXSize * nPixelSpace)
     163                 :         {
     164            9083 :              memset( pData, 0, nBufYSize * nLineSpace );
     165                 :         }
     166                 :         else
     167                 :         {
     168                 :             int    iLine;
     169            1538 :             for( iLine = 0; iLine < nBufYSize; iLine++ )
     170                 :             {
     171            1524 :                 memset( ((GByte*)pData) + iLine * nLineSpace, 0, nBufXSize * nPixelSpace );
     172                 :             }
     173                 :         }
     174                 :     }
     175            1631 :     else if ( !bEqualAreas || bNoDataValueSet )
     176                 :     {
     177            1631 :         double dfWriteValue = 0.0;
     178                 :         int    iLine;
     179                 : 
     180            1631 :         if( bNoDataValueSet )
     181            1631 :             dfWriteValue = dfNoDataValue;
     182                 :         
     183            5544 :         for( iLine = 0; iLine < nBufYSize; iLine++ )
     184                 :         {
     185                 :             GDALCopyWords( &dfWriteValue, GDT_Float64, 0, 
     186                 :                            ((GByte *)pData) + nLineSpace * iLine, 
     187            3913 :                            eBufType, nPixelSpace, nBufXSize );
     188                 :         }
     189                 :     }
     190                 : 
     191                 : 
     192                 : /* -------------------------------------------------------------------- */
     193                 : /*      Do we have overviews that would be appropriate to satisfy       */
     194                 : /*      this request?                                                   */
     195                 : /* -------------------------------------------------------------------- */
     196           10748 :     if( (nBufXSize < nXSize || nBufYSize < nYSize)
     197              20 :         && GetOverviewCount() > 0 )
     198                 :     {
     199               0 :         if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
     200                 :                               pData, nBufXSize, nBufYSize, 
     201                 :                               eBufType, nPixelSpace, nLineSpace ) == CE_None )
     202               0 :             return CE_None;
     203                 :     }
     204                 :     
     205           10728 :     bAntiRecursionFlag = TRUE;
     206                 : 
     207                 : /* -------------------------------------------------------------------- */
     208                 : /*      Overlay each source in turn over top this.                      */
     209                 : /* -------------------------------------------------------------------- */
     210           24157 :     for( iSource = 0; eErr == CE_None && iSource < nSources; iSource++ )
     211                 :     {
     212                 :         eErr = 
     213           40287 :             papoSources[iSource]->RasterIO( nXOff, nYOff, nXSize, nYSize, 
     214                 :                                             pData, nBufXSize, nBufYSize, 
     215           53716 :                                             eBufType, nPixelSpace, nLineSpace);
     216                 :     }
     217                 :     
     218           10728 :     bAntiRecursionFlag = FALSE;
     219                 :     
     220           10728 :     return eErr;
     221                 : }
     222                 : 
     223                 : /************************************************************************/
     224                 : /*                             IReadBlock()                             */
     225                 : /************************************************************************/
     226                 : 
     227              54 : CPLErr VRTSourcedRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     228                 :                                    void * pImage )
     229                 : 
     230                 : {
     231              54 :     int nPixelSize = GDALGetDataTypeSize(eDataType)/8;
     232                 :     int nReadXSize, nReadYSize;
     233                 : 
     234              54 :     if( (nBlockXOff+1) * nBlockXSize > GetXSize() )
     235              12 :         nReadXSize = GetXSize() - nBlockXOff * nBlockXSize;
     236                 :     else
     237              42 :         nReadXSize = nBlockXSize;
     238                 : 
     239              54 :     if( (nBlockYOff+1) * nBlockYSize > GetYSize() )
     240              16 :         nReadYSize = GetYSize() - nBlockYOff * nBlockYSize;
     241                 :     else
     242              38 :         nReadYSize = nBlockYSize;
     243                 : 
     244                 :     return IRasterIO( GF_Read, 
     245                 :                       nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, 
     246                 :                       nReadXSize, nReadYSize, 
     247                 :                       pImage, nReadXSize, nReadYSize, eDataType, 
     248              54 :                       nPixelSize, nPixelSize * nBlockXSize );
     249                 : }
     250                 : 
     251                 : /************************************************************************/
     252                 : /*                             GetMinimum()                             */
     253                 : /************************************************************************/
     254                 : 
     255              10 : double VRTSourcedRasterBand::GetMinimum( int *pbSuccess )
     256                 : {
     257              10 :     const char *pszValue = NULL;
     258                 : 
     259              10 :     if( (pszValue = GetMetadataItem("STATISTICS_MINIMUM")) != NULL )
     260                 :     {
     261               1 :         if( pbSuccess != NULL )
     262               1 :             *pbSuccess = TRUE;
     263                 : 
     264               1 :         return CPLAtofM(pszValue);
     265                 :     }
     266                 : 
     267               9 :     if ( bAntiRecursionFlag )
     268                 :     {
     269                 :         CPLError( CE_Failure, CPLE_AppDefined,
     270                 :                   "VRTSourcedRasterBand::GetMinimum() called recursively on the same band. "
     271               0 :                   "It looks like the VRT is referencing itself." );
     272               0 :         if( pbSuccess != NULL )
     273               0 :             *pbSuccess = FALSE;
     274               0 :         return 0.0;
     275                 :     }
     276               9 :     bAntiRecursionFlag = TRUE;
     277                 : 
     278               9 :     double dfMin = 0;
     279              10 :     for( int iSource = 0; iSource < nSources; iSource++ )
     280                 :     {
     281               9 :         int bSuccess = FALSE;
     282               9 :         double dfSourceMin = papoSources[iSource]->GetMinimum(GetXSize(), GetYSize(), &bSuccess);
     283               9 :         if (!bSuccess)
     284                 :         {
     285               8 :             dfMin = GDALRasterBand::GetMinimum(pbSuccess);
     286               8 :             bAntiRecursionFlag = FALSE;
     287               8 :             return dfMin;
     288                 :         }
     289                 : 
     290               1 :         if (iSource == 0 || dfSourceMin < dfMin)
     291               1 :             dfMin = dfSourceMin;
     292                 :     }
     293                 : 
     294               1 :     bAntiRecursionFlag = FALSE;
     295                 : 
     296               1 :     if( pbSuccess != NULL )
     297               1 :         *pbSuccess = TRUE;
     298                 : 
     299               1 :     return dfMin;
     300                 : }
     301                 : 
     302                 : /************************************************************************/
     303                 : /*                             GetMaximum()                             */
     304                 : /************************************************************************/
     305                 : 
     306              10 : double VRTSourcedRasterBand::GetMaximum(int *pbSuccess )
     307                 : {
     308              10 :     const char *pszValue = NULL;
     309                 : 
     310              10 :     if( (pszValue = GetMetadataItem("STATISTICS_MAXIMUM")) != NULL )
     311                 :     {
     312               1 :         if( pbSuccess != NULL )
     313               1 :             *pbSuccess = TRUE;
     314                 : 
     315               1 :         return CPLAtofM(pszValue);
     316                 :     }
     317                 : 
     318               9 :     if ( bAntiRecursionFlag )
     319                 :     {
     320                 :         CPLError( CE_Failure, CPLE_AppDefined,
     321                 :                   "VRTSourcedRasterBand::GetMaximum() called recursively on the same band. "
     322               0 :                   "It looks like the VRT is referencing itself." );
     323               0 :         if( pbSuccess != NULL )
     324               0 :             *pbSuccess = FALSE;
     325               0 :         return 0.0;
     326                 :     }
     327               9 :     bAntiRecursionFlag = TRUE;
     328                 : 
     329               9 :     double dfMax = 0;
     330              10 :     for( int iSource = 0; iSource < nSources; iSource++ )
     331                 :     {
     332               9 :         int bSuccess = FALSE;
     333               9 :         double dfSourceMax = papoSources[iSource]->GetMaximum(GetXSize(), GetYSize(), &bSuccess);
     334               9 :         if (!bSuccess)
     335                 :         {
     336               8 :             dfMax = GDALRasterBand::GetMaximum(pbSuccess);
     337               8 :             bAntiRecursionFlag = FALSE;
     338               8 :             return dfMax;
     339                 :         }
     340                 : 
     341               1 :         if (iSource == 0 || dfSourceMax > dfMax)
     342               1 :             dfMax = dfSourceMax;
     343                 :     }
     344                 : 
     345               1 :     bAntiRecursionFlag = FALSE;
     346                 : 
     347               1 :     if( pbSuccess != NULL )
     348               1 :         *pbSuccess = TRUE;
     349                 : 
     350               1 :     return dfMax;
     351                 : }
     352                 : 
     353                 : 
     354                 : /************************************************************************/
     355                 : /*                             AddSource()                              */
     356                 : /************************************************************************/
     357                 : 
     358             629 : CPLErr VRTSourcedRasterBand::AddSource( VRTSource *poNewSource )
     359                 : 
     360                 : {
     361             629 :     nSources++;
     362                 : 
     363                 :     papoSources = (VRTSource **) 
     364             629 :         CPLRealloc(papoSources, sizeof(void*) * nSources);
     365             629 :     papoSources[nSources-1] = poNewSource;
     366                 : 
     367             629 :     ((VRTDataset *)poDS)->SetNeedsFlush();
     368                 : 
     369             629 :     return CE_None;
     370                 : }
     371                 : 
     372                 : /************************************************************************/
     373                 : /*                              VRTAddSource()                          */
     374                 : /************************************************************************/
     375                 : 
     376                 : /**
     377                 :  * @see VRTSourcedRasterBand::AddSource().
     378                 :  */
     379                 : 
     380               0 : CPLErr CPL_STDCALL VRTAddSource( VRTSourcedRasterBandH hVRTBand,
     381                 :                                  VRTSourceH hNewSource )
     382                 : {
     383               0 :     VALIDATE_POINTER1( hVRTBand, "VRTAddSource", CE_Failure );
     384                 : 
     385                 :     return ((VRTSourcedRasterBand *) hVRTBand)->
     386               0 :         AddSource( (VRTSource *)hNewSource );
     387                 : }
     388                 : 
     389                 : /************************************************************************/
     390                 : /*                              XMLInit()                               */
     391                 : /************************************************************************/
     392                 : 
     393             345 : CPLErr VRTSourcedRasterBand::XMLInit( CPLXMLNode * psTree, 
     394                 :                                       const char *pszVRTPath )
     395                 : 
     396                 : {
     397                 :     CPLErr eErr;
     398                 : 
     399             345 :     eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath );
     400             345 :     if( eErr != CE_None )
     401               0 :         return eErr;
     402                 :     
     403                 : /* -------------------------------------------------------------------- */
     404                 : /*      Validate a bit.                                                 */
     405                 : /* -------------------------------------------------------------------- */
     406             345 :     if( psTree == NULL || psTree->eType != CXT_Element
     407                 :         || (!EQUAL(psTree->pszValue,"VRTSourcedRasterBand") 
     408                 :             && !EQUAL(psTree->pszValue,"VRTRasterBand")
     409                 :       && !EQUAL(psTree->pszValue,"VRTDerivedRasterBand")) )
     410                 :     {
     411                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     412               0 :                   "Invalid node passed to VRTSourcedRasterBand::XMLInit()." );
     413               0 :         return CE_Failure;
     414                 :     }
     415                 : 
     416                 : /* -------------------------------------------------------------------- */
     417                 : /*      Process sources.                                                */
     418                 : /* -------------------------------------------------------------------- */
     419                 :     CPLXMLNode  *psChild;
     420             345 :     VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     421                 :     
     422            1817 :     for( psChild = psTree->psChild; 
     423                 :          psChild != NULL && poDriver != NULL; 
     424                 :          psChild = psChild->psNext)
     425                 :     {
     426                 :         VRTSource *poSource;
     427                 : 
     428            1473 :         if( psChild->eType != CXT_Element )
     429             682 :             continue;
     430                 : 
     431             791 :         CPLErrorReset();
     432             791 :         poSource = poDriver->ParseSource( psChild, pszVRTPath );
     433             791 :         if( poSource != NULL )
     434             330 :             AddSource( poSource );
     435             461 :         else if( CPLGetLastErrorType() != CE_None )
     436               1 :             return CE_Failure;
     437                 :     }
     438                 : 
     439                 : /* -------------------------------------------------------------------- */
     440                 : /*      Done.                                                           */
     441                 : /* -------------------------------------------------------------------- */
     442             344 :     if( nSources == 0 )
     443                 :         CPLDebug( "VRT", "No valid sources found for band in VRT file:\n%s",
     444              55 :                   pszVRTPath );
     445                 : 
     446             344 :     return CE_None;
     447                 : }
     448                 : 
     449                 : /************************************************************************/
     450                 : /*                           SerializeToXML()                           */
     451                 : /************************************************************************/
     452                 : 
     453             211 : CPLXMLNode *VRTSourcedRasterBand::SerializeToXML( const char *pszVRTPath )
     454                 : 
     455                 : {
     456                 :     CPLXMLNode *psTree;
     457                 : 
     458             211 :     psTree = VRTRasterBand::SerializeToXML( pszVRTPath );
     459                 : 
     460                 : /* -------------------------------------------------------------------- */
     461                 : /*      Process Sources.                                                */
     462                 : /* -------------------------------------------------------------------- */
     463             392 :     for( int iSource = 0; iSource < nSources; iSource++ )
     464                 :     {
     465                 :         CPLXMLNode      *psXMLSrc;
     466                 : 
     467             181 :         psXMLSrc = papoSources[iSource]->SerializeToXML( pszVRTPath );
     468                 :         
     469             181 :         if( psXMLSrc != NULL )
     470             181 :             CPLAddXMLChild( psTree, psXMLSrc );
     471                 :     }
     472                 : 
     473             211 :     return psTree;
     474                 : }
     475                 : 
     476                 : /************************************************************************/
     477                 : /*                          AddSimpleSource()                           */
     478                 : /************************************************************************/
     479                 : 
     480             265 : CPLErr VRTSourcedRasterBand::AddSimpleSource( GDALRasterBand *poSrcBand, 
     481                 :                                        int nSrcXOff, int nSrcYOff, 
     482                 :                                        int nSrcXSize, int nSrcYSize, 
     483                 :                                        int nDstXOff, int nDstYOff, 
     484                 :                                        int nDstXSize, int nDstYSize,
     485                 :                                        const char *pszResampling, 
     486                 :                                        double dfNoDataValue )
     487                 : 
     488                 : {
     489                 : /* -------------------------------------------------------------------- */
     490                 : /*      Default source and dest rectangles.                             */
     491                 : /* -------------------------------------------------------------------- */
     492             265 :     if( nSrcYSize == -1 )
     493                 :     {
     494             101 :         nSrcXOff = 0;
     495             101 :         nSrcYOff = 0;
     496             101 :         nSrcXSize = poSrcBand->GetXSize();
     497             101 :         nSrcYSize = poSrcBand->GetYSize();
     498                 :     }
     499                 : 
     500             265 :     if( nDstYSize == -1 )
     501                 :     {
     502             101 :         nDstXOff = 0;
     503             101 :         nDstYOff = 0;
     504             101 :         nDstXSize = nRasterXSize;
     505             101 :         nDstYSize = nRasterYSize;
     506                 :     }
     507                 : 
     508                 : /* -------------------------------------------------------------------- */
     509                 : /*      Create source.                                                  */
     510                 : /* -------------------------------------------------------------------- */
     511                 :     VRTSimpleSource *poSimpleSource;
     512                 : 
     513             265 :     if( pszResampling != NULL && EQUALN(pszResampling,"aver",4) )
     514               0 :         poSimpleSource = new VRTAveragedSource();
     515                 :     else
     516                 :     {
     517             265 :         poSimpleSource = new VRTSimpleSource();
     518             265 :         if( dfNoDataValue != VRT_NODATA_UNSET )
     519                 :             CPLError( 
     520                 :                 CE_Warning, CPLE_AppDefined, 
     521                 :                 "NODATA setting not currently supported for nearest\n"
     522               0 :                 "neighbour sampled simple sources on Virtual Datasources." );
     523                 :     }
     524                 : 
     525             265 :     poSimpleSource->SetSrcBand( poSrcBand );
     526             265 :     poSimpleSource->SetSrcWindow( nSrcXOff, nSrcYOff, nSrcXSize, nSrcYSize );
     527             265 :     poSimpleSource->SetDstWindow( nDstXOff, nDstYOff, nDstXSize, nDstYSize );
     528                 : 
     529             265 :     if( dfNoDataValue != VRT_NODATA_UNSET )
     530               0 :         poSimpleSource->SetNoDataValue( dfNoDataValue );
     531                 : 
     532                 : /* -------------------------------------------------------------------- */
     533                 : /*      Default source and dest rectangles.                             */
     534                 : /* -------------------------------------------------------------------- */
     535             265 :     if ( nSrcXOff == nDstXOff && nSrcYOff == nDstYOff &&
     536                 :          nSrcXSize == nDstXSize && nSrcYSize == nRasterYSize )
     537             192 :         bEqualAreas = TRUE;
     538                 : 
     539                 : /* -------------------------------------------------------------------- */
     540                 : /*      If we can get the associated GDALDataset, add a reference to it.*/
     541                 : /* -------------------------------------------------------------------- */
     542             265 :     if( poSrcBand->GetDataset() != NULL )
     543             265 :         poSrcBand->GetDataset()->Reference();
     544                 : 
     545                 : /* -------------------------------------------------------------------- */
     546                 : /*      add to list.                                                    */
     547                 : /* -------------------------------------------------------------------- */
     548             265 :     return AddSource( poSimpleSource );
     549                 : }
     550                 : 
     551                 : /************************************************************************/
     552                 : /*                         AddMaskBandSource()                          */
     553                 : /************************************************************************/
     554                 : 
     555                 : /* poSrcBand is not the mask band, but the band from which the mask band is taken */
     556               5 : CPLErr VRTSourcedRasterBand::AddMaskBandSource( GDALRasterBand *poSrcBand,
     557                 :                                                 int nSrcXOff, int nSrcYOff,
     558                 :                                                 int nSrcXSize, int nSrcYSize,
     559                 :                                                 int nDstXOff, int nDstYOff,
     560                 :                                                 int nDstXSize, int nDstYSize )
     561                 : {
     562                 : /* -------------------------------------------------------------------- */
     563                 : /*      Default source and dest rectangles.                             */
     564                 : /* -------------------------------------------------------------------- */
     565               5 :     if( nSrcYSize == -1 )
     566                 :     {
     567               2 :         nSrcXOff = 0;
     568               2 :         nSrcYOff = 0;
     569               2 :         nSrcXSize = poSrcBand->GetXSize();
     570               2 :         nSrcYSize = poSrcBand->GetYSize();
     571                 :     }
     572                 : 
     573               5 :     if( nDstYSize == -1 )
     574                 :     {
     575               2 :         nDstXOff = 0;
     576               2 :         nDstYOff = 0;
     577               2 :         nDstXSize = nRasterXSize;
     578               2 :         nDstYSize = nRasterYSize;
     579                 :     }
     580                 : 
     581                 : /* -------------------------------------------------------------------- */
     582                 : /*      Create source.                                                  */
     583                 : /* -------------------------------------------------------------------- */
     584               5 :     VRTSimpleSource* poSimpleSource = new VRTSimpleSource();
     585               5 :     poSimpleSource->SetSrcMaskBand( poSrcBand );
     586               5 :     poSimpleSource->SetSrcWindow( 0, 0, poSrcBand->GetXSize(), poSrcBand->GetYSize() );
     587               5 :     poSimpleSource->SetDstWindow( 0, 0, nRasterXSize, nRasterYSize );
     588                 : 
     589                 : /* -------------------------------------------------------------------- */
     590                 : /*      Default source and dest rectangles.                             */
     591                 : /* -------------------------------------------------------------------- */
     592              10 :     if ( nSrcXOff == nDstXOff && nSrcYOff == nDstYOff &&
     593                 :          nSrcXSize == nDstXSize && nSrcYSize == nRasterYSize )
     594               5 :         bEqualAreas = TRUE;
     595                 : 
     596                 : /* -------------------------------------------------------------------- */
     597                 : /*      If we can get the associated GDALDataset, add a reference to it.*/
     598                 : /* -------------------------------------------------------------------- */
     599               5 :     if( poSrcBand->GetDataset() != NULL )
     600               5 :         poSrcBand->GetDataset()->Reference();
     601                 : 
     602                 : /* -------------------------------------------------------------------- */
     603                 : /*      add to list.                                                    */
     604                 : /* -------------------------------------------------------------------- */
     605               5 :     return AddSource( poSimpleSource );
     606                 : }
     607                 : 
     608                 : /************************************************************************/
     609                 : /*                         VRTAddSimpleSource()                         */
     610                 : /************************************************************************/
     611                 : 
     612                 : /**
     613                 :  * @see VRTSourcedRasterBand::AddSimpleSource().
     614                 :  */
     615                 : 
     616              40 : CPLErr CPL_STDCALL VRTAddSimpleSource( VRTSourcedRasterBandH hVRTBand,
     617                 :                                        GDALRasterBandH hSrcBand, 
     618                 :                                        int nSrcXOff, int nSrcYOff, 
     619                 :                                        int nSrcXSize, int nSrcYSize, 
     620                 :                                        int nDstXOff, int nDstYOff, 
     621                 :                                        int nDstXSize, int nDstYSize,
     622                 :                                        const char *pszResampling,
     623                 :                                        double dfNoDataValue )
     624                 : {
     625              40 :     VALIDATE_POINTER1( hVRTBand, "VRTAddSimpleSource", CE_Failure );
     626                 : 
     627                 :     return ((VRTSourcedRasterBand *) hVRTBand)->AddSimpleSource(
     628                 :                                             (GDALRasterBand *)hSrcBand, 
     629                 :                                             nSrcXOff, nSrcYOff, 
     630                 :                                             nSrcXSize, nSrcYSize, 
     631                 :                                             nDstXOff, nDstYOff, 
     632                 :                                             nDstXSize, nDstYSize,
     633              40 :                                             pszResampling, dfNoDataValue );
     634                 : }
     635                 : 
     636                 : /************************************************************************/
     637                 : /*                          AddComplexSource()                          */
     638                 : /************************************************************************/
     639                 : 
     640              24 : CPLErr VRTSourcedRasterBand::AddComplexSource( GDALRasterBand *poSrcBand, 
     641                 :                                                int nSrcXOff, int nSrcYOff, 
     642                 :                                                int nSrcXSize, int nSrcYSize, 
     643                 :                                                int nDstXOff, int nDstYOff, 
     644                 :                                                int nDstXSize, int nDstYSize,
     645                 :                                                double dfScaleOff,
     646                 :                                                double dfScaleRatio,
     647                 :                                                double dfNoDataValue,
     648                 :                                                int nColorTableComponent)
     649                 : 
     650                 : {
     651                 : /* -------------------------------------------------------------------- */
     652                 : /*      Default source and dest rectangles.                             */
     653                 : /* -------------------------------------------------------------------- */
     654              24 :     if( nSrcYSize == -1 )
     655                 :     {
     656               0 :         nSrcXOff = 0;
     657               0 :         nSrcYOff = 0;
     658               0 :         nSrcXSize = poSrcBand->GetXSize();
     659               0 :         nSrcYSize = poSrcBand->GetYSize();
     660                 :     }
     661                 : 
     662              24 :     if( nDstYSize == -1 )
     663                 :     {
     664               0 :         nDstXOff = 0;
     665               0 :         nDstYOff = 0;
     666               0 :         nDstXSize = nRasterXSize;
     667               0 :         nDstYSize = nRasterYSize;
     668                 :     }
     669                 : 
     670                 : /* -------------------------------------------------------------------- */
     671                 : /*      Create source.                                                  */
     672                 : /* -------------------------------------------------------------------- */
     673                 :     VRTComplexSource *poSource;
     674                 : 
     675              24 :     poSource = new VRTComplexSource();
     676                 : 
     677              24 :     poSource->SetSrcBand( poSrcBand );
     678              24 :     poSource->SetSrcWindow( nSrcXOff, nSrcYOff, nSrcXSize, nSrcYSize );
     679              24 :     poSource->SetDstWindow( nDstXOff, nDstYOff, nDstXSize, nDstYSize );
     680                 : 
     681                 : /* -------------------------------------------------------------------- */
     682                 : /*      Set complex parameters.                                         */
     683                 : /* -------------------------------------------------------------------- */
     684              24 :     if( dfNoDataValue != VRT_NODATA_UNSET )
     685               8 :         poSource->SetNoDataValue( dfNoDataValue );
     686                 : 
     687              24 :     if( dfScaleOff != 0.0 || dfScaleRatio != 1.0 )
     688                 :     {
     689               1 :         poSource->bDoScaling = TRUE;
     690               1 :         poSource->dfScaleOff = dfScaleOff;
     691               1 :         poSource->dfScaleRatio = dfScaleRatio;
     692                 :           
     693                 :     }
     694                 : 
     695              24 :     poSource->nColorTableComponent = nColorTableComponent;
     696                 : 
     697                 : /* -------------------------------------------------------------------- */
     698                 : /*      If we can get the associated GDALDataset, add a reference to it.*/
     699                 : /* -------------------------------------------------------------------- */
     700              24 :     if( poSrcBand->GetDataset() != NULL )
     701              24 :         poSrcBand->GetDataset()->Reference();
     702                 : 
     703                 : /* -------------------------------------------------------------------- */
     704                 : /*      add to list.                                                    */
     705                 : /* -------------------------------------------------------------------- */
     706              24 :     return AddSource( poSource );
     707                 : }
     708                 : 
     709                 : /************************************************************************/
     710                 : /*                         VRTAddComplexSource()                        */
     711                 : /************************************************************************/
     712                 : 
     713                 : /**
     714                 :  * @see VRTSourcedRasterBand::AddComplexSource().
     715                 :  */
     716                 : 
     717               8 : CPLErr CPL_STDCALL VRTAddComplexSource( VRTSourcedRasterBandH hVRTBand,
     718                 :                                         GDALRasterBandH hSrcBand, 
     719                 :                                         int nSrcXOff, int nSrcYOff, 
     720                 :                                         int nSrcXSize, int nSrcYSize, 
     721                 :                                         int nDstXOff, int nDstYOff, 
     722                 :                                         int nDstXSize, int nDstYSize,
     723                 :                                         double dfScaleOff, 
     724                 :                                         double dfScaleRatio,
     725                 :                                         double dfNoDataValue )
     726                 : {
     727               8 :     VALIDATE_POINTER1( hVRTBand, "VRTAddComplexSource", CE_Failure );
     728                 : 
     729                 :     return ((VRTSourcedRasterBand *) hVRTBand)->AddComplexSource(
     730                 :                                             (GDALRasterBand *)hSrcBand, 
     731                 :                                             nSrcXOff, nSrcYOff, 
     732                 :                                             nSrcXSize, nSrcYSize, 
     733                 :                                             nDstXOff, nDstYOff, 
     734                 :                                             nDstXSize, nDstYSize,
     735                 :                                             dfScaleOff, dfScaleRatio,
     736               8 :                                             dfNoDataValue );
     737                 : }
     738                 : 
     739                 : /************************************************************************/
     740                 : /*                           AddFuncSource()                            */
     741                 : /************************************************************************/
     742                 : 
     743               0 : CPLErr VRTSourcedRasterBand::AddFuncSource( VRTImageReadFunc pfnReadFunc, 
     744                 :                                      void *pCBData, double dfNoDataValue )
     745                 : 
     746                 : {
     747                 : /* -------------------------------------------------------------------- */
     748                 : /*      Create source.                                                  */
     749                 : /* -------------------------------------------------------------------- */
     750               0 :     VRTFuncSource *poFuncSource = new VRTFuncSource;
     751                 : 
     752               0 :     poFuncSource->fNoDataValue = (float) dfNoDataValue;
     753               0 :     poFuncSource->pfnReadFunc = pfnReadFunc;
     754               0 :     poFuncSource->pCBData = pCBData;
     755               0 :     poFuncSource->eType = GetRasterDataType();
     756                 : 
     757                 : /* -------------------------------------------------------------------- */
     758                 : /*      add to list.                                                    */
     759                 : /* -------------------------------------------------------------------- */
     760               0 :     return AddSource( poFuncSource );
     761                 : }
     762                 : 
     763                 : /************************************************************************/
     764                 : /*                          VRTAddFuncSource()                          */
     765                 : /************************************************************************/
     766                 : 
     767                 : /**
     768                 :  * @see VRTSourcedRasterBand::AddFuncSource().
     769                 :  */
     770                 : 
     771               0 : CPLErr CPL_STDCALL VRTAddFuncSource( VRTSourcedRasterBandH hVRTBand,
     772                 :                                      VRTImageReadFunc pfnReadFunc, 
     773                 :                                      void *pCBData, double dfNoDataValue )
     774                 : {
     775               0 :     VALIDATE_POINTER1( hVRTBand, "VRTAddFuncSource", CE_Failure );
     776                 : 
     777                 :     return ((VRTSourcedRasterBand *) hVRTBand)->
     778               0 :         AddFuncSource( pfnReadFunc, pCBData, dfNoDataValue );
     779                 : }
     780                 : 
     781                 : 
     782                 : /************************************************************************/
     783                 : /*                          GetMetadataItem()                           */
     784                 : /************************************************************************/
     785                 : 
     786             226 : const char *VRTSourcedRasterBand::GetMetadataItem( const char * pszName,
     787                 :                                                    const char * pszDomain )
     788                 : 
     789                 : {
     790                 : /* ==================================================================== */
     791                 : /*      LocationInfo handling.                                          */
     792                 : /* ==================================================================== */
     793             226 :     if( pszDomain != NULL 
     794                 :         && EQUAL(pszDomain,"LocationInfo")
     795                 :         && (EQUALN(pszName,"Pixel_",6) || EQUALN(pszName,"GeoPixel_",9)) )
     796                 :     {
     797                 :         int iPixel, iLine;
     798                 : 
     799                 : /* -------------------------------------------------------------------- */
     800                 : /*      What pixel are we aiming at?                                    */
     801                 : /* -------------------------------------------------------------------- */
     802               1 :         if( EQUALN(pszName,"Pixel_",6) )
     803                 :         {
     804               1 :             if( sscanf( pszName+6, "%d_%d", &iPixel, &iLine ) != 2 )
     805               0 :                 return NULL;
     806                 :         }
     807               0 :         else if( EQUALN(pszName,"GeoPixel_",9) )
     808                 :         {
     809                 :             double adfGeoTransform[6];
     810                 :             double adfInvGeoTransform[6];
     811                 :             double dfGeoX, dfGeoY;
     812                 : 
     813               0 :             if( sscanf( pszName+9, "%lf_%lf", &dfGeoX, &dfGeoY ) != 2 )
     814               0 :                 return NULL;
     815                 : 
     816               0 :             if( GetDataset() == NULL )
     817               0 :                 return NULL;
     818                 :             
     819               0 :             if( GetDataset()->GetGeoTransform( adfGeoTransform ) != CE_None )
     820               0 :                 return NULL;
     821                 :             
     822               0 :             if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) )
     823               0 :                 return NULL;
     824                 :                 
     825                 :             iPixel = (int) floor(
     826               0 :                 adfInvGeoTransform[0] 
     827               0 :                 + adfInvGeoTransform[1] * dfGeoX
     828               0 :                 + adfInvGeoTransform[2] * dfGeoY );
     829                 :             iLine = (int) floor(
     830               0 :                 adfInvGeoTransform[3] 
     831               0 :                 + adfInvGeoTransform[4] * dfGeoX
     832               0 :                 + adfInvGeoTransform[5] * dfGeoY );
     833                 :         }
     834                 :         else
     835               0 :             return NULL;
     836                 : 
     837               1 :         if( iPixel < 0 || iLine < 0 
     838                 :             || iPixel >= GetXSize()
     839                 :             || iLine >= GetYSize() )
     840               0 :             return NULL;
     841                 : 
     842                 : /* -------------------------------------------------------------------- */
     843                 : /*      Find the file(s) at this location.                              */
     844                 : /* -------------------------------------------------------------------- */
     845               1 :         char **papszFileList = NULL;
     846               1 :         int nListMaxSize = 0, nListSize = 0;
     847                 :         CPLHashSet* hSetFiles = CPLHashSetNew(CPLHashSetHashStr,
     848                 :                                               CPLHashSetEqualStr,
     849               1 :                                               NULL);
     850                 :         
     851               2 :         for( int iSource = 0; iSource < nSources; iSource++ )
     852                 :         {
     853                 :             int nReqXOff, nReqYOff, nReqXSize, nReqYSize;
     854                 :             int nOutXOff, nOutYOff, nOutXSize, nOutYSize;
     855                 : 
     856               1 :             if (!papoSources[iSource]->IsSimpleSource())
     857               0 :                 continue;
     858                 : 
     859               1 :             VRTSimpleSource *poSrc = (VRTSimpleSource *) papoSources[iSource];
     860                 : 
     861               1 :             if( !poSrc->GetSrcDstWindow( iPixel, iLine, 1, 1, 1, 1,
     862                 :                                          &nReqXOff, &nReqYOff, 
     863                 :                                          &nReqXSize, &nReqYSize,
     864                 :                                          &nOutXOff, &nOutYOff, 
     865                 :                                          &nOutXSize, &nOutYSize ) )
     866               0 :                 continue;
     867                 : 
     868                 :             poSrc->GetFileList( &papszFileList, &nListSize, &nListMaxSize,
     869               1 :                                 hSetFiles );
     870                 :         }
     871                 :         
     872                 : /* -------------------------------------------------------------------- */
     873                 : /*      Format into XML.                                                */
     874                 : /* -------------------------------------------------------------------- */
     875                 :         int i;
     876                 : 
     877               1 :         osLastLocationInfo = "<LocationInfo>";
     878               2 :         for( i = 0; i < nListSize; i++ )
     879                 :         {
     880               1 :             osLastLocationInfo += "<File>";
     881               1 :             char* pszXMLEscaped = CPLEscapeString(papszFileList[i], -1, CPLES_XML);
     882               1 :             osLastLocationInfo += pszXMLEscaped;
     883               1 :             CPLFree(pszXMLEscaped);
     884               1 :             osLastLocationInfo += "</File>";
     885                 :         }
     886               1 :         osLastLocationInfo += "</LocationInfo>";
     887                 : 
     888               1 :         CSLDestroy( papszFileList );
     889               1 :         CPLHashSetDestroy( hSetFiles );
     890                 : 
     891               1 :         return osLastLocationInfo.c_str();
     892                 :     }
     893                 : 
     894                 : /* ==================================================================== */
     895                 : /*      Other domains.                                                  */
     896                 : /* ==================================================================== */
     897                 :     else
     898             225 :         return GDALRasterBand::GetMetadataItem( pszName, pszDomain );
     899                 : }
     900                 : 
     901                 : /************************************************************************/
     902                 : /*                            GetMetadata()                             */
     903                 : /************************************************************************/
     904                 : 
     905             392 : char **VRTSourcedRasterBand::GetMetadata( const char *pszDomain )
     906                 : 
     907                 : {
     908                 : /* ==================================================================== */
     909                 : /*      vrt_sources domain handling.                                    */
     910                 : /* ==================================================================== */
     911             392 :     if( pszDomain != NULL && EQUAL(pszDomain,"vrt_sources") )
     912                 :     {
     913               0 :         char **papszSourceList = NULL;
     914                 : 
     915                 : /* -------------------------------------------------------------------- */
     916                 : /*      Process SimpleSources.                                          */
     917                 : /* -------------------------------------------------------------------- */
     918               0 :         for( int iSource = 0; iSource < nSources; iSource++ )
     919                 :         {
     920                 :             CPLXMLNode      *psXMLSrc;
     921                 :             char            *pszXML;
     922                 :             
     923               0 :             psXMLSrc = papoSources[iSource]->SerializeToXML( NULL );
     924               0 :             if( psXMLSrc == NULL )
     925               0 :                 continue;
     926                 : 
     927               0 :             pszXML = CPLSerializeXMLTree( psXMLSrc );
     928                 : 
     929                 :             papszSourceList = 
     930                 :                 CSLSetNameValue( papszSourceList, 
     931               0 :                                  CPLSPrintf( "source_%d", iSource ), pszXML );
     932               0 :             CPLFree( pszXML );
     933               0 :             CPLDestroyXMLNode( psXMLSrc );
     934                 :         }
     935                 :         
     936               0 :         return papszSourceList;
     937                 :     }
     938                 : 
     939                 : /* ==================================================================== */
     940                 : /*      Other domains.                                                  */
     941                 : /* ==================================================================== */
     942                 :     else
     943             392 :         return GDALRasterBand::GetMetadata( pszDomain );
     944                 : }
     945                 : 
     946                 : /************************************************************************/
     947                 : /*                          SetMetadataItem()                           */
     948                 : /************************************************************************/
     949                 : 
     950              16 : CPLErr VRTSourcedRasterBand::SetMetadataItem( const char *pszName, 
     951                 :                                               const char *pszValue, 
     952                 :                                               const char *pszDomain )
     953                 : 
     954                 : {
     955                 :     CPLDebug( "VRT", "VRTSourcedRasterBand::SetMetadataItem(%s,%s,%s)\n",
     956              16 :               pszName, pszValue, pszDomain );
     957                 :               
     958              16 :     if( pszDomain != NULL
     959                 :         && EQUAL(pszDomain,"new_vrt_sources") )
     960                 :     {
     961               1 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     962                 : 
     963               1 :         CPLXMLNode *psTree = CPLParseXMLString( pszValue );
     964                 :         VRTSource *poSource;
     965                 :         
     966               1 :         if( psTree == NULL )
     967               0 :             return CE_Failure;
     968                 :         
     969               1 :         poSource = poDriver->ParseSource( psTree, NULL );
     970               1 :         CPLDestroyXMLNode( psTree );
     971                 :         
     972               1 :         if( poSource != NULL )
     973               1 :             return AddSource( poSource );
     974                 :         else
     975               0 :             return CE_Failure;
     976                 :     }
     977              15 :     else if( pszDomain != NULL
     978                 :         && EQUAL(pszDomain,"vrt_sources") )
     979                 :     {
     980                 :         int iSource;
     981               1 :         if (sscanf(pszName, "source_%d", &iSource) != 1 || iSource < 0 ||
     982                 :             iSource >= nSources)
     983                 :         {
     984                 :             CPLError(CE_Failure, CPLE_AppDefined,
     985                 :                      "%s metadata item name is not recognized. "
     986                 :                      "Should be between source_0 and source_%d",
     987               0 :                      pszName, nSources - 1);
     988               0 :             return CE_Failure;
     989                 :         }
     990                 : 
     991               1 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     992                 : 
     993               1 :         CPLXMLNode *psTree = CPLParseXMLString( pszValue );
     994                 :         VRTSource *poSource;
     995                 :         
     996               1 :         if( psTree == NULL )
     997               0 :             return CE_Failure;
     998                 :         
     999               1 :         poSource = poDriver->ParseSource( psTree, NULL );
    1000               1 :         CPLDestroyXMLNode( psTree );
    1001                 :         
    1002               1 :         if( poSource != NULL )
    1003                 :         {
    1004               1 :             delete papoSources[iSource];
    1005               1 :             papoSources[iSource] = poSource;
    1006               1 :             ((VRTDataset *)poDS)->SetNeedsFlush();
    1007               1 :             return CE_None;
    1008                 :         }
    1009                 :         else
    1010               0 :             return CE_Failure;
    1011                 :     }
    1012                 :     else
    1013              14 :         return VRTRasterBand::SetMetadataItem( pszName, pszValue, pszDomain );
    1014                 : }
    1015                 : 
    1016                 : /************************************************************************/
    1017                 : /*                            SetMetadata()                             */
    1018                 : /************************************************************************/
    1019                 : 
    1020             168 : CPLErr VRTSourcedRasterBand::SetMetadata( char **papszNewMD, const char *pszDomain )
    1021                 : 
    1022                 : {
    1023             168 :     if( pszDomain != NULL
    1024                 :         && (EQUAL(pszDomain,"new_vrt_sources") 
    1025                 :             || EQUAL(pszDomain,"vrt_sources")) )
    1026                 :     {
    1027               4 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
    1028                 :         CPLErr eErr;
    1029                 :         int    i;
    1030                 : 
    1031               4 :         if( EQUAL(pszDomain,"vrt_sources") )
    1032                 :         {
    1033               4 :             for( int i = 0; i < nSources; i++ )
    1034               0 :                 delete papoSources[i];
    1035               4 :             CPLFree( papoSources );
    1036               4 :             papoSources = NULL;
    1037               4 :             nSources = 0;
    1038                 :         }
    1039                 : 
    1040              16 :         for( i = 0; i < CSLCount(papszNewMD); i++ )
    1041                 :         {
    1042               4 :             const char *pszXML = CPLParseNameValue( papszNewMD[i], NULL );
    1043               4 :             CPLXMLNode *psTree = CPLParseXMLString( pszXML );
    1044                 :             VRTSource *poSource;
    1045                 :             
    1046               4 :             if( psTree == NULL )
    1047               0 :                 return CE_Failure;
    1048                 : 
    1049               4 :             poSource = poDriver->ParseSource( psTree, NULL );
    1050               4 :             CPLDestroyXMLNode( psTree );
    1051                 : 
    1052               4 :             if( poSource != NULL )
    1053                 :             {
    1054               4 :                 eErr = AddSource( poSource );
    1055               4 :                 if( eErr != CE_None )
    1056               0 :                     return eErr;
    1057                 :             }
    1058                 :             else
    1059               0 :                 return CE_Failure;
    1060                 :         }
    1061                 : 
    1062               4 :         return CE_None;
    1063                 :     }
    1064                 :     else
    1065             164 :         return VRTRasterBand::SetMetadata( papszNewMD, pszDomain );
    1066                 : }
    1067                 : 
    1068                 : /************************************************************************/
    1069                 : /*                             GetFileList()                            */
    1070                 : /************************************************************************/
    1071                 : 
    1072               4 : void VRTSourcedRasterBand::GetFileList(char*** ppapszFileList, int *pnSize,
    1073                 :                                        int *pnMaxSize, CPLHashSet* hSetFiles)
    1074                 : {
    1075               8 :     for( int i = 0; i < nSources; i++ )
    1076                 :     {
    1077              12 :         papoSources[i]->GetFileList(ppapszFileList, pnSize,
    1078              16 :                                     pnMaxSize, hSetFiles);
    1079                 :     }
    1080                 : 
    1081                 :     VRTRasterBand::GetFileList( ppapszFileList, pnSize,
    1082               4 :                                 pnMaxSize, hSetFiles);
    1083               4 : }
    1084                 : 
    1085                 : /************************************************************************/
    1086                 : /*                        CloseDependentDatasets()                      */
    1087                 : /************************************************************************/
    1088                 : 
    1089             648 : int VRTSourcedRasterBand::CloseDependentDatasets()
    1090                 : {
    1091             648 :     if (nSources == 0)
    1092             112 :         return FALSE;
    1093                 : 
    1094            1165 :     for( int i = 0; i < nSources; i++ )
    1095             629 :         delete papoSources[i];
    1096                 : 
    1097             536 :     CPLFree( papoSources );
    1098             536 :     papoSources = NULL;
    1099             536 :     nSources = 0;
    1100                 : 
    1101             536 :     return TRUE;
    1102                 : }

Generated by: LCOV version 1.7