LCOV - code coverage report
Current view: directory - frmts/vrt - vrtdriver.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 119 100 84.0 %
Date: 2012-12-26 Functions: 11 7 63.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: vrtdriver.cpp 21945 2011-03-12 21:11:37Z warmerdam $
       3                 :  *
       4                 :  * Project:  Virtual GDAL Datasets
       5                 :  * Purpose:  Implementation of VRTDriver
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2003, 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                 : #include "gdal_alg_priv.h"
      34                 : 
      35                 : CPL_CVSID("$Id: vrtdriver.cpp 21945 2011-03-12 21:11:37Z warmerdam $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                             VRTDriver()                              */
      39                 : /************************************************************************/
      40                 : 
      41             561 : VRTDriver::VRTDriver()
      42                 : 
      43                 : {
      44             561 :     papszSourceParsers = NULL;
      45                 :     pDeserializerData = GDALRegisterTransformDeserializer("WarpedOverviewTransformer",
      46                 :                                                           VRTWarpedOverviewTransform,
      47             561 :                                                           VRTDeserializeWarpedOverviewTransformer);
      48             561 : }
      49                 : 
      50                 : /************************************************************************/
      51                 : /*                             ~VRTDriver()                             */
      52                 : /************************************************************************/
      53                 : 
      54             542 : VRTDriver::~VRTDriver()
      55                 : 
      56                 : {
      57             542 :     CSLDestroy( papszSourceParsers );
      58                 : 
      59             542 :     if ( pDeserializerData )
      60                 :     {
      61             542 :         GDALUnregisterTransformDeserializer( pDeserializerData );
      62                 :     }
      63             542 : }
      64                 : 
      65                 : /************************************************************************/
      66                 : /*                            GetMetadata()                             */
      67                 : /************************************************************************/
      68                 : 
      69              18 : char **VRTDriver::GetMetadata( const char *pszDomain )
      70                 : 
      71                 : {
      72              18 :     if( pszDomain && EQUAL(pszDomain,"SourceParsers") )
      73               0 :         return papszSourceParsers;
      74                 :     else
      75              18 :         return GDALDriver::GetMetadata( pszDomain );
      76                 : }
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                            SetMetadata()                             */
      80                 : /************************************************************************/
      81                 : 
      82               0 : CPLErr VRTDriver::SetMetadata( char **papszMetadata, const char *pszDomain )
      83                 : 
      84                 : {
      85               0 :     if( pszDomain && EQUAL(pszDomain,"SourceParsers") )
      86                 :     {
      87               0 :         CSLDestroy( papszSourceParsers );
      88               0 :         papszSourceParsers = CSLDuplicate( papszMetadata );
      89               0 :         return CE_None;
      90                 :     }
      91                 :     else
      92               0 :         return GDALDriver::SetMetadata( papszMetadata, pszDomain );
      93                 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                          AddSourceParser()                           */
      97                 : /************************************************************************/
      98                 : 
      99            2244 : void VRTDriver::AddSourceParser( const char *pszElementName, 
     100                 :                                  VRTSourceParser pfnParser )
     101                 : 
     102                 : {
     103                 :     char szPtrValue[128];
     104                 : 
     105            2244 :     sprintf( szPtrValue, "%p", pfnParser );
     106                 :     papszSourceParsers = CSLSetNameValue( papszSourceParsers, 
     107            2244 :                                           pszElementName, szPtrValue );
     108            2244 : }
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                            ParseSource()                             */
     112                 : /************************************************************************/
     113                 : 
     114             945 : VRTSource *VRTDriver::ParseSource( CPLXMLNode *psSrc, const char *pszVRTPath )
     115                 : 
     116                 : {
     117                 :     const char *pszParserFunc;
     118                 : 
     119             945 :     if( psSrc == NULL || psSrc->eType != CXT_Element )
     120                 :     {
     121                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     122               0 :                   "Corrupt or empty VRT source XML document." );
     123               0 :         return NULL;
     124                 :     }
     125                 : 
     126             945 :     pszParserFunc = CSLFetchNameValue( papszSourceParsers, psSrc->pszValue );
     127             945 :     if( pszParserFunc == NULL )
     128             484 :         return NULL;
     129                 : 
     130             461 :     VRTSourceParser pfnParser = NULL;
     131                 : 
     132             461 :     sscanf( pszParserFunc, "%p", &pfnParser );
     133                 : 
     134             461 :     if( pfnParser == NULL )
     135               0 :         return NULL;
     136                 :     else
     137             461 :         return pfnParser( psSrc, pszVRTPath );
     138                 : }
     139                 : 
     140                 : /************************************************************************/
     141                 : /*                           VRTCreateCopy()                            */
     142                 : /************************************************************************/
     143                 : 
     144                 : static GDALDataset *
     145             102 : VRTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     146                 :                int bStrict, char ** papszOptions, 
     147                 :                GDALProgressFunc pfnProgress, void * pProgressData )
     148                 : 
     149                 : {
     150             102 :     VRTDataset *poVRTDS = NULL;
     151                 : 
     152                 :     (void) bStrict;
     153                 :     (void) papszOptions;
     154                 : 
     155             102 :     CPLAssert( NULL != poSrcDS );
     156                 : 
     157                 : /* -------------------------------------------------------------------- */
     158                 : /*      If the source dataset is a virtual dataset then just write      */
     159                 : /*      it to disk as a special case to avoid extra layers of           */
     160                 : /*      indirection.                                                    */
     161                 : /* -------------------------------------------------------------------- */
     162             306 :     if( poSrcDS->GetDriver() != NULL &&
     163             204 :         EQUAL(poSrcDS->GetDriver()->GetDescription(),"VRT") )
     164                 :     {
     165                 : 
     166                 :     /* -------------------------------------------------------------------- */
     167                 :     /*      Convert tree to a single block of XML text.                     */
     168                 :     /* -------------------------------------------------------------------- */
     169               8 :         char *pszVRTPath = CPLStrdup(CPLGetPath(pszFilename));
     170               8 :         CPLXMLNode *psDSTree = ((VRTDataset *) poSrcDS)->SerializeToXML( pszVRTPath );
     171                 : 
     172               8 :         char *pszXML = CPLSerializeXMLTree( psDSTree );
     173                 :         
     174               8 :         CPLDestroyXMLNode( psDSTree );
     175                 : 
     176               8 :         CPLFree( pszVRTPath );
     177                 :         
     178                 :     /* -------------------------------------------------------------------- */
     179                 :     /*      Write to disk.                                                  */
     180                 :     /* -------------------------------------------------------------------- */
     181               8 :         GDALDataset* pCopyDS = NULL;
     182                 : 
     183               8 :         if( 0 != strlen( pszFilename ) )
     184                 :         {
     185               8 :             VSILFILE *fpVRT = NULL;
     186                 : 
     187               8 :             fpVRT = VSIFOpenL( pszFilename, "wb" );
     188               8 :             if (fpVRT == NULL)
     189                 :             {
     190                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     191               1 :                          "Cannot create %s", pszFilename);
     192               1 :                 CPLFree( pszXML );
     193               1 :                 return NULL;
     194                 :             }
     195                 : 
     196               7 :             VSIFWriteL( pszXML, 1, strlen(pszXML), fpVRT );
     197               7 :             VSIFCloseL( fpVRT );
     198                 : 
     199               7 :             pCopyDS = (GDALDataset *) GDALOpen( pszFilename, GA_Update );
     200                 :         }
     201                 :         else
     202                 :         {
     203                 :             /* No destination file is given, so pass serialized XML directly. */
     204                 : 
     205               0 :             pCopyDS = (GDALDataset *) GDALOpen( pszXML, GA_Update );
     206                 :         }
     207                 : 
     208               7 :         CPLFree( pszXML );
     209                 : 
     210               7 :         return pCopyDS;
     211                 :     }
     212                 : 
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      Create the virtual dataset.                                     */
     215                 : /* -------------------------------------------------------------------- */
     216                 :     poVRTDS = (VRTDataset *) 
     217                 :         VRTDataset::Create( pszFilename, 
     218                 :                             poSrcDS->GetRasterXSize(),
     219                 :                             poSrcDS->GetRasterYSize(),
     220              94 :                             0, GDT_Byte, NULL );
     221              94 :     if (poVRTDS == NULL)
     222               0 :         return NULL;
     223                 : 
     224                 : /* -------------------------------------------------------------------- */
     225                 : /*      Do we have a geotransform?                                      */
     226                 : /* -------------------------------------------------------------------- */
     227                 :     double adfGeoTransform[6];
     228                 : 
     229              94 :     if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
     230                 :     {
     231              94 :         poVRTDS->SetGeoTransform( adfGeoTransform );
     232                 :     }
     233                 : 
     234                 : /* -------------------------------------------------------------------- */
     235                 : /*      Copy projection                                                 */
     236                 : /* -------------------------------------------------------------------- */
     237              94 :     poVRTDS->SetProjection( poSrcDS->GetProjectionRef() );
     238                 : 
     239                 : /* -------------------------------------------------------------------- */
     240                 : /*      Emit dataset level metadata.                                    */
     241                 : /* -------------------------------------------------------------------- */
     242              94 :     poVRTDS->SetMetadata( poSrcDS->GetMetadata() );
     243                 : 
     244                 : /* -------------------------------------------------------------------- */
     245                 : /*      Copy any special domains that should be transportable.          */
     246                 : /* -------------------------------------------------------------------- */
     247                 :     char **papszMD;
     248                 : 
     249              94 :     papszMD = poSrcDS->GetMetadata( "RPC" );
     250              94 :     if( papszMD )
     251               0 :         poVRTDS->SetMetadata( papszMD, "RPC" );
     252                 : 
     253              94 :     papszMD = poSrcDS->GetMetadata( "IMD" );
     254              94 :     if( papszMD )
     255               0 :         poVRTDS->SetMetadata( papszMD, "IMD" );
     256                 : 
     257              94 :     papszMD = poSrcDS->GetMetadata( "GEOLOCATION" );
     258              94 :     if( papszMD )
     259               0 :         poVRTDS->SetMetadata( papszMD, "GEOLOCATION" );
     260                 : 
     261                 : /* -------------------------------------------------------------------- */
     262                 : /*      GCPs                                                            */
     263                 : /* -------------------------------------------------------------------- */
     264              94 :     if( poSrcDS->GetGCPCount() > 0 )
     265                 :     {
     266               1 :         poVRTDS->SetGCPs( poSrcDS->GetGCPCount(), 
     267               1 :                           poSrcDS->GetGCPs(),
     268               3 :                           poSrcDS->GetGCPProjection() );
     269                 :     }
     270                 : 
     271                 : /* -------------------------------------------------------------------- */
     272                 : /*      Loop over all the bands.          */
     273                 : /* -------------------------------------------------------------------- */
     274             205 :     for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
     275                 :     {
     276             111 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
     277                 : 
     278                 : /* -------------------------------------------------------------------- */
     279                 : /*      Create the band with the appropriate band type.                 */
     280                 : /* -------------------------------------------------------------------- */
     281             111 :         poVRTDS->AddBand( poSrcBand->GetRasterDataType(), NULL );
     282                 : 
     283                 :         VRTSourcedRasterBand *poVRTBand = 
     284             111 :             (VRTSourcedRasterBand *) poVRTDS->GetRasterBand( iBand+1 );
     285                 : 
     286                 : /* -------------------------------------------------------------------- */
     287                 : /*      Setup source mapping.                                           */
     288                 : /* -------------------------------------------------------------------- */
     289             111 :         poVRTBand->AddSimpleSource( poSrcBand );
     290                 : 
     291                 : /* -------------------------------------------------------------------- */
     292                 : /*      Emit various band level metadata.                               */
     293                 : /* -------------------------------------------------------------------- */
     294             111 :         poVRTBand->CopyCommonInfoFrom( poSrcBand );
     295                 : 
     296                 : /* -------------------------------------------------------------------- */
     297                 : /*      Add specific mask band.                                         */
     298                 : /* -------------------------------------------------------------------- */
     299             111 :         if ( (poSrcBand->GetMaskFlags() & (GMF_PER_DATASET | GMF_ALL_VALID | GMF_NODATA)) == 0)
     300                 :         {
     301                 :             VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand(poVRTDS, 0,
     302               0 :                 poSrcBand->GetMaskBand()->GetRasterDataType(),
     303               0 :                 poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize());
     304               0 :             poVRTMaskBand->AddMaskBandSource( poSrcBand );
     305               0 :             poVRTBand->SetMaskBand( poVRTMaskBand );
     306                 :         }
     307                 :     }
     308                 : 
     309                 : /* -------------------------------------------------------------------- */
     310                 : /*      Add dataset mask band                                           */
     311                 : /* -------------------------------------------------------------------- */
     312             187 :     if (poSrcDS->GetRasterCount() != 0 &&
     313                 :         poSrcDS->GetRasterBand(1) != NULL &&
     314              93 :         poSrcDS->GetRasterBand(1)->GetMaskFlags() == GMF_PER_DATASET)
     315                 :     {
     316               1 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
     317                 :         VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand(poVRTDS, 0,
     318               1 :             poSrcBand->GetMaskBand()->GetRasterDataType(),
     319               1 :             poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize());
     320               1 :         poVRTMaskBand->AddMaskBandSource( poSrcBand );
     321               1 :         poVRTDS->SetMaskBand( poVRTMaskBand );
     322                 :     }
     323                 : 
     324              94 :     poVRTDS->FlushCache();
     325                 : 
     326              94 :     return poVRTDS;
     327                 : }
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                          GDALRegister_VRT()                          */
     331                 : /************************************************************************/
     332                 : 
     333            1594 : void GDALRegister_VRT()
     334                 : 
     335                 : {
     336                 :     VRTDriver *poDriver;
     337                 : 
     338            1594 :     if( GDALGetDriverByName( "VRT" ) == NULL )
     339                 :     {
     340             561 :         poDriver = new VRTDriver();
     341                 :         
     342             561 :         poDriver->SetDescription( "VRT" );
     343                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     344             561 :                                    "Virtual Raster" );
     345             561 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "vrt" );
     346             561 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "gdal_vrttut.html" );
     347                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     348             561 :                                    "Byte Int16 UInt16 Int32 UInt32 Float32 Float64 CInt16 CInt32 CFloat32 CFloat64" );
     349                 :         
     350             561 :         poDriver->pfnOpen = VRTDataset::Open;
     351             561 :         poDriver->pfnCreateCopy = VRTCreateCopy;
     352             561 :         poDriver->pfnCreate = VRTDataset::Create;
     353             561 :         poDriver->pfnIdentify = VRTDataset::Identify;
     354             561 :         poDriver->pfnDelete = VRTDataset::Delete;
     355                 : 
     356             561 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     357                 : 
     358                 :         poDriver->AddSourceParser( "SimpleSource", 
     359             561 :                                    VRTParseCoreSources );
     360                 :         poDriver->AddSourceParser( "ComplexSource", 
     361             561 :                                    VRTParseCoreSources );
     362                 :         poDriver->AddSourceParser( "AveragedSource", 
     363             561 :                                    VRTParseCoreSources );
     364                 : 
     365                 :         poDriver->AddSourceParser( "KernelFilteredSource", 
     366             561 :                                    VRTParseFilterSources );
     367                 : 
     368             561 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     369                 :     }
     370            1594 : }
     371                 : 

Generated by: LCOV version 1.7