LCOV - code coverage report
Current view: directory - frmts/vrt - vrtsourcedrasterband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 241 165 68.5 %
Date: 2010-01-09 Functions: 22 16 72.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: vrtsourcedrasterband.cpp 17852 2009-10-18 11:15:09Z 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 17852 2009-10-18 11:15:09Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /* ==================================================================== */
      38                 : /*                          VRTSourcedRasterBand                        */
      39                 : /* ==================================================================== */
      40                 : /************************************************************************/
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                        VRTSourcedRasterBand()                        */
      44                 : /************************************************************************/
      45                 : 
      46             143 : VRTSourcedRasterBand::VRTSourcedRasterBand( GDALDataset *poDS, int nBand )
      47                 : 
      48                 : {
      49             143 :     Initialize( poDS->GetRasterXSize(), poDS->GetRasterYSize() );
      50                 : 
      51             143 :     this->poDS = poDS;
      52             143 :     this->nBand = nBand;
      53             143 : }
      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             114 : VRTSourcedRasterBand::VRTSourcedRasterBand( GDALDataset *poDS, int nBand,
      73                 :                                             GDALDataType eType, 
      74             114 :                                             int nXSize, int nYSize )
      75                 : 
      76                 : {
      77             114 :     Initialize( nXSize, nYSize );
      78                 : 
      79             114 :     this->poDS = poDS;
      80             114 :     this->nBand = nBand;
      81                 : 
      82             114 :     eDataType = eType;
      83             114 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                             Initialize()                             */
      87                 : /************************************************************************/
      88                 : 
      89             257 : void VRTSourcedRasterBand::Initialize( int nXSize, int nYSize )
      90                 : 
      91                 : {
      92             257 :     VRTRasterBand::Initialize( nXSize, nYSize );
      93                 : 
      94             257 :     nSources = 0;
      95             257 :     papoSources = NULL;
      96             257 :     bEqualAreas = FALSE;
      97             257 :     bAlreadyInIRasterIO = FALSE;
      98             257 : }
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                       ~VRTSourcedRasterBand()                        */
     102                 : /************************************************************************/
     103                 : 
     104             514 : VRTSourcedRasterBand::~VRTSourcedRasterBand()
     105                 : 
     106                 : {
     107             554 :     for( int i = 0; i < nSources; i++ )
     108             297 :         delete papoSources[i];
     109                 : 
     110             257 :     CPLFree( papoSources );
     111             257 :     nSources = 0;
     112             514 : }
     113                 : 
     114                 : /************************************************************************/
     115                 : /*                             IRasterIO()                              */
     116                 : /************************************************************************/
     117                 : 
     118            6051 : CPLErr VRTSourcedRasterBand::IRasterIO( GDALRWFlag eRWFlag,
     119                 :                                  int nXOff, int nYOff, int nXSize, int nYSize,
     120                 :                                  void * pData, int nBufXSize, int nBufYSize,
     121                 :                                  GDALDataType eBufType,
     122                 :                                  int nPixelSpace, int nLineSpace )
     123                 : 
     124                 : {
     125                 :     int         iSource;
     126            6051 :     CPLErr      eErr = CE_None;
     127                 : 
     128            6051 :     if( eRWFlag == GF_Write )
     129                 :     {
     130                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     131               0 :                   "Writing through VRTSourcedRasterBand is not supported." );
     132               0 :         return CE_Failure;
     133                 :     }
     134                 :     
     135                 :     /* When using GDALProxyPoolDataset for sources, the recusion will not be */
     136                 :     /* detected at VRT opening but when doing RasterIO. As the proxy pool will */
     137                 :     /* return the already opened dataset, we can just test a member variable. */
     138            6051 :     if ( bAlreadyInIRasterIO )
     139                 :     {
     140                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     141                 :                   "VRTSourcedRasterBand::IRasterIO() called recursively on the same band. "
     142               0 :                   "It looks like the VRT is referencing itself." );
     143               0 :         return CE_Failure;
     144                 :     }
     145                 : 
     146                 : /* -------------------------------------------------------------------- */
     147                 : /*      Initialize the buffer to some background value. Use the         */
     148                 : /*      nodata value if available.                                      */
     149                 : /* -------------------------------------------------------------------- */
     150            6051 :     if ( nPixelSpace == GDALGetDataTypeSize(eBufType)/8 &&
     151                 :          (!bNoDataValueSet || dfNoDataValue == 0) )
     152                 :     {
     153            4432 :         if (nLineSpace == nBufXSize * nPixelSpace)
     154                 :         {
     155            4430 :              memset( pData, 0, nBufYSize * nLineSpace );
     156                 :         }
     157                 :         else
     158                 :         {
     159                 :             int    iLine;
     160             202 :             for( iLine = 0; iLine < nBufYSize; iLine++ )
     161                 :             {
     162             200 :                 memset( ((GByte*)pData) + iLine * nLineSpace, 0, nBufXSize * nPixelSpace );
     163                 :             }
     164                 :         }
     165                 :     }
     166            1619 :     else if ( !bEqualAreas || bNoDataValueSet )
     167                 :     {
     168            1619 :         double dfWriteValue = 0.0;
     169                 :         int    iLine;
     170                 : 
     171            1619 :         if( bNoDataValueSet )
     172            1619 :             dfWriteValue = dfNoDataValue;
     173                 :         
     174            5501 :         for( iLine = 0; iLine < nBufYSize; iLine++ )
     175                 :         {
     176                 :             GDALCopyWords( &dfWriteValue, GDT_Float64, 0, 
     177                 :                            ((GByte *)pData) + nLineSpace * iLine, 
     178            3882 :                            eBufType, nPixelSpace, nBufXSize );
     179                 :         }
     180                 :     }
     181                 : 
     182                 : 
     183                 : /* -------------------------------------------------------------------- */
     184                 : /*      Do we have overviews that would be appropriate to satisfy       */
     185                 : /*      this request?                                                   */
     186                 : /* -------------------------------------------------------------------- */
     187            6071 :     if( (nBufXSize < nXSize || nBufYSize < nYSize)
     188              20 :         && GetOverviewCount() > 0 )
     189                 :     {
     190               0 :         if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
     191                 :                               pData, nBufXSize, nBufYSize, 
     192                 :                               eBufType, nPixelSpace, nLineSpace ) == CE_None )
     193               0 :             return CE_None;
     194                 :     }
     195                 :     
     196            6051 :     bAlreadyInIRasterIO = TRUE;
     197                 : 
     198                 : /* -------------------------------------------------------------------- */
     199                 : /*      Overlay each source in turn over top this.                      */
     200                 : /* -------------------------------------------------------------------- */
     201           12613 :     for( iSource = 0; eErr == CE_None && iSource < nSources; iSource++ )
     202                 :     {
     203                 :         eErr = 
     204           19686 :             papoSources[iSource]->RasterIO( nXOff, nYOff, nXSize, nYSize, 
     205                 :                                             pData, nBufXSize, nBufYSize, 
     206           26248 :                                             eBufType, nPixelSpace, nLineSpace);
     207                 :     }
     208                 :     
     209            6051 :     bAlreadyInIRasterIO = FALSE;
     210                 :     
     211            6051 :     return eErr;
     212                 : }
     213                 : 
     214                 : /************************************************************************/
     215                 : /*                             IReadBlock()                             */
     216                 : /************************************************************************/
     217                 : 
     218               0 : CPLErr VRTSourcedRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     219                 :                                    void * pImage )
     220                 : 
     221                 : {
     222               0 :     int nPixelSize = GDALGetDataTypeSize(eDataType)/8;
     223                 :     int nReadXSize, nReadYSize;
     224                 : 
     225               0 :     if( (nBlockXOff+1) * nBlockXSize > GetXSize() )
     226               0 :         nReadXSize = GetXSize() - nBlockXOff * nBlockXSize;
     227                 :     else
     228               0 :         nReadXSize = nBlockXSize;
     229                 : 
     230               0 :     if( (nBlockYOff+1) * nBlockYSize > GetYSize() )
     231               0 :         nReadYSize = GetYSize() - nBlockYOff * nBlockYSize;
     232                 :     else
     233               0 :         nReadYSize = nBlockYSize;
     234                 : 
     235                 :     return IRasterIO( GF_Read, 
     236                 :                       nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, 
     237                 :                       nReadXSize, nReadYSize, 
     238                 :                       pImage, nReadXSize, nReadYSize, eDataType, 
     239               0 :                       nPixelSize, nPixelSize * nBlockXSize );
     240                 : }
     241                 : 
     242                 : /************************************************************************/
     243                 : /*                             AddSource()                              */
     244                 : /************************************************************************/
     245                 : 
     246             297 : CPLErr VRTSourcedRasterBand::AddSource( VRTSource *poNewSource )
     247                 : 
     248                 : {
     249             297 :     nSources++;
     250                 : 
     251                 :     papoSources = (VRTSource **) 
     252             297 :         CPLRealloc(papoSources, sizeof(void*) * nSources);
     253             297 :     papoSources[nSources-1] = poNewSource;
     254                 : 
     255             297 :     ((VRTDataset *)poDS)->SetNeedsFlush();
     256                 : 
     257             297 :     return CE_None;
     258                 : }
     259                 : 
     260                 : /************************************************************************/
     261                 : /*                              VRTAddSource()                          */
     262                 : /************************************************************************/
     263                 : 
     264                 : /**
     265                 :  * @see VRTSourcedRasterBand::AddSource().
     266                 :  */
     267                 : 
     268               0 : CPLErr CPL_STDCALL VRTAddSource( VRTSourcedRasterBandH hVRTBand,
     269                 :                                  VRTSourceH hNewSource )
     270                 : {
     271               0 :     VALIDATE_POINTER1( hVRTBand, "VRTAddSource", CE_Failure );
     272                 : 
     273                 :     return ((VRTSourcedRasterBand *) hVRTBand)->
     274               0 :         AddSource( (VRTSource *)hNewSource );
     275                 : }
     276                 : 
     277                 : /************************************************************************/
     278                 : /*                              XMLInit()                               */
     279                 : /************************************************************************/
     280                 : 
     281             143 : CPLErr VRTSourcedRasterBand::XMLInit( CPLXMLNode * psTree, 
     282                 :                                       const char *pszVRTPath )
     283                 : 
     284                 : {
     285                 :     CPLErr eErr;
     286                 : 
     287             143 :     eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath );
     288             143 :     if( eErr != CE_None )
     289               0 :         return eErr;
     290                 :     
     291                 : /* -------------------------------------------------------------------- */
     292                 : /*      Validate a bit.                                                 */
     293                 : /* -------------------------------------------------------------------- */
     294             143 :     if( psTree == NULL || psTree->eType != CXT_Element
     295                 :         || (!EQUAL(psTree->pszValue,"VRTSourcedRasterBand") 
     296                 :             && !EQUAL(psTree->pszValue,"VRTRasterBand")
     297                 :       && !EQUAL(psTree->pszValue,"VRTDerivedRasterBand")) )
     298                 :     {
     299                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     300               0 :                   "Invalid node passed to VRTSourcedRasterBand::XMLInit()." );
     301               0 :         return CE_Failure;
     302                 :     }
     303                 : 
     304                 : /* -------------------------------------------------------------------- */
     305                 : /*      Process sources.                                                */
     306                 : /* -------------------------------------------------------------------- */
     307                 :     CPLXMLNode  *psChild;
     308             143 :     VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     309                 :     
     310             819 :     for( psChild = psTree->psChild; 
     311                 :          psChild != NULL && poDriver != NULL; 
     312                 :          psChild = psChild->psNext)
     313                 :     {
     314                 :         VRTSource *poSource;
     315                 : 
     316             677 :         if( psChild->eType != CXT_Element )
     317             288 :             continue;
     318                 : 
     319             389 :         CPLErrorReset();
     320             389 :         poSource = poDriver->ParseSource( psChild, pszVRTPath );
     321             389 :         if( poSource != NULL )
     322             183 :             AddSource( poSource );
     323             206 :         else if( CPLGetLastErrorType() != CE_None )
     324               1 :             return CE_Failure;
     325                 :     }
     326                 : 
     327                 : /* -------------------------------------------------------------------- */
     328                 : /*      Done.                                                           */
     329                 : /* -------------------------------------------------------------------- */
     330             142 :     if( nSources == 0 )
     331                 :         CPLDebug( "VRT", "No valid sources found for band in VRT file:\n%s",
     332               0 :                   pszVRTPath );
     333                 : 
     334             142 :     return CE_None;
     335                 : }
     336                 : 
     337                 : /************************************************************************/
     338                 : /*                           SerializeToXML()                           */
     339                 : /************************************************************************/
     340                 : 
     341              76 : CPLXMLNode *VRTSourcedRasterBand::SerializeToXML( const char *pszVRTPath )
     342                 : 
     343                 : {
     344                 :     CPLXMLNode *psTree;
     345                 : 
     346              76 :     psTree = VRTRasterBand::SerializeToXML( pszVRTPath );
     347                 : 
     348                 : /* -------------------------------------------------------------------- */
     349                 : /*      Process Sources.                                                */
     350                 : /* -------------------------------------------------------------------- */
     351             152 :     for( int iSource = 0; iSource < nSources; iSource++ )
     352                 :     {
     353                 :         CPLXMLNode      *psXMLSrc;
     354                 : 
     355              76 :         psXMLSrc = papoSources[iSource]->SerializeToXML( pszVRTPath );
     356                 :         
     357              76 :         if( psXMLSrc != NULL )
     358              76 :             CPLAddXMLChild( psTree, psXMLSrc );
     359                 :     }
     360                 : 
     361              76 :     return psTree;
     362                 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                          AddSimpleSource()                           */
     366                 : /************************************************************************/
     367                 : 
     368              94 : CPLErr VRTSourcedRasterBand::AddSimpleSource( GDALRasterBand *poSrcBand, 
     369                 :                                        int nSrcXOff, int nSrcYOff, 
     370                 :                                        int nSrcXSize, int nSrcYSize, 
     371                 :                                        int nDstXOff, int nDstYOff, 
     372                 :                                        int nDstXSize, int nDstYSize,
     373                 :                                        const char *pszResampling, 
     374                 :                                        double dfNoDataValue )
     375                 : 
     376                 : {
     377                 : /* -------------------------------------------------------------------- */
     378                 : /*      Default source and dest rectangles.                             */
     379                 : /* -------------------------------------------------------------------- */
     380              94 :     if( nSrcYSize == -1 )
     381                 :     {
     382              30 :         nSrcXOff = 0;
     383              30 :         nSrcYOff = 0;
     384              30 :         nSrcXSize = poSrcBand->GetXSize();
     385              30 :         nSrcYSize = poSrcBand->GetYSize();
     386                 :     }
     387                 : 
     388              94 :     if( nDstYSize == -1 )
     389                 :     {
     390              30 :         nDstXOff = 0;
     391              30 :         nDstYOff = 0;
     392              30 :         nDstXSize = nRasterXSize;
     393              30 :         nDstYSize = nRasterYSize;
     394                 :     }
     395                 : 
     396                 : /* -------------------------------------------------------------------- */
     397                 : /*      Create source.                                                  */
     398                 : /* -------------------------------------------------------------------- */
     399                 :     VRTSimpleSource *poSimpleSource;
     400                 : 
     401              94 :     if( pszResampling != NULL && EQUALN(pszResampling,"aver",4) )
     402               0 :         poSimpleSource = new VRTAveragedSource();
     403                 :     else
     404                 :     {
     405              94 :         poSimpleSource = new VRTSimpleSource();
     406              94 :         if( dfNoDataValue != VRT_NODATA_UNSET )
     407                 :             CPLError( 
     408                 :                 CE_Warning, CPLE_AppDefined, 
     409                 :                 "NODATA setting not currently supported for nearest\n"
     410               0 :                 "neighbour sampled simple sources on Virtual Datasources." );
     411                 :     }
     412                 : 
     413              94 :     poSimpleSource->SetSrcBand( poSrcBand );
     414              94 :     poSimpleSource->SetSrcWindow( nSrcXOff, nSrcYOff, nSrcXSize, nSrcYSize );
     415              94 :     poSimpleSource->SetDstWindow( nDstXOff, nDstYOff, nDstXSize, nDstYSize );
     416                 : 
     417              94 :     if( dfNoDataValue != VRT_NODATA_UNSET )
     418               0 :         poSimpleSource->SetNoDataValue( dfNoDataValue );
     419                 : 
     420                 : /* -------------------------------------------------------------------- */
     421                 : /*      Default source and dest rectangles.                             */
     422                 : /* -------------------------------------------------------------------- */
     423              94 :     if ( nSrcXOff == nDstXOff && nSrcYOff == nDstYOff &&
     424                 :          nSrcXSize == nDstXSize && nSrcYSize == nRasterYSize )
     425              58 :         bEqualAreas = TRUE;
     426                 : 
     427                 : /* -------------------------------------------------------------------- */
     428                 : /*      If we can get the associated GDALDataset, add a reference to it.*/
     429                 : /* -------------------------------------------------------------------- */
     430              94 :     if( poSrcBand->GetDataset() != NULL )
     431              94 :         poSrcBand->GetDataset()->Reference();
     432                 : 
     433                 : /* -------------------------------------------------------------------- */
     434                 : /*      add to list.                                                    */
     435                 : /* -------------------------------------------------------------------- */
     436              94 :     return AddSource( poSimpleSource );
     437                 : }
     438                 : 
     439                 : /************************************************************************/
     440                 : /*                         VRTAddSimpleSource()                         */
     441                 : /************************************************************************/
     442                 : 
     443                 : /**
     444                 :  * @see VRTSourcedRasterBand::AddSimpleSource().
     445                 :  */
     446                 : 
     447              34 : CPLErr CPL_STDCALL VRTAddSimpleSource( VRTSourcedRasterBandH hVRTBand,
     448                 :                                        GDALRasterBandH hSrcBand, 
     449                 :                                        int nSrcXOff, int nSrcYOff, 
     450                 :                                        int nSrcXSize, int nSrcYSize, 
     451                 :                                        int nDstXOff, int nDstYOff, 
     452                 :                                        int nDstXSize, int nDstYSize,
     453                 :                                        const char *pszResampling,
     454                 :                                        double dfNoDataValue )
     455                 : {
     456              34 :     VALIDATE_POINTER1( hVRTBand, "VRTAddSimpleSource", CE_Failure );
     457                 : 
     458                 :     return ((VRTSourcedRasterBand *) hVRTBand)->AddSimpleSource(
     459                 :                                             (GDALRasterBand *)hSrcBand, 
     460                 :                                             nSrcXOff, nSrcYOff, 
     461                 :                                             nSrcXSize, nSrcYSize, 
     462                 :                                             nDstXOff, nDstYOff, 
     463                 :                                             nDstXSize, nDstYSize,
     464              34 :                                             pszResampling, dfNoDataValue );
     465                 : }
     466                 : 
     467                 : /************************************************************************/
     468                 : /*                          AddComplexSource()                          */
     469                 : /************************************************************************/
     470                 : 
     471              18 : CPLErr VRTSourcedRasterBand::AddComplexSource( GDALRasterBand *poSrcBand, 
     472                 :                                                int nSrcXOff, int nSrcYOff, 
     473                 :                                                int nSrcXSize, int nSrcYSize, 
     474                 :                                                int nDstXOff, int nDstYOff, 
     475                 :                                                int nDstXSize, int nDstYSize,
     476                 :                                                double dfScaleOff,
     477                 :                                                double dfScaleRatio,
     478                 :                                                double dfNoDataValue,
     479                 :                                                int nColorTableComponent)
     480                 : 
     481                 : {
     482                 : /* -------------------------------------------------------------------- */
     483                 : /*      Default source and dest rectangles.                             */
     484                 : /* -------------------------------------------------------------------- */
     485              18 :     if( nSrcYSize == -1 )
     486                 :     {
     487               0 :         nSrcXOff = 0;
     488               0 :         nSrcYOff = 0;
     489               0 :         nSrcXSize = poSrcBand->GetXSize();
     490               0 :         nSrcYSize = poSrcBand->GetYSize();
     491                 :     }
     492                 : 
     493              18 :     if( nDstYSize == -1 )
     494                 :     {
     495               0 :         nDstXOff = 0;
     496               0 :         nDstYOff = 0;
     497               0 :         nDstXSize = nRasterXSize;
     498               0 :         nDstYSize = nRasterYSize;
     499                 :     }
     500                 : 
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Create source.                                                  */
     503                 : /* -------------------------------------------------------------------- */
     504                 :     VRTComplexSource *poSource;
     505                 : 
     506              18 :     poSource = new VRTComplexSource();
     507                 : 
     508              18 :     poSource->SetSrcBand( poSrcBand );
     509              18 :     poSource->SetSrcWindow( nSrcXOff, nSrcYOff, nSrcXSize, nSrcYSize );
     510              18 :     poSource->SetDstWindow( nDstXOff, nDstYOff, nDstXSize, nDstYSize );
     511                 : 
     512                 : /* -------------------------------------------------------------------- */
     513                 : /*      Set complex parameters.                                         */
     514                 : /* -------------------------------------------------------------------- */
     515              18 :     if( dfNoDataValue != VRT_NODATA_UNSET )
     516               8 :         poSource->SetNoDataValue( dfNoDataValue );
     517                 : 
     518              18 :     if( dfScaleOff != 0.0 || dfScaleRatio != 1.0 )
     519                 :     {
     520               0 :         poSource->bDoScaling = TRUE;
     521               0 :         poSource->dfScaleOff = dfScaleOff;
     522               0 :         poSource->dfScaleRatio = dfScaleRatio;
     523                 :           
     524                 :     }
     525                 : 
     526              18 :     poSource->nColorTableComponent = nColorTableComponent;
     527                 : 
     528                 : /* -------------------------------------------------------------------- */
     529                 : /*      If we can get the associated GDALDataset, add a reference to it.*/
     530                 : /* -------------------------------------------------------------------- */
     531              18 :     if( poSrcBand->GetDataset() != NULL )
     532              18 :         poSrcBand->GetDataset()->Reference();
     533                 : 
     534                 : /* -------------------------------------------------------------------- */
     535                 : /*      add to list.                                                    */
     536                 : /* -------------------------------------------------------------------- */
     537              18 :     return AddSource( poSource );
     538                 : }
     539                 : 
     540                 : /************************************************************************/
     541                 : /*                         VRTAddComplexSource()                        */
     542                 : /************************************************************************/
     543                 : 
     544                 : /**
     545                 :  * @see VRTSourcedRasterBand::AddComplexSource().
     546                 :  */
     547                 : 
     548               8 : CPLErr CPL_STDCALL VRTAddComplexSource( VRTSourcedRasterBandH hVRTBand,
     549                 :                                         GDALRasterBandH hSrcBand, 
     550                 :                                         int nSrcXOff, int nSrcYOff, 
     551                 :                                         int nSrcXSize, int nSrcYSize, 
     552                 :                                         int nDstXOff, int nDstYOff, 
     553                 :                                         int nDstXSize, int nDstYSize,
     554                 :                                         double dfScaleOff, 
     555                 :                                         double dfScaleRatio,
     556                 :                                         double dfNoDataValue )
     557                 : {
     558               8 :     VALIDATE_POINTER1( hVRTBand, "VRTAddComplexSource", CE_Failure );
     559                 : 
     560                 :     return ((VRTSourcedRasterBand *) hVRTBand)->AddComplexSource(
     561                 :                                             (GDALRasterBand *)hSrcBand, 
     562                 :                                             nSrcXOff, nSrcYOff, 
     563                 :                                             nSrcXSize, nSrcYSize, 
     564                 :                                             nDstXOff, nDstYOff, 
     565                 :                                             nDstXSize, nDstYSize,
     566                 :                                             dfScaleOff, dfScaleRatio,
     567               8 :                                             dfNoDataValue );
     568                 : }
     569                 : 
     570                 : /************************************************************************/
     571                 : /*                           AddFuncSource()                            */
     572                 : /************************************************************************/
     573                 : 
     574               0 : CPLErr VRTSourcedRasterBand::AddFuncSource( VRTImageReadFunc pfnReadFunc, 
     575                 :                                      void *pCBData, double dfNoDataValue )
     576                 : 
     577                 : {
     578                 : /* -------------------------------------------------------------------- */
     579                 : /*      Create source.                                                  */
     580                 : /* -------------------------------------------------------------------- */
     581               0 :     VRTFuncSource *poFuncSource = new VRTFuncSource;
     582                 : 
     583               0 :     poFuncSource->fNoDataValue = (float) dfNoDataValue;
     584               0 :     poFuncSource->pfnReadFunc = pfnReadFunc;
     585               0 :     poFuncSource->pCBData = pCBData;
     586               0 :     poFuncSource->eType = GetRasterDataType();
     587                 : 
     588                 : /* -------------------------------------------------------------------- */
     589                 : /*      add to list.                                                    */
     590                 : /* -------------------------------------------------------------------- */
     591               0 :     return AddSource( poFuncSource );
     592                 : }
     593                 : 
     594                 : /************************************************************************/
     595                 : /*                          VRTAddFuncSource()                          */
     596                 : /************************************************************************/
     597                 : 
     598                 : /**
     599                 :  * @see VRTSourcedRasterBand::AddFuncSource().
     600                 :  */
     601                 : 
     602               0 : CPLErr CPL_STDCALL VRTAddFuncSource( VRTSourcedRasterBandH hVRTBand,
     603                 :                                      VRTImageReadFunc pfnReadFunc, 
     604                 :                                      void *pCBData, double dfNoDataValue )
     605                 : {
     606               0 :     VALIDATE_POINTER1( hVRTBand, "VRTAddFuncSource", CE_Failure );
     607                 : 
     608                 :     return ((VRTSourcedRasterBand *) hVRTBand)->
     609               0 :         AddFuncSource( pfnReadFunc, pCBData, dfNoDataValue );
     610                 : }
     611                 : 
     612                 : /************************************************************************/
     613                 : /*                            GetMetadata()                             */
     614                 : /************************************************************************/
     615                 : 
     616             238 : char **VRTSourcedRasterBand::GetMetadata( const char *pszDomain )
     617                 : 
     618                 : {
     619             238 :     if( pszDomain != NULL && EQUAL(pszDomain,"vrt_sources") )
     620                 :     {
     621               0 :         char **papszSourceList = NULL;
     622                 : 
     623                 : /* -------------------------------------------------------------------- */
     624                 : /*      Process SimpleSources.                                          */
     625                 : /* -------------------------------------------------------------------- */
     626               0 :         for( int iSource = 0; iSource < nSources; iSource++ )
     627                 :         {
     628                 :             CPLXMLNode      *psXMLSrc;
     629                 :             char            *pszXML;
     630                 : 
     631               0 :             psXMLSrc = papoSources[iSource]->SerializeToXML( NULL );
     632               0 :             if( psXMLSrc == NULL )
     633               0 :                 continue;
     634                 : 
     635               0 :             pszXML = CPLSerializeXMLTree( psXMLSrc );
     636                 : 
     637                 :             papszSourceList = 
     638                 :                 CSLSetNameValue( papszSourceList, 
     639               0 :                                  CPLSPrintf( "source_%d", iSource ), pszXML );
     640               0 :             CPLFree( pszXML );
     641               0 :             CPLDestroyXMLNode( psXMLSrc );
     642                 :         }
     643                 :         
     644               0 :         return papszSourceList;
     645                 :     }
     646                 :     else
     647             238 :         return GDALRasterBand::GetMetadata( pszDomain );
     648                 : }
     649                 : 
     650                 : /************************************************************************/
     651                 : /*                          SetMetadataItem()                           */
     652                 : /************************************************************************/
     653                 : 
     654              12 : CPLErr VRTSourcedRasterBand::SetMetadataItem( const char *pszName, 
     655                 :                                               const char *pszValue, 
     656                 :                                               const char *pszDomain )
     657                 : 
     658                 : {
     659                 :     CPLDebug( "VRT", "VRTSourcedRasterBand::SetMetadataItem(%s,%s,%s)\n",
     660              12 :               pszName, pszValue, pszDomain );
     661                 :               
     662              12 :     if( pszDomain != NULL
     663                 :         && EQUAL(pszDomain,"new_vrt_sources") )
     664                 :     {
     665               1 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     666                 : 
     667               1 :         CPLXMLNode *psTree = CPLParseXMLString( pszValue );
     668                 :         VRTSource *poSource;
     669                 :         
     670               1 :         if( psTree == NULL )
     671               0 :             return CE_Failure;
     672                 :         
     673               1 :         poSource = poDriver->ParseSource( psTree, NULL );
     674               1 :         CPLDestroyXMLNode( psTree );
     675                 :         
     676               1 :         if( poSource != NULL )
     677               1 :             return AddSource( poSource );
     678                 :         else
     679               0 :             return CE_Failure;
     680                 :     }
     681              11 :     else if( pszDomain != NULL
     682                 :         && EQUAL(pszDomain,"vrt_sources") )
     683                 :     {
     684                 :         int iSource;
     685               1 :         if (sscanf(pszName, "source_%d", &iSource) != 1 || iSource < 0 ||
     686                 :             iSource >= nSources)
     687                 :         {
     688                 :             CPLError(CE_Failure, CPLE_AppDefined,
     689                 :                      "%s metadata item name is not recognized. "
     690                 :                      "Should be between source_0 and source_%d",
     691               0 :                      pszName, nSources - 1);
     692               0 :             return CE_Failure;
     693                 :         }
     694                 : 
     695               1 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     696                 : 
     697               1 :         CPLXMLNode *psTree = CPLParseXMLString( pszValue );
     698                 :         VRTSource *poSource;
     699                 :         
     700               1 :         if( psTree == NULL )
     701               0 :             return CE_Failure;
     702                 :         
     703               1 :         poSource = poDriver->ParseSource( psTree, NULL );
     704               1 :         CPLDestroyXMLNode( psTree );
     705                 :         
     706               1 :         if( poSource != NULL )
     707                 :         {
     708               1 :             delete papoSources[iSource];
     709               1 :             papoSources[iSource] = poSource;
     710               1 :             ((VRTDataset *)poDS)->SetNeedsFlush();
     711               1 :             return CE_None;
     712                 :         }
     713                 :         else
     714               0 :             return CE_Failure;
     715                 :     }
     716                 :     else
     717              10 :         return VRTRasterBand::SetMetadataItem( pszName, pszValue, pszDomain );
     718                 : }
     719                 : 
     720                 : /************************************************************************/
     721                 : /*                            SetMetadata()                             */
     722                 : /************************************************************************/
     723                 : 
     724              44 : CPLErr VRTSourcedRasterBand::SetMetadata( char **papszNewMD, const char *pszDomain )
     725                 : 
     726                 : {
     727              44 :     if( pszDomain != NULL
     728                 :         && (EQUAL(pszDomain,"new_vrt_sources") 
     729                 :             || EQUAL(pszDomain,"vrt_sources")) )
     730                 :     {
     731               1 :         VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" );
     732                 :         CPLErr eErr;
     733                 :         int    i;
     734                 : 
     735               1 :         if( EQUAL(pszDomain,"vrt_sources") )
     736                 :         {
     737               1 :             for( int i = 0; i < nSources; i++ )
     738               0 :                 delete papoSources[i];
     739               1 :             CPLFree( papoSources );
     740               1 :             papoSources = NULL;
     741               1 :             nSources = 0;
     742                 :         }
     743                 : 
     744               4 :         for( i = 0; i < CSLCount(papszNewMD); i++ )
     745                 :         {
     746               1 :             const char *pszXML = CPLParseNameValue( papszNewMD[i], NULL );
     747               1 :             CPLXMLNode *psTree = CPLParseXMLString( pszXML );
     748                 :             VRTSource *poSource;
     749                 :             
     750               1 :             if( psTree == NULL )
     751               0 :                 return CE_Failure;
     752                 : 
     753               1 :             poSource = poDriver->ParseSource( psTree, NULL );
     754               1 :             CPLDestroyXMLNode( psTree );
     755                 : 
     756               1 :             if( poSource != NULL )
     757                 :             {
     758               1 :                 eErr = AddSource( poSource );
     759               1 :                 if( eErr != CE_None )
     760               0 :                     return eErr;
     761                 :             }
     762                 :             else
     763               0 :                 return CE_Failure;
     764                 :         }
     765                 : 
     766               1 :         return CE_None;
     767                 :     }
     768                 :     else
     769              43 :         return VRTRasterBand::SetMetadata( papszNewMD, pszDomain );
     770                 : }
     771                 : 
     772                 : /************************************************************************/
     773                 : /*                             GetFileList()                            */
     774                 : /************************************************************************/
     775                 : 
     776               0 : void VRTSourcedRasterBand::GetFileList(char*** ppapszFileList, int *pnSize,
     777                 :                                        int *pnMaxSize, CPLHashSet* hSetFiles)
     778                 : {
     779               0 :     for( int i = 0; i < nSources; i++ )
     780                 :     {
     781               0 :         papoSources[i]->GetFileList(ppapszFileList, pnSize,
     782               0 :                                     pnMaxSize, hSetFiles);
     783                 :     }
     784               0 : }

Generated by: LCOV version 1.7