LCOV - code coverage report
Current view: directory - frmts/vrt - vrtrawrasterband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 134 86 64.2 %
Date: 2012-12-26 Functions: 13 8 61.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: vrtrawrasterband.cpp 22776 2011-07-23 18:07:58Z rouault $
       3                 :  *
       4                 :  * Project:  Virtual GDAL Datasets
       5                 :  * Purpose:  Implementation of VRTRawRasterBand
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, 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 "rawdataset.h"
      34                 : 
      35                 : CPL_CVSID("$Id: vrtrawrasterband.cpp 22776 2011-07-23 18:07:58Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /* ==================================================================== */
      39                 : /*                          VRTRawRasterBand                            */
      40                 : /* ==================================================================== */
      41                 : /************************************************************************/
      42                 : 
      43                 : /************************************************************************/
      44                 : /*                          VRTRawRasterBand()                          */
      45                 : /************************************************************************/
      46                 : 
      47              13 : VRTRawRasterBand::VRTRawRasterBand( GDALDataset *poDS, int nBand,
      48              13 :                                     GDALDataType eType )
      49                 : 
      50                 : {
      51              13 :     Initialize( poDS->GetRasterXSize(), poDS->GetRasterYSize() );
      52                 : 
      53              13 :     this->poDS = poDS;
      54              13 :     this->nBand = nBand;
      55                 : 
      56              13 :     if( eType != GDT_Unknown )
      57               2 :         this->eDataType = eType;
      58                 : 
      59              13 :     poRawRaster = NULL;
      60              13 :     pszSourceFilename = NULL;
      61              13 : }
      62                 : 
      63                 : /************************************************************************/
      64                 : /*                         ~VRTRawRasterBand()                          */
      65                 : /************************************************************************/
      66                 : 
      67              13 : VRTRawRasterBand::~VRTRawRasterBand()
      68                 : 
      69                 : {
      70              13 :     FlushCache();
      71              13 :     ClearRawLink();
      72              13 : }
      73                 : 
      74                 : /************************************************************************/
      75                 : /*                             IRasterIO()                              */
      76                 : /************************************************************************/
      77                 : 
      78             353 : CPLErr VRTRawRasterBand::IRasterIO( GDALRWFlag eRWFlag,
      79                 :                                  int nXOff, int nYOff, int nXSize, int nYSize,
      80                 :                                  void * pData, int nBufXSize, int nBufYSize,
      81                 :                                  GDALDataType eBufType,
      82                 :                                  int nPixelSpace, int nLineSpace )
      83                 : 
      84                 : {
      85             353 :     if( poRawRaster == NULL )
      86                 :     {
      87                 :         CPLError( CE_Failure, CPLE_AppDefined, 
      88               0 :                   "No raw raster band configured on VRTRawRasterBand." );
      89               0 :         return CE_Failure;
      90                 :     }
      91                 : 
      92             353 :     if( eRWFlag == GF_Write && eAccess == GA_ReadOnly )
      93                 :     {
      94                 :         CPLError( CE_Failure, CPLE_NoWriteAccess,
      95                 :                   "Attempt to write to read only dataset in"
      96               0 :                   "VRTRawRasterBand::IRasterIO().\n" );
      97                 : 
      98               0 :         return( CE_Failure );
      99                 :     }
     100                 :     
     101                 : /* -------------------------------------------------------------------- */
     102                 : /*      Do we have overviews that would be appropriate to satisfy       */
     103                 : /*      this request?                                                   */
     104                 : /* -------------------------------------------------------------------- */
     105             353 :     if( (nBufXSize < nXSize || nBufYSize < nYSize)
     106               0 :         && GetOverviewCount() > 0 )
     107                 :     {
     108               0 :         if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
     109                 :                               pData, nBufXSize, nBufYSize, 
     110                 :                               eBufType, nPixelSpace, nLineSpace ) == CE_None )
     111               0 :             return CE_None;
     112                 :     }
     113                 :     
     114             353 :     poRawRaster->SetAccess(eAccess);
     115                 : 
     116                 :     return poRawRaster->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
     117                 :                                   pData, nBufXSize, nBufYSize, 
     118             353 :                                   eBufType, nPixelSpace, nLineSpace );
     119                 : }
     120                 : 
     121                 : /************************************************************************/
     122                 : /*                             IReadBlock()                             */
     123                 : /************************************************************************/
     124                 : 
     125              35 : CPLErr VRTRawRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     126                 :                                    void * pImage )
     127                 : 
     128                 : {
     129              35 :     if( poRawRaster == NULL )
     130                 :     {
     131                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     132               0 :                   "No raw raster band configured on VRTRawRasterBand." );
     133               0 :         return CE_Failure;
     134                 :     }
     135                 : 
     136              35 :     return poRawRaster->ReadBlock( nBlockXOff, nBlockYOff, pImage );
     137                 : }
     138                 : 
     139                 : /************************************************************************/
     140                 : /*                            IWriteBlock()                             */
     141                 : /************************************************************************/
     142                 : 
     143               0 : CPLErr VRTRawRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
     144                 :                                       void * pImage )
     145                 : 
     146                 : {
     147               0 :     if( poRawRaster == NULL )
     148                 :     {
     149                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     150               0 :                   "No raw raster band configured on VRTRawRasterBand." );
     151               0 :         return CE_Failure;
     152                 :     }
     153                 :     
     154               0 :     poRawRaster->SetAccess(eAccess);
     155                 :     
     156               0 :     return poRawRaster->WriteBlock( nBlockXOff, nBlockYOff, pImage );
     157                 : }
     158                 : 
     159                 : /************************************************************************/
     160                 : /*                             SetRawLink()                             */
     161                 : /************************************************************************/
     162                 : 
     163              13 : CPLErr VRTRawRasterBand::SetRawLink( const char *pszFilename, 
     164                 :                                      const char *pszVRTPath,
     165                 :                                      int bRelativeToVRT, 
     166                 :                                      vsi_l_offset nImageOffset, 
     167                 :                                      int nPixelOffset, int nLineOffset, 
     168                 :                                      const char *pszByteOrder )
     169                 : 
     170                 : {
     171              13 :     ClearRawLink();
     172                 : 
     173              13 :     ((VRTDataset *)poDS)->SetNeedsFlush();
     174                 : 
     175                 : /* -------------------------------------------------------------------- */
     176                 : /*      Prepare filename.                                               */
     177                 : /* -------------------------------------------------------------------- */
     178              13 :     char *pszExpandedFilename = NULL;
     179                 : 
     180              13 :     if( pszFilename == NULL )
     181                 :     {
     182                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     183               0 :                   "Missing <SourceFilename> element in VRTRasterBand." );
     184               0 :         return CE_Failure;
     185                 :     }
     186                 :     
     187              21 :     if( pszVRTPath != NULL && bRelativeToVRT )
     188                 :     {
     189                 :         pszExpandedFilename = CPLStrdup(
     190               8 :             CPLProjectRelativeFilename( pszVRTPath, pszFilename ) );
     191                 :     }
     192                 :     else
     193               5 :         pszExpandedFilename = CPLStrdup( pszFilename );
     194                 : 
     195                 : /* -------------------------------------------------------------------- */
     196                 : /*      Try and open the file.  We always use the large file API.       */
     197                 : /* -------------------------------------------------------------------- */
     198              13 :     FILE *fp = CPLOpenShared( pszExpandedFilename, "rb+", TRUE );
     199                 : 
     200              13 :     if( fp == NULL )
     201               0 :         fp = CPLOpenShared( pszExpandedFilename, "rb", TRUE );
     202                 : 
     203              13 :     if( fp == NULL && ((VRTDataset *)poDS)->GetAccess() == GA_Update )
     204                 :     {
     205               0 :         fp = CPLOpenShared( pszExpandedFilename, "wb+", TRUE );
     206                 :     }
     207                 : 
     208              13 :     if( fp == NULL )
     209                 :     {
     210                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     211                 :                   "Unable to open %s.\n%s", 
     212                 :                   pszExpandedFilename,
     213               0 :                   VSIStrerror( errno ) );
     214                 :         
     215               0 :         CPLFree( pszExpandedFilename );
     216               0 :         return CE_Failure;
     217                 :     }
     218                 : 
     219              13 :     CPLFree( pszExpandedFilename );
     220                 : 
     221              13 :     pszSourceFilename = CPLStrdup(pszFilename);
     222              13 :     this->bRelativeToVRT = bRelativeToVRT;
     223                 : 
     224                 : /* -------------------------------------------------------------------- */
     225                 : /*      Work out if we are in native mode or not.                       */
     226                 : /* -------------------------------------------------------------------- */
     227              13 :     int bNative = TRUE;
     228                 : 
     229              13 :     if( pszByteOrder != NULL )
     230                 :     {
     231              12 :         if( EQUAL(pszByteOrder,"LSB") )
     232              10 :             bNative = CPL_IS_LSB;
     233               2 :         else if( EQUAL(pszByteOrder,"MSB") )
     234               2 :             bNative = !CPL_IS_LSB;
     235                 :         else
     236                 :         {
     237                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     238                 :                       "Illegal ByteOrder value '%s', should be LSB or MSB.", 
     239               0 :                       pszByteOrder );
     240               0 :             return CE_Failure;
     241                 :         }
     242                 :     }
     243                 : 
     244                 : /* -------------------------------------------------------------------- */
     245                 : /*      Create a corresponding RawRasterBand.                           */
     246                 : /* -------------------------------------------------------------------- */
     247                 :     poRawRaster = new RawRasterBand( fp, nImageOffset, nPixelOffset, 
     248                 :                                      nLineOffset, GetRasterDataType(), 
     249              13 :                                      bNative, GetXSize(), GetYSize(), TRUE );
     250                 : 
     251                 : /* -------------------------------------------------------------------- */
     252                 : /*      Reset block size to match the raw raster.                       */
     253                 : /* -------------------------------------------------------------------- */
     254              13 :     poRawRaster->GetBlockSize( &nBlockXSize, &nBlockYSize );
     255                 : 
     256              13 :     return CE_None;
     257                 : }
     258                 : 
     259                 : /************************************************************************/
     260                 : /*                            ClearRawLink()                            */
     261                 : /************************************************************************/
     262                 : 
     263              26 : void VRTRawRasterBand::ClearRawLink()
     264                 : 
     265                 : {
     266              26 :     if( poRawRaster != NULL )
     267                 :     {
     268              13 :         VSILFILE* fp = poRawRaster->GetFPL();
     269              13 :         delete poRawRaster;
     270              13 :         poRawRaster = NULL;
     271                 :         /* We close the file after deleting the raster band */
     272                 :         /* since data can be flushed in the destructor */
     273              13 :         if( fp != NULL )
     274                 :         {
     275              13 :             CPLCloseShared( (FILE*) fp );
     276                 :         }
     277                 :     }
     278              26 :     CPLFree( pszSourceFilename );
     279              26 :     pszSourceFilename = NULL;
     280              26 : }
     281                 : 
     282                 : /************************************************************************/
     283                 : /*                              XMLInit()                               */
     284                 : /************************************************************************/
     285                 : 
     286              11 : CPLErr VRTRawRasterBand::XMLInit( CPLXMLNode * psTree, 
     287                 :                                       const char *pszVRTPath )
     288                 : 
     289                 : {
     290                 :     CPLErr eErr;
     291                 : 
     292              11 :     eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath );
     293              11 :     if( eErr != CE_None )
     294               0 :         return eErr;
     295                 :     
     296                 : 
     297                 : /* -------------------------------------------------------------------- */
     298                 : /*      Validate a bit.                                                 */
     299                 : /* -------------------------------------------------------------------- */
     300              11 :     if( psTree == NULL || psTree->eType != CXT_Element
     301                 :         || !EQUAL(psTree->pszValue,"VRTRasterBand") 
     302                 :         || !EQUAL(CPLGetXMLValue(psTree,"subClass",""),"VRTRawRasterBand") )
     303                 :     {
     304                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     305               0 :                   "Invalid node passed to VRTRawRasterBand::XMLInit()." );
     306               0 :         return CE_Failure;
     307                 :     }
     308                 : 
     309                 : /* -------------------------------------------------------------------- */
     310                 : /*      Prepare filename.                                               */
     311                 : /* -------------------------------------------------------------------- */
     312                 :     int  bRelativeToVRT;
     313                 : 
     314                 :     const char *pszFilename = 
     315              11 :         CPLGetXMLValue(psTree, "SourceFilename", NULL);
     316                 : 
     317              11 :     if( pszFilename == NULL )
     318                 :     {
     319                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     320               0 :                   "Missing <SourceFilename> element in VRTRasterBand." );
     321               0 :         return CE_Failure;
     322                 :     }
     323                 : 
     324                 :     bRelativeToVRT = atoi(CPLGetXMLValue(psTree,"SourceFilename.relativeToVRT",
     325              11 :                                          "1"));
     326                 :     
     327                 : /* -------------------------------------------------------------------- */
     328                 : /*      Collect layout information.                                     */
     329                 : /* -------------------------------------------------------------------- */
     330                 :     vsi_l_offset nImageOffset;
     331                 :     int nPixelOffset, nLineOffset;
     332              11 :     int nWordDataSize = GDALGetDataTypeSize( GetRasterDataType() ) / 8;
     333                 : 
     334              11 :     nImageOffset = atoi(CPLGetXMLValue( psTree, "ImageOffset", "0") );
     335                 : 
     336              11 :     if( CPLGetXMLValue( psTree, "PixelOffset", NULL ) == NULL )
     337               0 :         nPixelOffset = nWordDataSize;
     338                 :     else
     339              11 :         nPixelOffset = atoi(CPLGetXMLValue( psTree, "PixelOffset", "0") );
     340              11 :     if (nPixelOffset <= 0)
     341                 :     {
     342                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     343               0 :                   "Invalid value for <PixelOffset> element : %d", nPixelOffset );
     344               0 :         return CE_Failure;
     345                 :     }
     346                 :     
     347              11 :     if( CPLGetXMLValue( psTree, "LineOffset", NULL ) == NULL )
     348               0 :         nLineOffset = nWordDataSize * GetXSize();
     349                 :     else
     350              11 :         nLineOffset = atoi(CPLGetXMLValue( psTree, "LineOffset", "0") );
     351                 : 
     352              11 :     const char *pszByteOrder = CPLGetXMLValue( psTree, "ByteOrder", NULL );
     353                 : 
     354                 : /* -------------------------------------------------------------------- */
     355                 : /*      Open the file, and setup the raw layer access to the data.      */
     356                 : /* -------------------------------------------------------------------- */
     357                 :     return SetRawLink( pszFilename, pszVRTPath, bRelativeToVRT, 
     358                 :                        nImageOffset, nPixelOffset, nLineOffset, 
     359              11 :                        pszByteOrder );
     360                 : }
     361                 : 
     362                 : /************************************************************************/
     363                 : /*                           SerializeToXML()                           */
     364                 : /************************************************************************/
     365                 : 
     366               3 : CPLXMLNode *VRTRawRasterBand::SerializeToXML( const char *pszVRTPath )
     367                 : 
     368                 : {
     369                 :     CPLXMLNode *psTree;
     370                 : 
     371               3 :     psTree = VRTRasterBand::SerializeToXML( pszVRTPath );
     372                 : 
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      Set subclass.                                                   */
     375                 : /* -------------------------------------------------------------------- */
     376                 :     CPLCreateXMLNode( 
     377                 :         CPLCreateXMLNode( psTree, CXT_Attribute, "subClass" ), 
     378               3 :         CXT_Text, "VRTRawRasterBand" );
     379                 : 
     380                 : /* -------------------------------------------------------------------- */
     381                 : /*      Setup the filename with relative flag.                          */
     382                 : /* -------------------------------------------------------------------- */
     383                 :     CPLXMLNode *psNode;
     384                 : 
     385                 :     psNode = 
     386                 :         CPLCreateXMLElementAndValue( psTree, "SourceFilename", 
     387               3 :                                      pszSourceFilename );
     388                 :     
     389                 :     CPLCreateXMLNode( 
     390                 :         CPLCreateXMLNode( psNode, CXT_Attribute, "relativeToVRT" ), 
     391               3 :         CXT_Text, bRelativeToVRT ? "1" : "0"  );
     392                 : 
     393                 : /* -------------------------------------------------------------------- */
     394                 : /*      We can't set the layout if there is no open rawband.            */
     395                 : /* -------------------------------------------------------------------- */
     396               3 :     if( poRawRaster == NULL )
     397                 :     {
     398                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     399               0 :                   "VRTRawRasterBand::SerializeToXML() fails because poRawRaster is NULL." );
     400               0 :         return NULL;
     401                 :     }
     402                 : 
     403                 : /* -------------------------------------------------------------------- */
     404                 : /*      Set other layout information.                                   */
     405                 : /* -------------------------------------------------------------------- */
     406                 :     CPLCreateXMLElementAndValue( 
     407                 :         psTree, "ImageOffset", 
     408               3 :         CPLSPrintf("%d",(int) poRawRaster->GetImgOffset()) );
     409                 :     
     410                 :     CPLCreateXMLElementAndValue( 
     411                 :         psTree, "PixelOffset", 
     412               3 :         CPLSPrintf("%d",(int) poRawRaster->GetPixelOffset()) );
     413                 :     
     414                 :     CPLCreateXMLElementAndValue( 
     415                 :         psTree, "LineOffset", 
     416               3 :         CPLSPrintf("%d",(int) poRawRaster->GetLineOffset()) );
     417                 : 
     418               3 :     if( (poRawRaster->GetNativeOrder() && CPL_IS_LSB)
     419                 :         || (!poRawRaster->GetNativeOrder() && !CPL_IS_LSB) )
     420               2 :         CPLCreateXMLElementAndValue( psTree, "ByteOrder", "LSB" );
     421                 :     else
     422               1 :         CPLCreateXMLElementAndValue( psTree, "ByteOrder", "MSB" );
     423                 :     
     424               3 :     return psTree;
     425                 : }
     426                 : 
     427                 : /************************************************************************/
     428                 : /*                             GetFileList()                            */
     429                 : /************************************************************************/
     430                 : 
     431               0 : void VRTRawRasterBand::GetFileList(char*** ppapszFileList, int *pnSize,
     432                 :                                 int *pnMaxSize, CPLHashSet* hSetFiles)
     433                 : {
     434               0 :     if (pszSourceFilename == NULL)
     435               0 :         return;
     436                 :         
     437                 : /* -------------------------------------------------------------------- */
     438                 : /*      Is it already in the list ?                                     */
     439                 : /* -------------------------------------------------------------------- */
     440               0 :     if( CPLHashSetLookup(hSetFiles, pszSourceFilename) != NULL )
     441               0 :         return;
     442                 :         
     443                 : /* -------------------------------------------------------------------- */
     444                 : /*      Grow array if necessary                                         */
     445                 : /* -------------------------------------------------------------------- */
     446               0 :     if (*pnSize + 1 >= *pnMaxSize)
     447                 :     {
     448               0 :         *pnMaxSize = 2 + 2 * (*pnMaxSize);
     449                 :         *ppapszFileList = (char **) CPLRealloc(
     450               0 :                     *ppapszFileList, sizeof(char*)  * (*pnMaxSize) );
     451                 :     }
     452                 :             
     453                 : /* -------------------------------------------------------------------- */
     454                 : /*      Add the string to the list                                      */
     455                 : /* -------------------------------------------------------------------- */
     456               0 :     (*ppapszFileList)[*pnSize] = CPLStrdup(pszSourceFilename);
     457               0 :     (*ppapszFileList)[(*pnSize + 1)] = NULL;
     458               0 :     CPLHashSetInsert(hSetFiles, (*ppapszFileList)[*pnSize]);
     459                 :     
     460               0 :     (*pnSize) ++;
     461                 : 
     462                 :     VRTRasterBand::GetFileList( ppapszFileList, pnSize,
     463               0 :                                 pnMaxSize, hSetFiles);
     464                 : }

Generated by: LCOV version 1.7