LCOV - code coverage report
Current view: directory - gcore - gdaldataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 604 492 81.5 %
Date: 2013-03-30 Functions: 86 72 83.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdaldataset.cpp 25716 2013-03-09 12:09:29Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Base class for raster file formats.  
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1998, 2003, Frank Warmerdam
      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 "gdal_priv.h"
      31                 : #include "cpl_string.h"
      32                 : #include "cpl_hash_set.h"
      33                 : #include "cpl_multiproc.h"
      34                 : #include <map>
      35                 : 
      36                 : CPL_CVSID("$Id: gdaldataset.cpp 25716 2013-03-09 12:09:29Z rouault $");
      37                 : 
      38                 : CPL_C_START
      39                 : GDALAsyncReader *
      40                 : GDALGetDefaultAsyncReader( GDALDataset *poDS,
      41                 :                              int nXOff, int nYOff,
      42                 :                              int nXSize, int nYSize,
      43                 :                              void *pBuf,
      44                 :                              int nBufXSize, int nBufYSize,
      45                 :                              GDALDataType eBufType,
      46                 :                              int nBandCount, int* panBandMap,
      47                 :                              int nPixelSpace, int nLineSpace,
      48                 :                              int nBandSpace, char **papszOptions);
      49                 : CPL_C_END
      50                 : 
      51                 : typedef struct
      52                 : {
      53                 :     /* PID of the thread that mark the dataset as shared */
      54                 :     /* This may not be the actual PID, but the responsiblePID */
      55                 :     GIntBig      nPID;
      56                 :     char        *pszDescription;
      57                 :     GDALAccess   eAccess;
      58                 : 
      59                 :     GDALDataset *poDS;
      60                 : } SharedDatasetCtxt;
      61                 : 
      62                 : typedef struct
      63                 : {
      64                 :     GDALDataset *poDS;
      65                 :     /* In the case of a shared dataset, memorize the PID of the thread */
      66                 :     /* that marked the dataset as shared, so that we can remove it from */
      67                 :     /* the phSharedDatasetSet in the destructor of the dataset, even */
      68                 :     /* if GDALClose is called from a different thread */
      69                 :     /* Ideally, this should be stored in the GDALDataset object itself */
      70                 :     /* but this is inconvenient to change the object size at that time */
      71                 :     GIntBig      nPIDCreatorForShared; 
      72                 : } DatasetCtxt;
      73                 : 
      74                 : /* Set of datasets opened as shared datasets (with GDALOpenShared) */
      75                 : /* The values in the set are of type SharedDatasetCtxt */
      76                 : static CPLHashSet* phSharedDatasetSet = NULL; 
      77                 : 
      78                 : /* Set of all datasets created in the constructor of GDALDataset */
      79                 : /* The values in the set are of type DatasetCtxt */
      80                 : static CPLHashSet* phAllDatasetSet = NULL;
      81                 : static void *hDLMutex = NULL;
      82                 : 
      83                 : /* Static array of all datasets. Used by GDALGetOpenDatasets */
      84                 : /* Not thread-safe. See GDALGetOpenDatasets */
      85                 : static GDALDataset** ppDatasets = NULL;
      86                 : 
      87            6835 : static unsigned long GDALSharedDatasetHashFunc(const void* elt)
      88                 : {
      89            6835 :     SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
      90            6835 :     return (unsigned long) (CPLHashSetHashStr(psStruct->pszDescription) ^ psStruct->eAccess ^ psStruct->nPID);
      91                 : }
      92                 : 
      93            5654 : static int GDALSharedDatasetEqualFunc(const void* elt1, const void* elt2)
      94                 : {
      95            5654 :     SharedDatasetCtxt* psStruct1 = (SharedDatasetCtxt*) elt1;
      96            5654 :     SharedDatasetCtxt* psStruct2 = (SharedDatasetCtxt*) elt2;
      97                 :     return strcmp(psStruct1->pszDescription, psStruct2->pszDescription) == 0 &&
      98                 :            psStruct1->nPID == psStruct2->nPID &&
      99            5654 :            psStruct1->eAccess == psStruct2->eAccess;
     100                 : }
     101                 : 
     102             299 : static void GDALSharedDatasetFreeFunc(void* elt)
     103                 : {
     104             299 :     SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
     105             299 :     CPLFree(psStruct->pszDescription);
     106             299 :     CPLFree(psStruct);
     107             299 : }
     108                 : 
     109           86688 : static unsigned long GDALDatasetHashFunc(const void* elt)
     110                 : {
     111           86688 :     DatasetCtxt* psStruct = (DatasetCtxt*) elt;
     112           86688 :     return (unsigned long)(GUIntBig) psStruct->poDS;
     113                 : }
     114                 : 
     115           41644 : static int GDALDatasetEqualFunc(const void* elt1, const void* elt2)
     116                 : {
     117           41644 :     DatasetCtxt* psStruct1 = (DatasetCtxt*) elt1;
     118           41644 :     DatasetCtxt* psStruct2 = (DatasetCtxt*) elt2;
     119           41644 :     return psStruct1->poDS == psStruct2->poDS ;
     120                 : }
     121                 : 
     122           16714 : static void GDALDatasetFreeFunc(void* elt)
     123                 : {
     124           16714 :     DatasetCtxt* psStruct = (DatasetCtxt*) elt;
     125           16714 :     CPLFree(psStruct);
     126           16714 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /* Functions shared between gdalproxypool.cpp and gdaldataset.cpp */
     130                 : /************************************************************************/
     131                 : 
     132                 : /* The open-shared mutex must be used by the ProxyPool too */
     133           32376 : void** GDALGetphDLMutex()
     134                 : {
     135           32376 :     return &hDLMutex;
     136                 : }
     137                 : 
     138                 : /* The current thread will act in the behalf of the thread of PID responsiblePID */
     139           29270 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID)
     140                 : {
     141           29270 :     GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
     142           29270 :     if (pResponsiblePID == NULL)
     143                 :     {
     144              93 :         pResponsiblePID = (GIntBig*) CPLMalloc(sizeof(GIntBig));
     145              93 :         CPLSetTLS(CTLS_RESPONSIBLEPID, pResponsiblePID, TRUE);
     146                 :     }
     147           29270 :     *pResponsiblePID = responsiblePID;
     148           29270 : }
     149                 : 
     150                 : /* Get the PID of the thread that the current thread will act in the behalf of */
     151                 : /* By default : the current thread acts in the behalf of itself */
     152           58819 : GIntBig GDALGetResponsiblePIDForCurrentThread()
     153                 : {
     154           58819 :     GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
     155           58819 :     if (pResponsiblePID == NULL)
     156            2242 :         return CPLGetPID();
     157           56577 :     return *pResponsiblePID;
     158                 : }
     159                 : 
     160                 : 
     161                 : /************************************************************************/
     162                 : /* ==================================================================== */
     163                 : /*                             GDALDataset                              */
     164                 : /* ==================================================================== */
     165                 : /************************************************************************/
     166                 : 
     167                 : /**
     168                 :  * \class GDALDataset "gdal_priv.h"
     169                 :  *
     170                 :  * A dataset encapsulating one or more raster bands.  Details are
     171                 :  * further discussed in the <a href="gdal_datamodel.html#GDALDataset">GDAL
     172                 :  * Data Model</a>.
     173                 :  *
     174                 :  * Use GDALOpen() or GDALOpenShared() to create a GDALDataset for a named file,
     175                 :  * or GDALDriver::Create() or GDALDriver::CreateCopy() to create a new 
     176                 :  * dataset.
     177                 :  */
     178                 : 
     179                 : /************************************************************************/
     180                 : /*                            GDALDataset()                             */
     181                 : /************************************************************************/
     182                 : 
     183           16714 : GDALDataset::GDALDataset()
     184                 : 
     185                 : {
     186           16714 :     poDriver = NULL;
     187           16714 :     eAccess = GA_ReadOnly;
     188           16714 :     nRasterXSize = 512;
     189           16714 :     nRasterYSize = 512;
     190           16714 :     nBands = 0;
     191           16714 :     papoBands = NULL;
     192           16714 :     nRefCount = 1;
     193           16714 :     bShared = FALSE;
     194                 : 
     195                 : /* -------------------------------------------------------------------- */
     196                 : /*      Add this dataset to the open dataset list.                      */
     197                 : /* -------------------------------------------------------------------- */
     198                 :     {
     199           16714 :         CPLMutexHolderD( &hDLMutex );
     200                 : 
     201           16714 :         if (phAllDatasetSet == NULL)
     202             643 :             phAllDatasetSet = CPLHashSetNew(GDALDatasetHashFunc, GDALDatasetEqualFunc, GDALDatasetFreeFunc);
     203           16714 :         DatasetCtxt* ctxt = (DatasetCtxt*)CPLMalloc(sizeof(DatasetCtxt));
     204           16714 :         ctxt->poDS = this;
     205           16714 :         ctxt->nPIDCreatorForShared = -1;
     206           16714 :         CPLHashSetInsert(phAllDatasetSet, ctxt);
     207                 :     }
     208                 : 
     209                 : /* -------------------------------------------------------------------- */
     210                 : /*      Set forced caching flag.                                        */
     211                 : /* -------------------------------------------------------------------- */
     212                 :     bForceCachedIO =  CSLTestBoolean( 
     213           16714 :         CPLGetConfigOption( "GDAL_FORCE_CACHING", "NO") );
     214           16714 : }
     215                 : 
     216                 : 
     217                 : /************************************************************************/
     218                 : /*                            ~GDALDataset()                            */
     219                 : /************************************************************************/
     220                 : 
     221                 : /**
     222                 :  * \brief Destroy an open GDALDataset.
     223                 :  *
     224                 :  * This is the accepted method of closing a GDAL dataset and deallocating
     225                 :  * all resources associated with it.
     226                 :  *
     227                 :  * Equivalent of the C callable GDALClose().  Except that GDALClose() first
     228                 :  * decrements the reference count, and then closes only if it has dropped to
     229                 :  * zero.
     230                 :  *
     231                 :  * For Windows users, it is not recommended to use the delete operator on the
     232                 :  * dataset object because of known issues when allocating and freeing memory across
     233                 :  * module boundaries. Calling GDALClose() is then a better option.
     234                 :  */
     235                 : 
     236           16714 : GDALDataset::~GDALDataset()
     237                 : 
     238                 : {
     239                 :     int         i;
     240                 : 
     241                 :     // we don't want to report destruction of datasets that 
     242                 :     // were never really open.
     243           16714 :     if( nBands != 0 || !EQUAL(GetDescription(),"") )
     244                 :     {
     245           16189 :         if( CPLGetPID() != GDALGetResponsiblePIDForCurrentThread() )
     246                 :             CPLDebug( "GDAL", 
     247                 :                       "GDALClose(%s, this=%p) (pid=%d, responsiblePID=%d)", GetDescription(), this,
     248                 :                       (int)CPLGetPID(), 
     249               0 :                       (int)GDALGetResponsiblePIDForCurrentThread() );
     250                 :         else
     251                 :             CPLDebug( "GDAL", 
     252           16189 :                       "GDALClose(%s, this=%p)", GetDescription(), this );
     253                 :     }
     254                 : 
     255                 : /* -------------------------------------------------------------------- */
     256                 : /*      Remove dataset from the "open" dataset list.                    */
     257                 : /* -------------------------------------------------------------------- */
     258                 :     {
     259           16714 :         CPLMutexHolderD( &hDLMutex );
     260           16714 :         if( phAllDatasetSet )
     261                 :         {
     262                 :             DatasetCtxt sStruct;
     263           16714 :             sStruct.poDS = this;
     264           16714 :             DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
     265           16714 :             GIntBig nPIDCreatorForShared = psStruct->nPIDCreatorForShared;
     266           16714 :             CPLHashSetRemove(phAllDatasetSet, psStruct);
     267                 : 
     268           16714 :             if (bShared && phSharedDatasetSet != NULL)
     269                 :             {
     270                 :                 SharedDatasetCtxt* psStruct;
     271                 :                 SharedDatasetCtxt sStruct;
     272             299 :                 sStruct.nPID = nPIDCreatorForShared;
     273             299 :                 sStruct.eAccess = eAccess;
     274             299 :                 sStruct.pszDescription = (char*) GetDescription();
     275             299 :                 psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
     276             598 :                 if (psStruct && psStruct->poDS == this)
     277                 :                 {
     278             299 :                     CPLHashSetRemove(phSharedDatasetSet, psStruct);
     279                 :                 }
     280                 :                 else
     281                 :                 {
     282               0 :                     CPLDebug("GDAL", "Should not happen. Cannot find %s, this=%p in phSharedDatasetSet", GetDescription(), this);
     283                 :                 }
     284                 :             }
     285                 : 
     286           16714 :             if (CPLHashSetSize(phAllDatasetSet) == 0)
     287                 :             {
     288             643 :                 CPLHashSetDestroy(phAllDatasetSet);
     289             643 :                 phAllDatasetSet = NULL;
     290             643 :                 if (phSharedDatasetSet)
     291                 :                 {
     292             152 :                     CPLHashSetDestroy(phSharedDatasetSet);
     293                 :                 }
     294             643 :                 phSharedDatasetSet = NULL;
     295             643 :                 CPLFree(ppDatasets);
     296             643 :                 ppDatasets = NULL;
     297                 :             }
     298           16714 :         }
     299                 :     }
     300                 : 
     301                 : /* -------------------------------------------------------------------- */
     302                 : /*      Destroy the raster bands if they exist.                         */
     303                 : /* -------------------------------------------------------------------- */
     304          430847 :     for( i = 0; i < nBands && papoBands != NULL; i++ )
     305                 :     {
     306          414133 :         if( papoBands[i] != NULL )
     307          414133 :             delete papoBands[i];
     308                 :     }
     309                 : 
     310           16714 :     CPLFree( papoBands );
     311           16714 : }
     312                 : 
     313                 : /************************************************************************/
     314                 : /*                             FlushCache()                             */
     315                 : /************************************************************************/
     316                 : 
     317                 : /**
     318                 :  * \brief Flush all write cached data to disk.
     319                 :  *
     320                 :  * Any raster (or other GDAL) data written via GDAL calls, but buffered
     321                 :  * internally will be written to disk.
     322                 :  *
     323                 :  * Using this method does not prevent use from calling GDALClose()
     324                 :  * to properly close a dataset and ensure that important data not addressed
     325                 :  * by FlushCache() is written in the file.
     326                 :  *
     327                 :  * This method is the same as the C function GDALFlushCache().
     328                 :  */
     329                 : 
     330           22285 : void GDALDataset::FlushCache()
     331                 : 
     332                 : {
     333                 :     int         i;
     334                 : 
     335                 :     // This sometimes happens if a dataset is destroyed before completely
     336                 :     // built. 
     337                 : 
     338           22285 :     if( papoBands == NULL )
     339             530 :         return;
     340                 : 
     341         1047356 :     for( i = 0; i < nBands; i++ )
     342                 :     {
     343         1025601 :         if( papoBands[i] != NULL )
     344         1025601 :             papoBands[i]->FlushCache();
     345                 :     }
     346                 : }
     347                 : 
     348                 : /************************************************************************/
     349                 : /*                           GDALFlushCache()                           */
     350                 : /************************************************************************/
     351                 : 
     352                 : /**
     353                 :  * \brief Flush all write cached data to disk.
     354                 :  *
     355                 :  * @see GDALDataset::FlushCache().
     356                 :  */
     357                 : 
     358             341 : void CPL_STDCALL GDALFlushCache( GDALDatasetH hDS )
     359                 : 
     360                 : {
     361             341 :     VALIDATE_POINTER0( hDS, "GDALFlushCache" );
     362                 : 
     363             341 :     ((GDALDataset *) hDS)->FlushCache();
     364                 : }
     365                 : 
     366                 : /************************************************************************/
     367                 : /*                        BlockBasedFlushCache()                        */
     368                 : /*                                                                      */
     369                 : /*      This helper method can be called by the                         */
     370                 : /*      GDALDataset::FlushCache() for particular drivers to ensure      */
     371                 : /*      that buffers will be flushed in a manner suitable for pixel     */
     372                 : /*      interleaved (by block) IO.  That is, if all the bands have      */
     373                 : /*      the same size blocks then a given block will be flushed for     */
     374                 : /*      all bands before proceeding to the next block.                  */
     375                 : /************************************************************************/
     376                 : 
     377              29 : void GDALDataset::BlockBasedFlushCache()
     378                 : 
     379                 : {
     380                 :     GDALRasterBand *poBand1;
     381                 :     int  nBlockXSize, nBlockYSize, iBand;
     382                 :     
     383              29 :     poBand1 = GetRasterBand( 1 );
     384              29 :     if( poBand1 == NULL )
     385                 :     {
     386               1 :         GDALDataset::FlushCache();
     387               1 :         return;
     388                 :     }
     389                 : 
     390              28 :     poBand1->GetBlockSize( &nBlockXSize, &nBlockYSize );
     391                 :     
     392                 : /* -------------------------------------------------------------------- */
     393                 : /*      Verify that all bands match.                                    */
     394                 : /* -------------------------------------------------------------------- */
     395              62 :     for( iBand = 1; iBand < nBands; iBand++ )
     396                 :     {
     397                 :         int nThisBlockXSize, nThisBlockYSize;
     398              34 :         GDALRasterBand *poBand = GetRasterBand( iBand+1 );
     399                 :         
     400              34 :         poBand->GetBlockSize( &nThisBlockXSize, &nThisBlockYSize );
     401              34 :         if( nThisBlockXSize != nBlockXSize && nThisBlockYSize != nBlockYSize )
     402                 :         {
     403               0 :             GDALDataset::FlushCache();
     404               0 :             return;
     405                 :         }
     406                 :     }
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      Now flush writable data.                                        */
     410                 : /* -------------------------------------------------------------------- */
     411             328 :     for( int iY = 0; iY < poBand1->nBlocksPerColumn; iY++ )
     412                 :     {
     413             600 :         for( int iX = 0; iX < poBand1->nBlocksPerRow; iX++ )
     414                 :         {
     415            1000 :             for( iBand = 0; iBand < nBands; iBand++ )
     416                 :             {
     417             700 :                 GDALRasterBand *poBand = GetRasterBand( iBand+1 );
     418                 :                 
     419             700 :                 if( poBand->papoBlocks[iX + iY*poBand1->nBlocksPerRow] != NULL)
     420                 :                 {
     421                 :                     CPLErr    eErr;
     422                 :                     
     423             400 :                     eErr = poBand->FlushBlock( iX, iY );
     424                 :                     
     425             400 :                     if( eErr != CE_None )
     426               0 :                         return;
     427                 :                 }
     428                 :             }
     429                 :         }
     430                 :     }
     431                 : }
     432                 : 
     433                 : /************************************************************************/
     434                 : /*                          RasterInitialize()                          */
     435                 : /*                                                                      */
     436                 : /*      Initialize raster size                                          */
     437                 : /************************************************************************/
     438                 : 
     439               0 : void GDALDataset::RasterInitialize( int nXSize, int nYSize )
     440                 : 
     441                 : {
     442               0 :     CPLAssert( nXSize > 0 && nYSize > 0 );
     443                 :     
     444               0 :     nRasterXSize = nXSize;
     445               0 :     nRasterYSize = nYSize;
     446               0 : }
     447                 : 
     448                 : /************************************************************************/
     449                 : /*                              AddBand()                               */
     450                 : /************************************************************************/
     451                 : 
     452                 : /**
     453                 :  * \brief Add a band to a dataset.
     454                 :  *
     455                 :  * This method will add a new band to the dataset if the underlying format
     456                 :  * supports this action.  Most formats do not. 
     457                 :  *
     458                 :  * Note that the new GDALRasterBand is not returned.  It may be fetched
     459                 :  * after successful completion of the method by calling 
     460                 :  * GDALDataset::GetRasterBand(GDALDataset::GetRasterCount()) as the newest
     461                 :  * band will always be the last band.
     462                 :  *
     463                 :  * @param eType the data type of the pixels in the new band. 
     464                 :  *
     465                 :  * @param papszOptions a list of NAME=VALUE option strings.  The supported
     466                 :  * options are format specific.  NULL may be passed by default.
     467                 :  *
     468                 :  * @return CE_None on success or CE_Failure on failure.  
     469                 :  */
     470                 : 
     471               2 : CPLErr GDALDataset::AddBand( GDALDataType eType, char ** papszOptions )
     472                 : 
     473                 : {
     474                 :     (void) eType;
     475                 :     (void) papszOptions;
     476                 : 
     477                 :     ReportError( CE_Failure, CPLE_NotSupported,
     478               2 :               "Dataset does not support the AddBand() method." );
     479                 : 
     480               2 :     return CE_Failure;
     481                 : }
     482                 : 
     483                 : /************************************************************************/
     484                 : /*                            GDALAddBand()                             */
     485                 : /************************************************************************/
     486                 : 
     487                 : /**
     488                 :  * \brief Add a band to a dataset.
     489                 :  *
     490                 :  * @see GDALDataset::AddBand().
     491                 :  */
     492                 : 
     493             286 : CPLErr CPL_STDCALL GDALAddBand( GDALDatasetH hDataset, 
     494                 :                     GDALDataType eType, char **papszOptions )
     495                 : 
     496                 : {
     497             286 :     VALIDATE_POINTER1( hDataset, "GDALAddBand", CE_Failure );
     498                 : 
     499             286 :     return ((GDALDataset *) hDataset)->AddBand( eType, papszOptions );
     500                 : }
     501                 : 
     502                 : /************************************************************************/
     503                 : /*                              SetBand()                               */
     504                 : /*                                                                      */
     505                 : /*      Set a band in the band array, updating the band count, and      */
     506                 : /*      array size appropriately.                                       */
     507                 : /************************************************************************/
     508                 : 
     509          625536 : void GDALDataset::SetBand( int nNewBand, GDALRasterBand * poBand )
     510                 : 
     511                 : {
     512                 : /* -------------------------------------------------------------------- */
     513                 : /*      Do we need to grow the bands list?                              */
     514                 : /* -------------------------------------------------------------------- */
     515          625536 :     if( nBands < nNewBand || papoBands == NULL ) {
     516                 :         int             i;
     517                 :         GDALRasterBand** papoNewBands;
     518                 : 
     519          360695 :         if( papoBands == NULL )
     520                 :             papoNewBands = (GDALRasterBand **)
     521           16136 :                 VSICalloc(sizeof(GDALRasterBand*), MAX(nNewBand,nBands));
     522                 :         else
     523                 :             papoNewBands = (GDALRasterBand **)
     524                 :                 VSIRealloc(papoBands, sizeof(GDALRasterBand*) *
     525          344559 :                            MAX(nNewBand,nBands));
     526          360695 :         if (papoNewBands == NULL)
     527                 :         {
     528                 :             ReportError(CE_Failure, CPLE_OutOfMemory,
     529               0 :                      "Cannot allocate band array");
     530               0 :             return;
     531                 :         }
     532          360695 :         papoBands = papoNewBands;
     533                 : 
     534          715086 :         for( i = nBands; i < nNewBand; i++ )
     535          354391 :             papoBands[i] = NULL;
     536                 : 
     537          360695 :         nBands = MAX(nBands,nNewBand);
     538                 :     }
     539                 : 
     540                 : /* -------------------------------------------------------------------- */
     541                 : /*      Set the band.  Resetting the band is currently not permitted.   */
     542                 : /* -------------------------------------------------------------------- */
     543          625536 :     if( papoBands[nNewBand-1] != NULL )
     544                 :     {
     545                 :         ReportError(CE_Failure, CPLE_NotSupported,
     546               0 :                  "Cannot set band %d as it is already set", nNewBand);
     547               0 :         return;
     548                 :     }
     549                 : 
     550          625536 :     papoBands[nNewBand-1] = poBand;
     551                 : 
     552                 : /* -------------------------------------------------------------------- */
     553                 : /*      Set back reference information on the raster band.  Note        */
     554                 : /*      that the GDALDataset is a friend of the GDALRasterBand          */
     555                 : /*      specifically to allow this.                                     */
     556                 : /* -------------------------------------------------------------------- */
     557          625536 :     poBand->nBand = nNewBand;
     558          625536 :     poBand->poDS = this;
     559          625536 :     poBand->nRasterXSize = nRasterXSize;
     560          625536 :     poBand->nRasterYSize = nRasterYSize;
     561          625536 :     poBand->eAccess = eAccess; /* default access to be same as dataset */
     562                 : }
     563                 : 
     564                 : /************************************************************************/
     565                 : /*                           GetRasterXSize()                           */
     566                 : /************************************************************************/
     567                 : 
     568                 : /**
     569                 : 
     570                 :  \brief Fetch raster width in pixels.
     571                 : 
     572                 :  Equivalent of the C function GDALGetRasterXSize().
     573                 : 
     574                 :  @return the width in pixels of raster bands in this GDALDataset.
     575                 : 
     576                 : */
     577                 : 
     578          401216 : int GDALDataset::GetRasterXSize()
     579                 : 
     580                 : {
     581          401216 :     return nRasterXSize;
     582                 : }
     583                 : 
     584                 : /************************************************************************/
     585                 : /*                         GDALGetRasterXSize()                         */
     586                 : /************************************************************************/
     587                 : 
     588                 : /**
     589                 :  * \brief Fetch raster width in pixels.
     590                 :  *
     591                 :  * @see GDALDataset::GetRasterXSize().
     592                 :  */
     593                 : 
     594            7466 : int CPL_STDCALL GDALGetRasterXSize( GDALDatasetH hDataset )
     595                 : 
     596                 : {
     597            7466 :     VALIDATE_POINTER1( hDataset, "GDALGetRasterXSize", 0 );
     598                 : 
     599            7466 :     return ((GDALDataset *) hDataset)->GetRasterXSize();
     600                 : }
     601                 : 
     602                 : 
     603                 : /************************************************************************/
     604                 : /*                           GetRasterYSize()                           */
     605                 : /************************************************************************/
     606                 : 
     607                 : /**
     608                 : 
     609                 :  \brief Fetch raster height in pixels.
     610                 : 
     611                 :  Equivalent of the C function GDALGetRasterYSize().
     612                 : 
     613                 :  @return the height in pixels of raster bands in this GDALDataset.
     614                 : 
     615                 : */
     616                 : 
     617          166314 : int GDALDataset::GetRasterYSize()
     618                 : 
     619                 : {
     620          166314 :     return nRasterYSize;
     621                 : }
     622                 : 
     623                 : /************************************************************************/
     624                 : /*                         GDALGetRasterYSize()                         */
     625                 : /************************************************************************/
     626                 : 
     627                 : /**
     628                 :  * \brief Fetch raster height in pixels.
     629                 :  *
     630                 :  * @see GDALDataset::GetRasterYSize().
     631                 :  */
     632                 : 
     633           15767 : int CPL_STDCALL GDALGetRasterYSize( GDALDatasetH hDataset )
     634                 : 
     635                 : {
     636           15767 :     VALIDATE_POINTER1( hDataset, "GDALGetRasterYSize", 0 );
     637                 : 
     638           15767 :     return ((GDALDataset *) hDataset)->GetRasterYSize();
     639                 : }
     640                 : 
     641                 : /************************************************************************/
     642                 : /*                           GetRasterBand()                            */
     643                 : /************************************************************************/
     644                 : 
     645                 : /**
     646                 : 
     647                 :  \brief Fetch a band object for a dataset.
     648                 : 
     649                 :  Equivalent of the C function GDALGetRasterBand().
     650                 : 
     651                 :  @param nBandId the index number of the band to fetch, from 1 to
     652                 :                 GetRasterCount().
     653                 : 
     654                 :  @return the nBandId th band object
     655                 : 
     656                 : */
     657                 : 
     658         2397772 : GDALRasterBand * GDALDataset::GetRasterBand( int nBandId )
     659                 : 
     660                 : {
     661         2397772 :     if ( papoBands )
     662                 :     {
     663         2397771 :         if( nBandId < 1 || nBandId > nBands )
     664                 :         {
     665                 :             ReportError( CE_Failure, CPLE_IllegalArg,
     666                 :                       "GDALDataset::GetRasterBand(%d) - Illegal band #\n",
     667               0 :                       nBandId );
     668               0 :             return NULL;
     669                 :         }
     670                 :         else
     671         2397771 :             return( papoBands[nBandId-1] );
     672                 :     }
     673               1 :     return NULL;
     674                 : }
     675                 : 
     676                 : /************************************************************************/
     677                 : /*                         GDALGetRasterBand()                          */
     678                 : /************************************************************************/
     679                 : 
     680                 : /**
     681                 :  * \brief Fetch a band object for a dataset.
     682                 :  * @see GDALDataset::GetRasterBand().
     683                 :  */
     684                 : 
     685          189746 : GDALRasterBandH CPL_STDCALL GDALGetRasterBand( GDALDatasetH hDS, int nBandId )
     686                 : 
     687                 : {
     688          189746 :     VALIDATE_POINTER1( hDS, "GDALGetRasterBand", NULL );
     689                 : 
     690          189746 :     return( (GDALRasterBandH) ((GDALDataset *) hDS)->GetRasterBand(nBandId) );
     691                 : }
     692                 : 
     693                 : /************************************************************************/
     694                 : /*                           GetRasterCount()                           */
     695                 : /************************************************************************/
     696                 : 
     697                 : /**
     698                 :  * \brief Fetch the number of raster bands on this dataset.
     699                 :  *
     700                 :  * Same as the C function GDALGetRasterCount().
     701                 :  *
     702                 :  * @return the number of raster bands.
     703                 :  */
     704                 : 
     705         1857592 : int GDALDataset::GetRasterCount()
     706                 : 
     707                 : {
     708         1857592 :     return papoBands ? nBands : 0;
     709                 : }
     710                 : 
     711                 : /************************************************************************/
     712                 : /*                         GDALGetRasterCount()                         */
     713                 : /************************************************************************/
     714                 : 
     715                 : /**
     716                 :  * \brief Fetch the number of raster bands on this dataset.
     717                 :  *
     718                 :  * @see GDALDataset::GetRasterCount().
     719                 :  */
     720                 : 
     721          340720 : int CPL_STDCALL GDALGetRasterCount( GDALDatasetH hDS )
     722                 : 
     723                 : {
     724          340720 :     VALIDATE_POINTER1( hDS, "GDALGetRasterCount", 0 );
     725                 : 
     726          340720 :     return( ((GDALDataset *) hDS)->GetRasterCount() );
     727                 : }
     728                 : 
     729                 : /************************************************************************/
     730                 : /*                          GetProjectionRef()                          */
     731                 : /************************************************************************/
     732                 : 
     733                 : /**
     734                 :  * \brief Fetch the projection definition string for this dataset.
     735                 :  *
     736                 :  * Same as the C function GDALGetProjectionRef().
     737                 :  *
     738                 :  * The returned string defines the projection coordinate system of the
     739                 :  * image in OpenGIS WKT format.  It should be suitable for use with the 
     740                 :  * OGRSpatialReference class.
     741                 :  *
     742                 :  * When a projection definition is not available an empty (but not NULL)
     743                 :  * string is returned.
     744                 :  *
     745                 :  * @return a pointer to an internal projection reference string.  It should
     746                 :  * not be altered, freed or expected to last for long. 
     747                 :  *
     748                 :  * @see http://www.gdal.org/ogr/osr_tutorial.html
     749                 :  */
     750                 : 
     751            4552 : const char *GDALDataset::GetProjectionRef()
     752                 : 
     753                 : {
     754            4552 :     return( "" );
     755                 : }
     756                 : 
     757                 : /************************************************************************/
     758                 : /*                        GDALGetProjectionRef()                        */
     759                 : /************************************************************************/
     760                 : 
     761                 : /**
     762                 :  * \brief Fetch the projection definition string for this dataset.
     763                 :  *
     764                 :  * @see GDALDataset::GetProjectionRef()
     765                 :  */
     766                 : 
     767            1891 : const char * CPL_STDCALL GDALGetProjectionRef( GDALDatasetH hDS )
     768                 : 
     769                 : {
     770            1891 :     VALIDATE_POINTER1( hDS, "GDALGetProjectionRef", NULL );
     771                 : 
     772            1891 :     return( ((GDALDataset *) hDS)->GetProjectionRef() );
     773                 : }
     774                 : 
     775                 : /************************************************************************/
     776                 : /*                           SetProjection()                            */
     777                 : /************************************************************************/
     778                 : 
     779                 : /**
     780                 :  * \brief Set the projection reference string for this dataset.
     781                 :  *
     782                 :  * The string should be in OGC WKT or PROJ.4 format.  An error may occur
     783                 :  * because of incorrectly specified projection strings, because the dataset
     784                 :  * is not writable, or because the dataset does not support the indicated
     785                 :  * projection.  Many formats do not support writing projections.
     786                 :  *
     787                 :  * This method is the same as the C GDALSetProjection() function. 
     788                 :  *
     789                 :  * @param pszProjection projection reference string.
     790                 :  *
     791                 :  * @return CE_Failure if an error occurs, otherwise CE_None.
     792                 :  */
     793                 : 
     794               5 : CPLErr GDALDataset::SetProjection( const char * pszProjection )
     795                 : 
     796                 : {
     797               5 :     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
     798                 :         ReportError( CE_Failure, CPLE_NotSupported,
     799               0 :                   "Dataset does not support the SetProjection() method." );
     800               5 :     return CE_Failure;
     801                 : }
     802                 : 
     803                 : /************************************************************************/
     804                 : /*                         GDALSetProjection()                          */
     805                 : /************************************************************************/
     806                 : 
     807                 : /**
     808                 :  * \brief Set the projection reference string for this dataset.
     809                 :  *
     810                 :  * @see GDALDataset::SetProjection()
     811                 :  */
     812                 : 
     813            1267 : CPLErr CPL_STDCALL GDALSetProjection( GDALDatasetH hDS, const char * pszProjection )
     814                 : 
     815                 : {
     816            1267 :     VALIDATE_POINTER1( hDS, "GDALSetProjection", CE_Failure );
     817                 : 
     818            1267 :     return( ((GDALDataset *) hDS)->SetProjection(pszProjection) );
     819                 : }
     820                 : 
     821                 : /************************************************************************/
     822                 : /*                          GetGeoTransform()                           */
     823                 : /************************************************************************/
     824                 : 
     825                 : /**
     826                 :  * \brief Fetch the affine transformation coefficients.
     827                 :  *
     828                 :  * Fetches the coefficients for transforming between pixel/line (P,L) raster
     829                 :  * space, and projection coordinates (Xp,Yp) space.
     830                 :  *
     831                 :  * \code
     832                 :  *   Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
     833                 :  *   Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
     834                 :  * \endcode
     835                 :  *
     836                 :  * In a north up image, padfTransform[1] is the pixel width, and
     837                 :  * padfTransform[5] is the pixel height.  The upper left corner of the
     838                 :  * upper left pixel is at position (padfTransform[0],padfTransform[3]).
     839                 :  *
     840                 :  * The default transform is (0,1,0,0,0,1) and should be returned even when
     841                 :  * a CE_Failure error is returned, such as for formats that don't support
     842                 :  * transformation to projection coordinates.
     843                 :  *
     844                 :  * NOTE: GetGeoTransform() isn't expressive enough to handle the variety of
     845                 :  * OGC Grid Coverages pixel/line to projection transformation schemes.
     846                 :  * Eventually this method will be depreciated in favour of a more general
     847                 :  * scheme.
     848                 :  *
     849                 :  * This method does the same thing as the C GDALGetGeoTransform() function.
     850                 :  *
     851                 :  * @param padfTransform an existing six double buffer into which the
     852                 :  * transformation will be placed.
     853                 :  *
     854                 :  * @return CE_None on success, or CE_Failure if no transform can be fetched.
     855                 :  */
     856                 : 
     857            4155 : CPLErr GDALDataset::GetGeoTransform( double * padfTransform )
     858                 : 
     859                 : {
     860            4155 :     CPLAssert( padfTransform != NULL );
     861                 :         
     862            4155 :     padfTransform[0] = 0.0;     /* X Origin (top left corner) */
     863            4155 :     padfTransform[1] = 1.0;     /* X Pixel size */
     864            4155 :     padfTransform[2] = 0.0;
     865                 : 
     866            4155 :     padfTransform[3] = 0.0;     /* Y Origin (top left corner) */
     867            4155 :     padfTransform[4] = 0.0;     
     868            4155 :     padfTransform[5] = 1.0;     /* Y Pixel Size */
     869                 : 
     870            4155 :     return( CE_Failure );
     871                 : }
     872                 : 
     873                 : /************************************************************************/
     874                 : /*                        GDALGetGeoTransform()                         */
     875                 : /************************************************************************/
     876                 : 
     877                 : /**
     878                 :  * \brief Fetch the affine transformation coefficients.
     879                 :  *
     880                 :  * @see GDALDataset::GetGeoTransform()
     881                 :  */
     882                 : 
     883            1799 : CPLErr CPL_STDCALL GDALGetGeoTransform( GDALDatasetH hDS, double * padfTransform )
     884                 : 
     885                 : {
     886            1799 :     VALIDATE_POINTER1( hDS, "GDALGetGeoTransform", CE_Failure );
     887                 : 
     888            1799 :     return( ((GDALDataset *) hDS)->GetGeoTransform(padfTransform) );
     889                 : }
     890                 : 
     891                 : /************************************************************************/
     892                 : /*                          SetGeoTransform()                           */
     893                 : /************************************************************************/
     894                 : 
     895                 : /**
     896                 :  * \brief Set the affine transformation coefficients.
     897                 :  *
     898                 :  * See GetGeoTransform() for details on the meaning of the padfTransform
     899                 :  * coefficients.
     900                 :  *
     901                 :  * This method does the same thing as the C GDALSetGeoTransform() function.
     902                 :  *
     903                 :  * @param padfTransform a six double buffer containing the transformation
     904                 :  * coefficients to be written with the dataset.
     905                 :  *
     906                 :  * @return CE_None on success, or CE_Failure if this transform cannot be
     907                 :  * written.
     908                 :  */
     909                 : 
     910               5 : CPLErr GDALDataset::SetGeoTransform( double * padfTransform )
     911                 : 
     912                 : {
     913               5 :     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
     914                 :         ReportError( CE_Failure, CPLE_NotSupported,
     915               0 :                   "SetGeoTransform() not supported for this dataset." );
     916                 :     
     917               5 :     return( CE_Failure );
     918                 : }
     919                 : 
     920                 : /************************************************************************/
     921                 : /*                        GDALSetGeoTransform()                         */
     922                 : /************************************************************************/
     923                 : 
     924                 : /**
     925                 :  * \brief Set the affine transformation coefficients.
     926                 :  *
     927                 :  * @see GDALDataset::SetGeoTransform()
     928                 :  */
     929                 : 
     930                 : CPLErr CPL_STDCALL 
     931            1244 : GDALSetGeoTransform( GDALDatasetH hDS, double * padfTransform )
     932                 : 
     933                 : {
     934            1244 :     VALIDATE_POINTER1( hDS, "GDALSetGeoTransform", CE_Failure );
     935                 : 
     936            1244 :     return( ((GDALDataset *) hDS)->SetGeoTransform(padfTransform) );
     937                 : }
     938                 : 
     939                 : /************************************************************************/
     940                 : /*                         GetInternalHandle()                          */
     941                 : /************************************************************************/
     942                 : 
     943                 : /**
     944                 :  * \brief Fetch a format specific internally meaningful handle.
     945                 :  *
     946                 :  * This method is the same as the C GDALGetInternalHandle() method. 
     947                 :  *
     948                 :  * @param pszHandleName the handle name desired.  The meaningful names
     949                 :  * will be specific to the file format.
     950                 :  *
     951                 :  * @return the desired handle value, or NULL if not recognised/supported.
     952                 :  */
     953                 : 
     954               0 : void *GDALDataset::GetInternalHandle( const char * pszHandleName )
     955                 : 
     956                 : {
     957               0 :     return( NULL );
     958                 : }
     959                 : 
     960                 : /************************************************************************/
     961                 : /*                       GDALGetInternalHandle()                        */
     962                 : /************************************************************************/
     963                 : 
     964                 : /**
     965                 :  * \brief Fetch a format specific internally meaningful handle.
     966                 :  *
     967                 :  * @see GDALDataset::GetInternalHandle()
     968                 :  */
     969                 : 
     970                 : void * CPL_STDCALL 
     971               0 : GDALGetInternalHandle( GDALDatasetH hDS, const char * pszRequest )
     972                 : 
     973                 : {
     974               0 :     VALIDATE_POINTER1( hDS, "GDALGetInternalHandle", NULL );
     975                 : 
     976               0 :     return( ((GDALDataset *) hDS)->GetInternalHandle(pszRequest) );
     977                 : }
     978                 : 
     979                 : /************************************************************************/
     980                 : /*                             GetDriver()                              */
     981                 : /************************************************************************/
     982                 : 
     983                 : /**
     984                 :  * \brief Fetch the driver to which this dataset relates.
     985                 :  *
     986                 :  * This method is the same as the C GDALGetDatasetDriver() function.
     987                 :  *
     988                 :  * @return the driver on which the dataset was created with GDALOpen() or
     989                 :  * GDALCreate().
     990                 :  */
     991                 : 
     992            2564 : GDALDriver * GDALDataset::GetDriver()
     993                 : 
     994                 : {
     995            2564 :     return poDriver;
     996                 : }
     997                 : 
     998                 : /************************************************************************/
     999                 : /*                        GDALGetDatasetDriver()                        */
    1000                 : /************************************************************************/
    1001                 : 
    1002                 : /**
    1003                 :  * \brief Fetch the driver to which this dataset relates.
    1004                 :  *
    1005                 :  * @see GDALDataset::GetDriver()
    1006                 :  */
    1007                 : 
    1008             605 : GDALDriverH CPL_STDCALL GDALGetDatasetDriver( GDALDatasetH hDataset )
    1009                 : 
    1010                 : {
    1011             605 :     VALIDATE_POINTER1( hDataset, "GDALGetDatasetDriver", NULL );
    1012                 : 
    1013             605 :     return (GDALDriverH) ((GDALDataset *) hDataset)->GetDriver();
    1014                 : }
    1015                 : 
    1016                 : /************************************************************************/
    1017                 : /*                             Reference()                              */
    1018                 : /************************************************************************/
    1019                 : 
    1020                 : /**
    1021                 :  * \brief Add one to dataset reference count.
    1022                 :  *
    1023                 :  * The reference is one after instantiation.
    1024                 :  *
    1025                 :  * This method is the same as the C GDALReferenceDataset() function.
    1026                 :  *
    1027                 :  * @return the post-increment reference count.
    1028                 :  */
    1029                 : 
    1030           11026 : int GDALDataset::Reference()
    1031                 : 
    1032                 : {
    1033           11026 :     return ++nRefCount;
    1034                 : }
    1035                 : 
    1036                 : /************************************************************************/
    1037                 : /*                        GDALReferenceDataset()                        */
    1038                 : /************************************************************************/
    1039                 : 
    1040                 : /**
    1041                 :  * \brief Add one to dataset reference count.
    1042                 :  *
    1043                 :  * @see GDALDataset::Reference()
    1044                 :  */
    1045                 : 
    1046              69 : int CPL_STDCALL GDALReferenceDataset( GDALDatasetH hDataset )
    1047                 : 
    1048                 : {
    1049              69 :     VALIDATE_POINTER1( hDataset, "GDALReferenceDataset", 0 );
    1050                 : 
    1051              69 :     return ((GDALDataset *) hDataset)->Reference();
    1052                 : }
    1053                 : 
    1054                 : /************************************************************************/
    1055                 : /*                            Dereference()                             */
    1056                 : /************************************************************************/
    1057                 : 
    1058                 : /**
    1059                 :  * \brief Subtract one from dataset reference count.
    1060                 :  *
    1061                 :  * The reference is one after instantiation.  Generally when the reference
    1062                 :  * count has dropped to zero the dataset may be safely deleted (closed).
    1063                 :  *
    1064                 :  * This method is the same as the C GDALDereferenceDataset() function.
    1065                 :  *
    1066                 :  * @return the post-decrement reference count.
    1067                 :  */
    1068                 : 
    1069           22951 : int GDALDataset::Dereference()
    1070                 : 
    1071                 : {
    1072           22951 :     return --nRefCount;
    1073                 : }
    1074                 : 
    1075                 : /************************************************************************/
    1076                 : /*                       GDALDereferenceDataset()                       */
    1077                 : /************************************************************************/
    1078                 : 
    1079                 : /**
    1080                 :  * \brief Subtract one from dataset reference count.
    1081                 :  *
    1082                 :  * @see GDALDataset::Dereference()
    1083                 :  */
    1084                 : 
    1085           16442 : int CPL_STDCALL GDALDereferenceDataset( GDALDatasetH hDataset )
    1086                 : 
    1087                 : {
    1088           16442 :     VALIDATE_POINTER1( hDataset, "GDALDereferenceDataset", 0 );
    1089                 : 
    1090           16442 :     return ((GDALDataset *) hDataset)->Dereference();
    1091                 : }
    1092                 : 
    1093                 : /************************************************************************/
    1094                 : /*                             GetShared()                              */
    1095                 : /************************************************************************/
    1096                 : 
    1097                 : /**
    1098                 :  * \brief Returns shared flag.
    1099                 :  *
    1100                 :  * @return TRUE if the GDALDataset is available for sharing, or FALSE if not.
    1101                 :  */
    1102                 : 
    1103           23722 : int GDALDataset::GetShared()
    1104                 : 
    1105                 : {
    1106           23722 :     return bShared;
    1107                 : }
    1108                 : 
    1109                 : /************************************************************************/
    1110                 : /*                            MarkAsShared()                            */
    1111                 : /************************************************************************/
    1112                 : 
    1113                 : /**
    1114                 :  * \brief Mark this dataset as available for sharing.
    1115                 :  */
    1116                 : 
    1117             299 : void GDALDataset::MarkAsShared()
    1118                 : 
    1119                 : {
    1120             299 :     CPLAssert( !bShared );
    1121                 : 
    1122             299 :     bShared = TRUE;
    1123                 : 
    1124             299 :     GIntBig nPID = GDALGetResponsiblePIDForCurrentThread();
    1125                 :     SharedDatasetCtxt* psStruct;
    1126                 : 
    1127                 :     /* Insert the dataset in the set of shared opened datasets */
    1128             299 :     CPLMutexHolderD( &hDLMutex );
    1129             299 :     if (phSharedDatasetSet == NULL)
    1130             152 :         phSharedDatasetSet = CPLHashSetNew(GDALSharedDatasetHashFunc, GDALSharedDatasetEqualFunc, GDALSharedDatasetFreeFunc);
    1131                 : 
    1132             299 :     psStruct = (SharedDatasetCtxt*)CPLMalloc(sizeof(SharedDatasetCtxt));
    1133             299 :     psStruct->poDS = this;
    1134             299 :     psStruct->nPID = nPID;
    1135             299 :     psStruct->eAccess = eAccess;
    1136             299 :     psStruct->pszDescription = CPLStrdup(GetDescription());
    1137             299 :     if(CPLHashSetLookup(phSharedDatasetSet, psStruct) != NULL)
    1138                 :     {
    1139               0 :         CPLFree(psStruct);
    1140                 :         ReportError(CE_Failure, CPLE_AppDefined,
    1141               0 :                  "An existing shared dataset already has this description. This should not happen.");
    1142                 :     }
    1143                 :     else
    1144                 :     {
    1145             299 :         CPLHashSetInsert(phSharedDatasetSet, psStruct);
    1146                 : 
    1147                 :         DatasetCtxt sStruct;
    1148             299 :         sStruct.poDS = this;
    1149             299 :         DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
    1150             299 :         psStruct->nPIDCreatorForShared = nPID;
    1151             299 :     }
    1152             299 : }
    1153                 : 
    1154                 : /************************************************************************/
    1155                 : /*                            GetGCPCount()                             */
    1156                 : /************************************************************************/
    1157                 : 
    1158                 : /**
    1159                 :  * \brief Get number of GCPs. 
    1160                 :  *
    1161                 :  * This method is the same as the C function GDALGetGCPCount(). 
    1162                 :  *
    1163                 :  * @return number of GCPs for this dataset.  Zero if there are none.
    1164                 :  */
    1165                 : 
    1166            4093 : int GDALDataset::GetGCPCount()
    1167                 : 
    1168                 : {
    1169            4093 :     return 0;
    1170                 : }
    1171                 : 
    1172                 : /************************************************************************/
    1173                 : /*                          GDALGetGCPCount()                           */
    1174                 : /************************************************************************/
    1175                 : 
    1176                 : /**
    1177                 :  * \brief Get number of GCPs. 
    1178                 :  *
    1179                 :  * @see GDALDataset::GetGCPCount()
    1180                 :  */
    1181                 : 
    1182             213 : int CPL_STDCALL GDALGetGCPCount( GDALDatasetH hDS )
    1183                 : 
    1184                 : {
    1185             213 :     VALIDATE_POINTER1( hDS, "GDALGetGCPCount", 0 );
    1186                 : 
    1187             213 :     return ((GDALDataset *) hDS)->GetGCPCount();
    1188                 : }
    1189                 : 
    1190                 : /************************************************************************/
    1191                 : /*                          GetGCPProjection()                          */
    1192                 : /************************************************************************/
    1193                 : 
    1194                 : /**
    1195                 :  * \brief Get output projection for GCPs. 
    1196                 :  *
    1197                 :  * This method is the same as the C function GDALGetGCPProjection(). 
    1198                 :  *
    1199                 :  * The projection string follows the normal rules from GetProjectionRef().
    1200                 :  *
    1201                 :  * @return internal projection string or "" if there are no GCPs. 
    1202                 :  *  It should not be altered, freed or expected to last for long.
    1203                 :  */
    1204                 : 
    1205               2 : const char *GDALDataset::GetGCPProjection()
    1206                 : 
    1207                 : {
    1208               2 :     return "";
    1209                 : }
    1210                 : 
    1211                 : /************************************************************************/
    1212                 : /*                        GDALGetGCPProjection()                        */
    1213                 : /************************************************************************/
    1214                 : 
    1215                 : /**
    1216                 :  * \brief Get output projection for GCPs. 
    1217                 :  *
    1218                 :  * @see GDALDataset::GetGCPProjection()
    1219                 :  */
    1220                 : 
    1221              98 : const char * CPL_STDCALL GDALGetGCPProjection( GDALDatasetH hDS )
    1222                 : 
    1223                 : {
    1224              98 :     VALIDATE_POINTER1( hDS, "GDALGetGCPProjection", NULL );
    1225                 : 
    1226              98 :     return ((GDALDataset *) hDS)->GetGCPProjection();
    1227                 : }
    1228                 : 
    1229                 : /************************************************************************/
    1230                 : /*                               GetGCPs()                              */
    1231                 : /************************************************************************/
    1232                 : 
    1233                 : /**
    1234                 :  * \brief Fetch GCPs.
    1235                 :  *
    1236                 :  * This method is the same as the C function GDALGetGCPs(). 
    1237                 :  *
    1238                 :  * @return pointer to internal GCP structure list.  It should not be modified, 
    1239                 :  * and may change on the next GDAL call. 
    1240                 :  */ 
    1241                 : 
    1242               1 : const GDAL_GCP *GDALDataset::GetGCPs()
    1243                 : 
    1244                 : {
    1245               1 :     return NULL;
    1246                 : }
    1247                 : 
    1248                 : /************************************************************************/
    1249                 : /*                            GDALGetGCPs()                             */
    1250                 : /************************************************************************/
    1251                 : 
    1252                 : /**
    1253                 :  * \brief Fetch GCPs.
    1254                 :  *
    1255                 :  * @see GDALDataset::GetGCPs()
    1256                 :  */
    1257                 : 
    1258              70 : const GDAL_GCP * CPL_STDCALL GDALGetGCPs( GDALDatasetH hDS )
    1259                 : 
    1260                 : {
    1261              70 :     VALIDATE_POINTER1( hDS, "GDALGetGCPs", NULL );
    1262                 : 
    1263              70 :     return ((GDALDataset *) hDS)->GetGCPs();
    1264                 : }
    1265                 : 
    1266                 : 
    1267                 : /************************************************************************/
    1268                 : /*                              SetGCPs()                               */
    1269                 : /************************************************************************/
    1270                 : 
    1271                 : /**
    1272                 :  * \brief Assign GCPs.
    1273                 :  *
    1274                 :  * This method is the same as the C function GDALSetGCPs(). 
    1275                 :  *
    1276                 :  * This method assigns the passed set of GCPs to this dataset, as well as
    1277                 :  * setting their coordinate system.  Internally copies are made of the
    1278                 :  * coordinate system and list of points, so the caller remains responsible for
    1279                 :  * deallocating these arguments if appropriate. 
    1280                 :  *
    1281                 :  * Most formats do not support setting of GCPs, even formats that can 
    1282                 :  * handle GCPs.  These formats will return CE_Failure. 
    1283                 :  *
    1284                 :  * @param nGCPCount number of GCPs being assigned. 
    1285                 :  *
    1286                 :  * @param pasGCPList array of GCP structures being assign (nGCPCount in array).
    1287                 :  *
    1288                 :  * @param pszGCPProjection the new OGC WKT coordinate system to assign for the 
    1289                 :  * GCP output coordinates.  This parameter should be "" if no output coordinate
    1290                 :  * system is known.
    1291                 :  *
    1292                 :  * @return CE_None on success, CE_Failure on failure (including if action is
    1293                 :  * not supported for this format). 
    1294                 :  */ 
    1295                 : 
    1296               0 : CPLErr GDALDataset::SetGCPs( int nGCPCount, 
    1297                 :                              const GDAL_GCP *pasGCPList,
    1298                 :                              const char * pszGCPProjection )
    1299                 : 
    1300                 : {
    1301                 :     (void) nGCPCount;
    1302                 :     (void) pasGCPList;
    1303                 :     (void) pszGCPProjection;
    1304                 : 
    1305               0 :     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
    1306                 :         ReportError( CE_Failure, CPLE_NotSupported,
    1307               0 :                   "Dataset does not support the SetGCPs() method." );
    1308                 : 
    1309               0 :     return CE_Failure;
    1310                 : }
    1311                 : 
    1312                 : /************************************************************************/
    1313                 : /*                            GDALSetGCPs()                             */
    1314                 : /************************************************************************/
    1315                 : 
    1316                 : /**
    1317                 :  * \brief Assign GCPs.
    1318                 :  *
    1319                 :  * @see GDALDataset::SetGCPs()
    1320                 :  */
    1321                 : 
    1322              11 : CPLErr CPL_STDCALL GDALSetGCPs( GDALDatasetH hDS, int nGCPCount, 
    1323                 :                     const GDAL_GCP *pasGCPList, 
    1324                 :                     const char *pszGCPProjection )
    1325                 : 
    1326                 : {
    1327              11 :     VALIDATE_POINTER1( hDS, "GDALSetGCPs", CE_Failure );
    1328                 : 
    1329                 :     return ((GDALDataset *) hDS)->SetGCPs( nGCPCount, pasGCPList, 
    1330              11 :                                            pszGCPProjection );
    1331                 : }
    1332                 : 
    1333                 : /************************************************************************/
    1334                 : /*                           BuildOverviews()                           */
    1335                 : /************************************************************************/
    1336                 : 
    1337                 : /**
    1338                 :  * \brief Build raster overview(s)
    1339                 :  *
    1340                 :  * If the operation is unsupported for the indicated dataset, then 
    1341                 :  * CE_Failure is returned, and CPLGetLastErrorNo() will return 
    1342                 :  * CPLE_NotSupported.
    1343                 :  *
    1344                 :  * This method is the same as the C function GDALBuildOverviews().
    1345                 :  *
    1346                 :  * @param pszResampling one of "NEAREST", "GAUSS", "CUBIC", "AVERAGE", "MODE",
    1347                 :  * "AVERAGE_MAGPHASE" or "NONE" controlling the downsampling method applied.
    1348                 :  * @param nOverviews number of overviews to build. 
    1349                 :  * @param panOverviewList the list of overview decimation factors to build. 
    1350                 :  * @param nListBands number of bands to build overviews for in panBandList.  Build
    1351                 :  * for all bands if this is 0. 
    1352                 :  * @param panBandList list of band numbers. 
    1353                 :  * @param pfnProgress a function to call to report progress, or NULL.
    1354                 :  * @param pProgressData application data to pass to the progress function.
    1355                 :  *
    1356                 :  * @return CE_None on success or CE_Failure if the operation doesn't work.
    1357                 :  *
    1358                 :  * For example, to build overview level 2, 4 and 8 on all bands the following
    1359                 :  * call could be made:
    1360                 :  * <pre>
    1361                 :  *   int       anOverviewList[3] = { 2, 4, 8 };
    1362                 :  *   
    1363                 :  *   poDataset->BuildOverviews( "NEAREST", 3, anOverviewList, 0, NULL, 
    1364                 :  *                              GDALDummyProgress, NULL );
    1365                 :  * </pre>
    1366                 :  *
    1367                 :  * @see GDALRegenerateOverviews()
    1368                 :  */
    1369                 : 
    1370             193 : CPLErr GDALDataset::BuildOverviews( const char *pszResampling, 
    1371                 :                                     int nOverviews, int *panOverviewList, 
    1372                 :                                     int nListBands, int *panBandList,
    1373                 :                                     GDALProgressFunc pfnProgress, 
    1374                 :                                     void * pProgressData )
    1375                 :     
    1376                 : {
    1377                 :     CPLErr   eErr;
    1378             193 :     int      *panAllBandList = NULL;
    1379                 : 
    1380             193 :     if( nListBands == 0 )
    1381                 :     {
    1382             187 :         nListBands = GetRasterCount();
    1383             187 :         panAllBandList = (int *) CPLMalloc(sizeof(int) * nListBands);
    1384             474 :         for( int i = 0; i < nListBands; i++ )
    1385             287 :             panAllBandList[i] = i+1;
    1386                 : 
    1387             187 :         panBandList = panAllBandList;
    1388                 :     }
    1389                 : 
    1390             193 :     if( pfnProgress == NULL )
    1391             181 :         pfnProgress = GDALDummyProgress;
    1392                 : 
    1393                 :     eErr = IBuildOverviews( pszResampling, nOverviews, panOverviewList, 
    1394             193 :                             nListBands, panBandList, pfnProgress, pProgressData );
    1395                 : 
    1396             193 :     if( panAllBandList != NULL )
    1397             187 :         CPLFree( panAllBandList );
    1398                 : 
    1399             193 :     return eErr;
    1400                 : }
    1401                 : 
    1402                 : /************************************************************************/
    1403                 : /*                         GDALBuildOverviews()                         */
    1404                 : /************************************************************************/
    1405                 : 
    1406                 : /**
    1407                 :  * \brief Build raster overview(s)
    1408                 :  *
    1409                 :  * @see GDALDataset::BuildOverviews()
    1410                 :  */
    1411                 : 
    1412             185 : CPLErr CPL_STDCALL GDALBuildOverviews( GDALDatasetH hDataset,
    1413                 :                            const char *pszResampling, 
    1414                 :                            int nOverviews, int *panOverviewList, 
    1415                 :                            int nListBands, int *panBandList,
    1416                 :                            GDALProgressFunc pfnProgress, 
    1417                 :                            void * pProgressData )
    1418                 : 
    1419                 : {
    1420             185 :     VALIDATE_POINTER1( hDataset, "GDALBuildOverviews", CE_Failure );
    1421                 : 
    1422                 :     return ((GDALDataset *) hDataset)->BuildOverviews(
    1423                 :         pszResampling, nOverviews, panOverviewList, nListBands, panBandList, 
    1424             185 :         pfnProgress, pProgressData );
    1425                 : }
    1426                 :     
    1427                 : /************************************************************************/
    1428                 : /*                          IBuildOverviews()                           */
    1429                 : /*                                                                      */
    1430                 : /*      Default implementation.                                         */
    1431                 : /************************************************************************/
    1432                 : 
    1433              85 : CPLErr GDALDataset::IBuildOverviews( const char *pszResampling, 
    1434                 :                                      int nOverviews, int *panOverviewList, 
    1435                 :                                      int nListBands, int *panBandList,
    1436                 :                                      GDALProgressFunc pfnProgress, 
    1437                 :                                      void * pProgressData )
    1438                 :     
    1439                 : {
    1440              85 :     if( oOvManager.IsInitialized() )
    1441                 :         return oOvManager.BuildOverviews( NULL, pszResampling, 
    1442                 :                                           nOverviews, panOverviewList,
    1443                 :                                           nListBands, panBandList,
    1444              85 :                                           pfnProgress, pProgressData );
    1445                 :     else
    1446                 :     {
    1447                 :         ReportError( CE_Failure, CPLE_NotSupported,
    1448               0 :                   "BuildOverviews() not supported for this dataset." );
    1449                 :         
    1450               0 :         return( CE_Failure );
    1451                 :     }
    1452                 : }
    1453                 : 
    1454                 : /************************************************************************/
    1455                 : /*                             IRasterIO()                              */
    1456                 : /*                                                                      */
    1457                 : /*      The default implementation of IRasterIO() is to pass the        */
    1458                 : /*      request off to each band objects rasterio methods with          */
    1459                 : /*      appropriate arguments.                                          */
    1460                 : /************************************************************************/
    1461                 : 
    1462          364497 : CPLErr GDALDataset::IRasterIO( GDALRWFlag eRWFlag,
    1463                 :                                int nXOff, int nYOff, int nXSize, int nYSize,
    1464                 :                                void * pData, int nBufXSize, int nBufYSize,
    1465                 :                                GDALDataType eBufType, 
    1466                 :                                int nBandCount, int *panBandMap,
    1467                 :                                int nPixelSpace, int nLineSpace, int nBandSpace)
    1468                 :     
    1469                 : {
    1470                 :     int iBandIndex; 
    1471          364497 :     CPLErr eErr = CE_None;
    1472          364497 :     const char* pszInterleave = NULL;
    1473                 : 
    1474          364497 :     CPLAssert( NULL != pData );
    1475                 : 
    1476          396916 :     if (nXSize == nBufXSize && nYSize == nBufYSize &&
    1477           32419 :         (pszInterleave = GetMetadataItem("INTERLEAVE", "IMAGE_STRUCTURE")) != NULL &&
    1478                 :         EQUAL(pszInterleave, "PIXEL"))
    1479                 :     {
    1480                 :         return BlockBasedRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
    1481                 :                                    pData, nBufXSize, nBufYSize,
    1482                 :                                    eBufType, nBandCount, panBandMap,
    1483            1513 :                                    nPixelSpace, nLineSpace, nBandSpace );
    1484                 :     }
    1485                 : 
    1486          752682 :     for( iBandIndex = 0; 
    1487                 :          iBandIndex < nBandCount && eErr == CE_None; 
    1488                 :          iBandIndex++ )
    1489                 :     {
    1490          389698 :         GDALRasterBand *poBand = GetRasterBand(panBandMap[iBandIndex]);
    1491                 :         GByte *pabyBandData;
    1492                 : 
    1493          389698 :         if (poBand == NULL)
    1494                 :         {
    1495               0 :             eErr = CE_Failure;
    1496               0 :             break;
    1497                 :         }
    1498                 : 
    1499          389698 :         pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace;
    1500                 :         
    1501                 :         eErr = poBand->IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 
    1502                 :                                   (void *) pabyBandData, nBufXSize, nBufYSize,
    1503          389698 :                                   eBufType, nPixelSpace, nLineSpace );
    1504                 :     }
    1505                 : 
    1506          362984 :     return eErr;
    1507                 : }
    1508                 : 
    1509                 : 
    1510                 : /************************************************************************/
    1511                 : /*                              RasterIO()                              */
    1512                 : /************************************************************************/
    1513                 : 
    1514                 : /**
    1515                 :  * \brief Read/write a region of image data from multiple bands.
    1516                 :  *
    1517                 :  * This method allows reading a region of one or more GDALRasterBands from
    1518                 :  * this dataset into a buffer,  or writing data from a buffer into a region 
    1519                 :  * of the GDALRasterBands.  It automatically takes care of data type
    1520                 :  * translation if the data type (eBufType) of the buffer is different than
    1521                 :  * that of the GDALRasterBand.
    1522                 :  * The method also takes care of image decimation / replication if the
    1523                 :  * buffer size (nBufXSize x nBufYSize) is different than the size of the
    1524                 :  * region being accessed (nXSize x nYSize).
    1525                 :  *
    1526                 :  * The nPixelSpace, nLineSpace and nBandSpace parameters allow reading into or
    1527                 :  * writing from various organization of buffers. 
    1528                 :  *
    1529                 :  * For highest performance full resolution data access, read and write
    1530                 :  * on "block boundaries" as returned by GetBlockSize(), or use the
    1531                 :  * ReadBlock() and WriteBlock() methods.
    1532                 :  *
    1533                 :  * This method is the same as the C GDALDatasetRasterIO() function.
    1534                 :  *
    1535                 :  * @param eRWFlag Either GF_Read to read a region of data, or GF_Write to
    1536                 :  * write a region of data.
    1537                 :  *
    1538                 :  * @param nXOff The pixel offset to the top left corner of the region
    1539                 :  * of the band to be accessed.  This would be zero to start from the left side.
    1540                 :  *
    1541                 :  * @param nYOff The line offset to the top left corner of the region
    1542                 :  * of the band to be accessed.  This would be zero to start from the top.
    1543                 :  *
    1544                 :  * @param nXSize The width of the region of the band to be accessed in pixels.
    1545                 :  *
    1546                 :  * @param nYSize The height of the region of the band to be accessed in lines.
    1547                 :  *
    1548                 :  * @param pData The buffer into which the data should be read, or from which
    1549                 :  * it should be written.  This buffer must contain at least
    1550                 :  * nBufXSize * nBufYSize * nBandCount words of type eBufType.  It is organized
    1551                 :  * in left to right,top to bottom pixel order.  Spacing is controlled by the
    1552                 :  * nPixelSpace, and nLineSpace parameters.
    1553                 :  *
    1554                 :  * @param nBufXSize the width of the buffer image into which the desired region
    1555                 :  * is to be read, or from which it is to be written.
    1556                 :  *
    1557                 :  * @param nBufYSize the height of the buffer image into which the desired
    1558                 :  * region is to be read, or from which it is to be written.
    1559                 :  *
    1560                 :  * @param eBufType the type of the pixel values in the pData data buffer. The
    1561                 :  * pixel values will automatically be translated to/from the GDALRasterBand
    1562                 :  * data type as needed.
    1563                 :  *
    1564                 :  * @param nBandCount the number of bands being read or written. 
    1565                 :  *
    1566                 :  * @param panBandMap the list of nBandCount band numbers being read/written.
    1567                 :  * Note band numbers are 1 based. This may be NULL to select the first 
    1568                 :  * nBandCount bands.
    1569                 :  *
    1570                 :  * @param nPixelSpace The byte offset from the start of one pixel value in
    1571                 :  * pData to the start of the next pixel value within a scanline. If defaulted
    1572                 :  * (0) the size of the datatype eBufType is used.
    1573                 :  *
    1574                 :  * @param nLineSpace The byte offset from the start of one scanline in
    1575                 :  * pData to the start of the next. If defaulted (0) the size of the datatype
    1576                 :  * eBufType * nBufXSize is used.
    1577                 :  *
    1578                 :  * @param nBandSpace the byte offset from the start of one bands data to the
    1579                 :  * start of the next. If defaulted (0) the value will be 
    1580                 :  * nLineSpace * nBufYSize implying band sequential organization
    1581                 :  * of the data buffer. 
    1582                 :  *
    1583                 :  * @return CE_Failure if the access fails, otherwise CE_None.
    1584                 :  */
    1585                 : 
    1586          365146 : CPLErr GDALDataset::RasterIO( GDALRWFlag eRWFlag,
    1587                 :                               int nXOff, int nYOff, int nXSize, int nYSize,
    1588                 :                               void * pData, int nBufXSize, int nBufYSize,
    1589                 :                               GDALDataType eBufType, 
    1590                 :                               int nBandCount, int *panBandMap,
    1591                 :                               int nPixelSpace, int nLineSpace, int nBandSpace )
    1592                 : 
    1593                 : {
    1594          365146 :     int i = 0;
    1595          365146 :     int bNeedToFreeBandMap = FALSE;
    1596          365146 :     CPLErr eErr = CE_None;
    1597                 : 
    1598          365146 :     if( NULL == pData )
    1599                 :     {
    1600                 :         ReportError( CE_Failure, CPLE_AppDefined,
    1601               0 :                   "The buffer into which the data should be read is null" );
    1602               0 :             return CE_Failure;
    1603                 :     }
    1604                 : 
    1605                 : /* -------------------------------------------------------------------- */
    1606                 : /*      Some size values are "noop".  Lets just return to avoid         */
    1607                 : /*      stressing lower level functions.                                */
    1608                 : /* -------------------------------------------------------------------- */
    1609          365146 :     if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
    1610                 :     {
    1611                 :         CPLDebug( "GDAL", 
    1612                 :                   "RasterIO() skipped for odd window or buffer size.\n"
    1613                 :                   "  Window = (%d,%d)x%dx%d\n"
    1614                 :                   "  Buffer = %dx%d\n",
    1615                 :                   nXOff, nYOff, nXSize, nYSize, 
    1616               0 :                   nBufXSize, nBufYSize );
    1617                 : 
    1618               0 :         return CE_None;
    1619                 :     }
    1620                 : 
    1621                 : /* -------------------------------------------------------------------- */
    1622                 : /*      If pixel and line spacing are defaulted assign reasonable      */
    1623                 : /*      value assuming a packed buffer.                                 */
    1624                 : /* -------------------------------------------------------------------- */
    1625          365146 :     if( nPixelSpace == 0 )
    1626          340775 :         nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
    1627                 :     
    1628          365146 :     if( nLineSpace == 0 )
    1629                 :     {
    1630          357880 :         if (nPixelSpace > INT_MAX / nBufXSize)
    1631                 :         {
    1632                 :             ReportError( CE_Failure, CPLE_AppDefined,
    1633               0 :                       "Int overflow : %d x %d", nPixelSpace, nBufXSize );
    1634               0 :             return CE_Failure;
    1635                 :         }
    1636          357880 :         nLineSpace = nPixelSpace * nBufXSize;
    1637                 :     }
    1638                 :     
    1639                 :     /* The nBandCount > 1 test is necessary to allow reading only */
    1640                 :     /* one band, even if the nLineSpace would overflow, but as it */
    1641                 :     /* is not used in that case, it can be left to 0 (#3481) */
    1642          365146 :     if( nBandSpace == 0 && nBandCount > 1 )
    1643                 :     {
    1644            1088 :         if (nLineSpace > INT_MAX / nBufYSize)
    1645                 :         {
    1646                 :             ReportError( CE_Failure, CPLE_AppDefined,
    1647               0 :                       "Int overflow : %d x %d", nLineSpace, nBufYSize );
    1648               0 :             return CE_Failure;
    1649                 :         }
    1650            1088 :         nBandSpace = nLineSpace * nBufYSize;
    1651                 :     }
    1652                 : 
    1653          365146 :     if( panBandMap == NULL )
    1654                 :     {
    1655           22612 :         if (nBandCount > GetRasterCount())
    1656                 :         {
    1657                 :             ReportError( CE_Failure, CPLE_IllegalArg,
    1658                 :                       "nBandCount cannot be greater than %d",
    1659               0 :                       GetRasterCount() );
    1660               0 :             return CE_Failure;
    1661                 :         }
    1662           22612 :         panBandMap = (int *) VSIMalloc2(sizeof(int), nBandCount);
    1663           22612 :         if (panBandMap == NULL)
    1664                 :         {
    1665                 :             ReportError( CE_Failure, CPLE_OutOfMemory,
    1666               0 :                       "Out of memory while allocating band map array" );
    1667               0 :             return CE_Failure;
    1668                 :         }
    1669           72620 :         for( i = 0; i < nBandCount; i++ )
    1670           50008 :             panBandMap[i] = i+1;
    1671                 : 
    1672           22612 :         bNeedToFreeBandMap = TRUE;
    1673                 :     }
    1674                 :     
    1675                 : /* -------------------------------------------------------------------- */
    1676                 : /*      Do some validation of parameters.                               */
    1677                 : /* -------------------------------------------------------------------- */
    1678          365146 :     if( nXOff < 0 || nXOff > INT_MAX - nXSize || nXOff + nXSize > nRasterXSize
    1679                 :         || nYOff < 0 || nYOff > INT_MAX - nYSize || nYOff + nYSize > nRasterYSize )
    1680                 :     {
    1681                 :         ReportError( CE_Failure, CPLE_IllegalArg,
    1682                 :                   "Access window out of range in RasterIO().  Requested\n"
    1683                 :                   "(%d,%d) of size %dx%d on raster of %dx%d.",
    1684               2 :                   nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
    1685               2 :         eErr = CE_Failure;
    1686                 :     }
    1687                 : 
    1688          365146 :     if( eRWFlag != GF_Read && eRWFlag != GF_Write )
    1689                 :     {
    1690                 :         ReportError( CE_Failure, CPLE_IllegalArg,
    1691                 :                   "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
    1692               0 :                   eRWFlag );
    1693               0 :         eErr = CE_Failure;
    1694                 :     }
    1695                 : 
    1696          761353 :     for( i = 0; i < nBandCount && eErr == CE_None; i++ )
    1697                 :     {
    1698          396207 :         if( panBandMap[i] < 1 || panBandMap[i] > GetRasterCount() )
    1699                 :         {
    1700                 :             ReportError( CE_Failure, CPLE_IllegalArg,
    1701                 :                       "panBandMap[%d] = %d, this band does not exist on dataset.",
    1702               0 :                       i, panBandMap[i] );
    1703               0 :             eErr = CE_Failure;
    1704                 :         }
    1705                 : 
    1706          396207 :         if( eErr == CE_None && GetRasterBand( panBandMap[i] ) == NULL )
    1707                 :         {
    1708                 :             ReportError( CE_Failure, CPLE_IllegalArg,
    1709                 :                       "panBandMap[%d]=%d, this band should exist but is NULL!",
    1710               0 :                       i, panBandMap[i] );
    1711               0 :             eErr = CE_Failure;
    1712                 :         }
    1713                 :     }
    1714                 : 
    1715                 : /* -------------------------------------------------------------------- */
    1716                 : /*      We are being forced to use cached IO instead of a driver        */
    1717                 : /*      specific implementation.                                        */
    1718                 : /* -------------------------------------------------------------------- */
    1719          365146 :     if( bForceCachedIO )
    1720                 :     {
    1721                 :         eErr = 
    1722                 :             BlockBasedRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
    1723                 :                                 pData, nBufXSize, nBufYSize, eBufType,
    1724                 :                                 nBandCount, panBandMap,
    1725               6 :                                 nPixelSpace, nLineSpace, nBandSpace );
    1726                 :     }
    1727                 : 
    1728                 : /* -------------------------------------------------------------------- */
    1729                 : /*      Call the format specific function.                              */
    1730                 : /* -------------------------------------------------------------------- */
    1731          365140 :     else if( eErr == CE_None )
    1732                 :     {
    1733                 :         eErr = 
    1734                 :             IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
    1735                 :                        pData, nBufXSize, nBufYSize, eBufType,
    1736                 :                        nBandCount, panBandMap,
    1737          365138 :                        nPixelSpace, nLineSpace, nBandSpace );
    1738                 :     }
    1739                 : 
    1740                 : /* -------------------------------------------------------------------- */
    1741                 : /*      Cleanup                                                         */
    1742                 : /* -------------------------------------------------------------------- */
    1743          365146 :     if( bNeedToFreeBandMap )
    1744           22612 :         CPLFree( panBandMap );
    1745                 : 
    1746          365146 :     return eErr;
    1747                 : }
    1748                 : 
    1749                 : /************************************************************************/
    1750                 : /*                        GDALDatasetRasterIO()                         */
    1751                 : /************************************************************************/
    1752                 : 
    1753                 : /**
    1754                 :  * \brief Read/write a region of image data from multiple bands.
    1755                 :  *
    1756                 :  * @see GDALDataset::RasterIO()
    1757                 :  */
    1758                 : 
    1759                 : CPLErr CPL_STDCALL              
    1760          340244 : GDALDatasetRasterIO( GDALDatasetH hDS, GDALRWFlag eRWFlag,
    1761                 :                      int nXOff, int nYOff, int nXSize, int nYSize,
    1762                 :                      void * pData, int nBufXSize, int nBufYSize,
    1763                 :                      GDALDataType eBufType,
    1764                 :                      int nBandCount, int *panBandMap,
    1765                 :                      int nPixelSpace, int nLineSpace, int nBandSpace )
    1766                 :     
    1767                 : {
    1768          340244 :     VALIDATE_POINTER1( hDS, "GDALDatasetRasterIO", CE_Failure );
    1769                 : 
    1770          340244 :     GDALDataset    *poDS = (GDALDataset *) hDS;
    1771                 :     
    1772                 :     return( poDS->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
    1773                 :                             pData, nBufXSize, nBufYSize, eBufType,
    1774                 :                             nBandCount, panBandMap, 
    1775          340244 :                             nPixelSpace, nLineSpace, nBandSpace ) );
    1776                 : }
    1777                 :                      
    1778                 : /************************************************************************/
    1779                 : /*                          GetOpenDatasets()                           */
    1780                 : /************************************************************************/
    1781                 : 
    1782              10 : static int GDALGetOpenDatasetsForeach(void* elt, void* user_data)
    1783                 : {
    1784              10 :     int* pnIndex = (int*) user_data;
    1785              10 :     DatasetCtxt* psStruct = (DatasetCtxt*) elt;
    1786                 : 
    1787              10 :     ppDatasets[*pnIndex] = psStruct->poDS;
    1788                 : 
    1789              10 :     (*pnIndex) ++;
    1790                 : 
    1791              10 :     return TRUE;
    1792                 : }
    1793                 : 
    1794                 : /**
    1795                 :  * \brief Fetch all open GDAL dataset handles.
    1796                 :  *
    1797                 :  * This method is the same as the C function GDALGetOpenDatasets().
    1798                 :  *
    1799                 :  * NOTE: This method is not thread safe.  The returned list may change
    1800                 :  * at any time and it should not be freed.
    1801                 :  *
    1802                 :  * @param pnCount integer into which to place the count of dataset pointers
    1803                 :  * being returned.
    1804                 :  *
    1805                 :  * @return a pointer to an array of dataset handles. 
    1806                 :  */
    1807                 : 
    1808            1100 : GDALDataset **GDALDataset::GetOpenDatasets( int *pnCount )
    1809                 : 
    1810                 : {
    1811            1100 :     CPLMutexHolderD( &hDLMutex );
    1812                 : 
    1813            1100 :     if (phAllDatasetSet != NULL)
    1814                 :     {
    1815               2 :         int nIndex = 0;
    1816               2 :         *pnCount = CPLHashSetSize(phAllDatasetSet);
    1817               2 :         ppDatasets = (GDALDataset**) CPLRealloc(ppDatasets, (*pnCount) * sizeof(GDALDataset*));
    1818               2 :         CPLHashSetForeach(phAllDatasetSet, GDALGetOpenDatasetsForeach, &nIndex);
    1819               2 :         return ppDatasets;
    1820                 :     }
    1821                 :     else
    1822                 :     {
    1823            1098 :         *pnCount = 0;
    1824            1098 :         return NULL;
    1825               0 :     }
    1826                 : }
    1827                 : 
    1828                 : /************************************************************************/
    1829                 : /*                        GDALGetOpenDatasets()                         */
    1830                 : /************************************************************************/
    1831                 : 
    1832                 : /**
    1833                 :  * \brief Fetch all open GDAL dataset handles.
    1834                 :  *
    1835                 :  * @see GDALDataset::GetOpenDatasets()
    1836                 :  */
    1837                 : 
    1838               0 : void CPL_STDCALL GDALGetOpenDatasets( GDALDatasetH **ppahDSList, int *pnCount )
    1839                 : 
    1840                 : {
    1841               0 :     VALIDATE_POINTER0( ppahDSList, "GDALGetOpenDatasets" );
    1842               0 :     VALIDATE_POINTER0( pnCount, "GDALGetOpenDatasets" );
    1843                 : 
    1844               0 :     *ppahDSList = (GDALDatasetH *) GDALDataset::GetOpenDatasets( pnCount);
    1845                 : }
    1846                 : 
    1847                 : 
    1848                 : /************************************************************************/
    1849                 : /*                        GDALCleanOpenDatasetsList()                   */
    1850                 : /************************************************************************/
    1851                 : 
    1852                 : /* Usefull when called from the child of a fork(), to avoid closing */
    1853                 : /* the datasets of the parent at the child termination */
    1854               0 : void GDALNullifyOpenDatasetsList()
    1855                 : {
    1856               0 :     phAllDatasetSet = NULL;
    1857               0 :     phSharedDatasetSet = NULL;
    1858               0 :     ppDatasets = NULL;
    1859               0 :     hDLMutex = NULL;
    1860               0 : }
    1861                 : 
    1862                 : /************************************************************************/
    1863                 : /*                             GDALGetAccess()                          */
    1864                 : /************************************************************************/
    1865                 : 
    1866                 : /**
    1867                 :  * \brief Return access flag
    1868                 :  *
    1869                 :  * @see GDALDataset::GetAccess()
    1870                 :  */
    1871                 : 
    1872               0 : int CPL_STDCALL GDALGetAccess( GDALDatasetH hDS )
    1873                 : {
    1874               0 :     VALIDATE_POINTER1( hDS, "GDALGetAccess", 0 );
    1875                 : 
    1876               0 :     return ((GDALDataset *) hDS)->GetAccess();
    1877                 : }
    1878                 : 
    1879                 : /************************************************************************/
    1880                 : /*                             AdviseRead()                             */
    1881                 : /************************************************************************/
    1882                 : 
    1883                 : /**
    1884                 :  * \brief Advise driver of upcoming read requests.
    1885                 :  *
    1886                 :  * Some GDAL drivers operate more efficiently if they know in advance what 
    1887                 :  * set of upcoming read requests will be made.  The AdviseRead() method allows
    1888                 :  * an application to notify the driver of the region and bands of interest, 
    1889                 :  * and at what resolution the region will be read.  
    1890                 :  *
    1891                 :  * Many drivers just ignore the AdviseRead() call, but it can dramatically
    1892                 :  * accelerate access via some drivers.  
    1893                 :  *
    1894                 :  * @param nXOff The pixel offset to the top left corner of the region
    1895                 :  * of the band to be accessed.  This would be zero to start from the left side.
    1896                 :  *
    1897                 :  * @param nYOff The line offset to the top left corner of the region
    1898                 :  * of the band to be accessed.  This would be zero to start from the top.
    1899                 :  *
    1900                 :  * @param nXSize The width of the region of the band to be accessed in pixels.
    1901                 :  *
    1902                 :  * @param nYSize The height of the region of the band to be accessed in lines.
    1903                 :  *
    1904                 :  * @param nBufXSize the width of the buffer image into which the desired region
    1905                 :  * is to be read, or from which it is to be written.
    1906                 :  *
    1907                 :  * @param nBufYSize the height of the buffer image into which the desired
    1908                 :  * region is to be read, or from which it is to be written.
    1909                 :  *
    1910                 :  * @param eBufType the type of the pixel values in the pData data buffer.  The
    1911                 :  * pixel values will automatically be translated to/from the GDALRasterBand
    1912                 :  * data type as needed.
    1913                 :  *
    1914                 :  * @param nBandCount the number of bands being read or written. 
    1915                 :  *
    1916                 :  * @param panBandMap the list of nBandCount band numbers being read/written.
    1917                 :  * Note band numbers are 1 based.   This may be NULL to select the first 
    1918                 :  * nBandCount bands.
    1919                 :  *
    1920                 :  * @param papszOptions a list of name=value strings with special control 
    1921                 :  * options.  Normally this is NULL.
    1922                 :  *
    1923                 :  * @return CE_Failure if the request is invalid and CE_None if it works or
    1924                 :  * is ignored. 
    1925                 :  */
    1926                 : 
    1927               0 : CPLErr GDALDataset::AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
    1928                 :                                 int nBufXSize, int nBufYSize, 
    1929                 :                                 GDALDataType eBufType, 
    1930                 :                                 int nBandCount, int *panBandMap,
    1931                 :                                 char **papszOptions )
    1932                 : 
    1933                 : {
    1934                 :     int iBand;
    1935                 : 
    1936               0 :     for( iBand = 0; iBand < nBandCount; iBand++ )
    1937                 :     {
    1938                 :         CPLErr eErr;
    1939                 :         GDALRasterBand *poBand;
    1940                 : 
    1941               0 :         if( panBandMap == NULL )
    1942               0 :             poBand = GetRasterBand(iBand+1);
    1943                 :         else
    1944               0 :             poBand = GetRasterBand(panBandMap[iBand]);
    1945                 : 
    1946                 :         eErr = poBand->AdviseRead( nXOff, nYOff, nXSize, nYSize,
    1947               0 :                                    nBufXSize, nBufYSize, eBufType, papszOptions );
    1948                 : 
    1949               0 :         if( eErr != CE_None )
    1950               0 :             return eErr;
    1951                 :     }
    1952                 :     
    1953               0 :     return CE_None;
    1954                 : }
    1955                 : 
    1956                 : /************************************************************************/
    1957                 : /*                       GDALDatasetAdviseRead()                        */
    1958                 : /************************************************************************/
    1959                 : 
    1960                 : /**
    1961                 :  * \brief Advise driver of upcoming read requests.
    1962                 :  *
    1963                 :  * @see GDALDataset::AdviseRead()
    1964                 :  */
    1965                 : CPLErr CPL_STDCALL 
    1966               0 : GDALDatasetAdviseRead( GDALDatasetH hDS, 
    1967                 :                        int nXOff, int nYOff, int nXSize, int nYSize,
    1968                 :                        int nBufXSize, int nBufYSize, GDALDataType eDT, 
    1969                 :                        int nBandCount, int *panBandMap,char **papszOptions )
    1970                 :     
    1971                 : {
    1972               0 :     VALIDATE_POINTER1( hDS, "GDALDatasetAdviseRead", CE_Failure );
    1973                 : 
    1974                 :     return ((GDALDataset *) hDS)->AdviseRead( nXOff, nYOff, nXSize, nYSize, 
    1975                 :                                               nBufXSize, nBufYSize, eDT, 
    1976                 :                                               nBandCount, panBandMap, 
    1977               0 :                                               papszOptions );
    1978                 : }
    1979                 : 
    1980                 : /************************************************************************/
    1981                 : /*                            GetFileList()                             */
    1982                 : /************************************************************************/
    1983                 : 
    1984                 : /**
    1985                 :  * \brief Fetch files forming dataset.
    1986                 :  *
    1987                 :  * Returns a list of files believed to be part of this dataset.  If it returns
    1988                 :  * an empty list of files it means there is believed to be no local file
    1989                 :  * system files associated with the dataset (for instance a virtual dataset).
    1990                 :  * The returned file list is owned by the caller and should be deallocated
    1991                 :  * with CSLDestroy().
    1992                 :  * 
    1993                 :  * The returned filenames will normally be relative or absolute paths 
    1994                 :  * depending on the path used to originally open the dataset.  The strings
    1995                 :  * will be UTF-8 encoded.
    1996                 :  *
    1997                 :  * This method is the same as the C GDALGetFileList() function.
    1998                 :  *
    1999                 :  * @return NULL or a NULL terminated array of file names. 
    2000                 :  */
    2001                 : 
    2002            1589 : char **GDALDataset::GetFileList()
    2003                 : 
    2004                 : {
    2005            1589 :     CPLString osMainFilename = GetDescription();
    2006                 :     int bMainFileReal;
    2007                 :     VSIStatBufL  sStat;
    2008                 : 
    2009                 : /* -------------------------------------------------------------------- */
    2010                 : /*      Is the main filename even a real filesystem object?             */
    2011                 : /* -------------------------------------------------------------------- */
    2012            1589 :     bMainFileReal = VSIStatExL( osMainFilename, &sStat, VSI_STAT_EXISTS_FLAG ) == 0;
    2013                 : 
    2014                 : /* -------------------------------------------------------------------- */
    2015                 : /*      Form new list.                                                  */
    2016                 : /* -------------------------------------------------------------------- */
    2017            1589 :     char **papszList = NULL;
    2018                 : 
    2019            1589 :     if( bMainFileReal )
    2020            1582 :         papszList = CSLAddString( papszList, osMainFilename );
    2021                 : 
    2022                 : /* -------------------------------------------------------------------- */
    2023                 : /*      Do we have a known overview file?                               */
    2024                 : /* -------------------------------------------------------------------- */
    2025            1589 :     if( oOvManager.IsInitialized() && oOvManager.poODS != NULL )
    2026                 :     {
    2027              66 :         char **papszOvrList = oOvManager.poODS->GetFileList();
    2028              66 :         papszList = CSLInsertStrings( papszList, -1, papszOvrList );
    2029              66 :         CSLDestroy( papszOvrList );
    2030                 :     }
    2031                 : 
    2032                 : /* -------------------------------------------------------------------- */
    2033                 : /*      Do we have a known overview file?                               */
    2034                 : /* -------------------------------------------------------------------- */
    2035            1589 :     if( oOvManager.HaveMaskFile() )
    2036                 :     {
    2037               7 :         char **papszMskList = oOvManager.poMaskDS->GetFileList();
    2038               7 :         char **papszIter = papszMskList;
    2039              20 :         while( papszIter && *papszIter )
    2040                 :         {
    2041               6 :             if( CSLFindString( papszList, *papszIter ) < 0 )
    2042               6 :                 papszList = CSLAddString( papszList, *papszIter );
    2043               6 :             papszIter ++;
    2044                 :         }
    2045               7 :         CSLDestroy( papszMskList );
    2046                 :     }
    2047                 : 
    2048                 : /* -------------------------------------------------------------------- */
    2049                 : /*      Do we have a world file?                                        */
    2050                 : /* -------------------------------------------------------------------- */
    2051            1589 :     if( bMainFileReal )
    2052                 :     {
    2053            1582 :         const char* pszExtension = CPLGetExtension( osMainFilename );
    2054            1582 :         if( strlen(pszExtension) > 2 )
    2055                 :         {
    2056                 :             // first + last + 'w'
    2057                 :             char szDerivedExtension[4];
    2058            1574 :             szDerivedExtension[0] = pszExtension[0];
    2059            1574 :             szDerivedExtension[1] = pszExtension[strlen(pszExtension)-1];
    2060            1574 :             szDerivedExtension[2] = 'w';
    2061            1574 :             szDerivedExtension[3] = '\0';
    2062            1574 :             CPLString osWorldFilename = CPLResetExtension( osMainFilename, szDerivedExtension );
    2063                 : 
    2064            1574 :             if (oOvManager.papszInitSiblingFiles)
    2065                 :             {
    2066                 :                 int iSibling = CSLFindString(oOvManager.papszInitSiblingFiles,
    2067            1048 :                                              CPLGetFilename(osWorldFilename));
    2068            1048 :                 if (iSibling >= 0)
    2069                 :                 {
    2070                 :                     osWorldFilename.resize(strlen(osWorldFilename) -
    2071               2 :                                            strlen(oOvManager.papszInitSiblingFiles[iSibling]));
    2072               2 :                     osWorldFilename += oOvManager.papszInitSiblingFiles[iSibling];
    2073               2 :                     papszList = CSLAddString( papszList, osWorldFilename );
    2074                 :                 }
    2075                 :             }
    2076             526 :             else if( VSIStatExL( osWorldFilename, &sStat, VSI_STAT_EXISTS_FLAG ) == 0 )
    2077               1 :                 papszList = CSLAddString( papszList, osWorldFilename );
    2078                 :         }
    2079                 :     }
    2080                 : 
    2081            1589 :     return papszList;
    2082                 : }
    2083                 : 
    2084                 : /************************************************************************/
    2085                 : /*                          GDALGetFileList()                           */
    2086                 : /************************************************************************/
    2087                 : 
    2088                 : /**
    2089                 :  * \brief Fetch files forming dataset.
    2090                 :  *
    2091                 :  * @see GDALDataset::GetFileList()
    2092                 :  */
    2093                 : 
    2094            1497 : char ** CPL_STDCALL GDALGetFileList( GDALDatasetH hDS )
    2095                 : 
    2096                 : {
    2097            1497 :     VALIDATE_POINTER1( hDS, "GDALGetFileList", NULL );
    2098                 : 
    2099            1497 :     return ((GDALDataset *) hDS)->GetFileList();
    2100                 : }
    2101                 : 
    2102                 : /************************************************************************/
    2103                 : /*                           CreateMaskBand()                           */
    2104                 : /************************************************************************/
    2105                 : 
    2106                 : /**
    2107                 :  * \brief Adds a mask band to the dataset
    2108                 :  *
    2109                 :  * The default implementation of the CreateMaskBand() method is implemented
    2110                 :  * based on similar rules to the .ovr handling implemented using the
    2111                 :  * GDALDefaultOverviews object. A TIFF file with the extension .msk will
    2112                 :  * be created with the same basename as the original file, and it will have
    2113                 :  * one band.
    2114                 :  * The mask images will be deflate compressed tiled images with the same
    2115                 :  * block size as the original image if possible.
    2116                 :  *
    2117                 :  * Note that if you got a mask band with a previous call to GetMaskBand(),
    2118                 :  * it might be invalidated by CreateMaskBand(). So you have to call GetMaskBand()
    2119                 :  * again.
    2120                 :  *
    2121                 :  * @since GDAL 1.5.0
    2122                 :  *
    2123                 :  * @param nFlags ignored. GMF_PER_DATASET will be assumed.
    2124                 :  * @return CE_None on success or CE_Failure on an error.
    2125                 :  *
    2126                 :  * @see http://trac.osgeo.org/gdal/wiki/rfc15_nodatabitmask
    2127                 :  *
    2128                 :  */
    2129               7 : CPLErr GDALDataset::CreateMaskBand( int nFlags )
    2130                 : 
    2131                 : {
    2132               7 :     if( oOvManager.IsInitialized() )
    2133                 :     {
    2134               7 :         CPLErr eErr = oOvManager.CreateMaskBand( nFlags, -1 );
    2135               7 :         if (eErr != CE_None)
    2136               0 :             return eErr;
    2137                 : 
    2138                 :         /* Invalidate existing raster band masks */
    2139                 :         int i;
    2140              20 :         for(i=0;i<nBands;i++)
    2141                 :         {
    2142              13 :             GDALRasterBand* poBand = papoBands[i];
    2143              13 :             if (poBand->bOwnMask)
    2144               3 :                 delete poBand->poMask;
    2145              13 :             poBand->bOwnMask = false;
    2146              13 :             poBand->poMask = NULL;
    2147                 :         }
    2148                 : 
    2149               7 :         return CE_None;
    2150                 :     }
    2151                 : 
    2152                 :     ReportError( CE_Failure, CPLE_NotSupported,
    2153               0 :               "CreateMaskBand() not supported for this dataset." );
    2154                 :     
    2155               0 :     return( CE_Failure );
    2156                 : }
    2157                 : 
    2158                 : /************************************************************************/
    2159                 : /*                     GDALCreateDatasetMaskBand()                      */
    2160                 : /************************************************************************/
    2161                 : 
    2162                 : /**
    2163                 :  * \brief Adds a mask band to the dataset
    2164                 :  * @see GDALDataset::CreateMaskBand()
    2165                 :  */
    2166              22 : CPLErr CPL_STDCALL GDALCreateDatasetMaskBand( GDALDatasetH hDS, int nFlags )
    2167                 : 
    2168                 : {
    2169              22 :     VALIDATE_POINTER1( hDS, "GDALCreateDatasetMaskBand", CE_Failure );
    2170                 : 
    2171              22 :     return ((GDALDataset *) hDS)->CreateMaskBand( nFlags );
    2172                 : }
    2173                 : 
    2174                 : /************************************************************************/
    2175                 : /*                              GDALOpen()                              */
    2176                 : /************************************************************************/
    2177                 : 
    2178                 : /**
    2179                 :  * \brief Open a raster file as a GDALDataset.
    2180                 :  *
    2181                 :  * This function will try to open the passed file, or virtual dataset
    2182                 :  * name by invoking the Open method of each registered GDALDriver in turn. 
    2183                 :  * The first successful open will result in a returned dataset.  If all
    2184                 :  * drivers fail then NULL is returned and an error is issued.
    2185                 :  *
    2186                 :  * Several recommendations :
    2187                 :  * <ul>
    2188                 :  * <li>If you open a dataset object with GA_Update access, it is not recommended
    2189                 :  * to open a new dataset on the same underlying file.</li>
    2190                 :  * <li>The returned dataset should only be accessed by one thread at a time. If you
    2191                 :  * want to use it from different threads, you must add all necessary code (mutexes, etc.)
    2192                 :  * to avoid concurrent use of the object. (Some drivers, such as GeoTIFF, maintain internal
    2193                 :  * state variables that are updated each time a new block is read, thus preventing concurrent
    2194                 :  * use.) </li>
    2195                 :  * </ul>
    2196                 :  *
    2197                 :  * For drivers supporting the VSI virtual file API, it is possible to open
    2198                 :  * a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
    2199                 :  * (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
    2200                 :  *
    2201                 :  * In some situations (dealing with unverified data), the datasets can be opened in another
    2202                 :  * process through the \ref gdal_api_proxy mechanism.
    2203                 :  *
    2204                 :  * \sa GDALOpenShared()
    2205                 :  *
    2206                 :  * @param pszFilename the name of the file to access.  In the case of
    2207                 :  * exotic drivers this may not refer to a physical file, but instead contain
    2208                 :  * information for the driver on how to access a dataset.  It should be in UTF-8
    2209                 :  * encoding.
    2210                 :  *
    2211                 :  * @param eAccess the desired access, either GA_Update or GA_ReadOnly.  Many
    2212                 :  * drivers support only read only access.
    2213                 :  *
    2214                 :  * @return A GDALDatasetH handle or NULL on failure.  For C++ applications
    2215                 :  * this handle can be cast to a GDALDataset *. 
    2216                 :  */
    2217                 : 
    2218                 : GDALDatasetH CPL_STDCALL 
    2219            8876 : GDALOpen( const char * pszFilename, GDALAccess eAccess )
    2220                 : 
    2221                 : {
    2222            8876 :     return GDALOpenInternal(pszFilename, eAccess, NULL);
    2223                 : }
    2224                 : 
    2225                 : /* The drivers listed in papszAllowedDrivers can be in any order */
    2226                 : /* Only the order of registration will be taken into account */
    2227            8904 : GDALDatasetH GDALOpenInternal( const char * pszFilename, GDALAccess eAccess,
    2228                 :                                const char* const * papszAllowedDrivers)
    2229                 : {
    2230            8904 :     GDALOpenInfo oOpenInfo( pszFilename, eAccess );
    2231            8904 :     return GDALOpenInternal(oOpenInfo, papszAllowedDrivers);
    2232                 : }
    2233                 : 
    2234            9022 : GDALDatasetH GDALOpenInternal( GDALOpenInfo& oOpenInfo,
    2235                 :                                const char* const * papszAllowedDrivers)
    2236                 : {
    2237                 : 
    2238            9022 :     VALIDATE_POINTER1( oOpenInfo.pszFilename, "GDALOpen", NULL );
    2239                 : 
    2240                 :     {
    2241            9022 :         int* pnRecCount = (int*)CPLGetTLS( CTLS_GDALDATASET_REC_PROTECT_MAP );
    2242            9022 :         if( pnRecCount == NULL )
    2243                 :         {
    2244             517 :             pnRecCount = (int*) CPLMalloc(sizeof(int));
    2245             517 :             *pnRecCount = 0;
    2246             517 :             CPLSetTLS( CTLS_GDALDATASET_REC_PROTECT_MAP, pnRecCount, TRUE );
    2247                 :         }
    2248            9022 :         if( *pnRecCount == 100 )
    2249                 :         {
    2250                 :             CPLError(CE_Failure, CPLE_AppDefined,
    2251               1 :                      "GDALOpen() called with too many recursion levels");
    2252               1 :             return NULL;
    2253                 :         }
    2254            9021 :         (*pnRecCount) ++;
    2255                 :     }
    2256                 : 
    2257                 :     int         iDriver;
    2258            9021 :     GDALDriverManager *poDM = GetGDALDriverManager();
    2259            9021 :     CPLLocaleC  oLocaleForcer;
    2260                 : 
    2261            9021 :     CPLErrorReset();
    2262            9021 :     CPLAssert( NULL != poDM );
    2263                 : 
    2264          359856 :     for( iDriver = -1; iDriver < poDM->GetDriverCount(); iDriver++ )
    2265                 :     {
    2266                 :         GDALDriver      *poDriver;
    2267                 :         GDALDataset     *poDS;
    2268                 : 
    2269          358643 :         if( iDriver < 0 )
    2270            9021 :             poDriver = GDALGetAPIPROXYDriver();
    2271                 :         else
    2272                 :         {
    2273          349622 :             poDriver = poDM->GetDriver( iDriver );
    2274          349622 :             if (papszAllowedDrivers != NULL &&
    2275                 :                 CSLFindString((char**)papszAllowedDrivers, GDALGetDriverShortName(poDriver)) == -1)
    2276            2886 :                 continue;
    2277                 :         }
    2278                 : 
    2279          355757 :         if ( poDriver->pfnOpen == NULL )
    2280            3874 :             continue;
    2281                 : 
    2282          351883 :         poDS = poDriver->pfnOpen( &oOpenInfo );
    2283          351883 :         if( poDS != NULL )
    2284                 :         {
    2285            7643 :             if( strlen(poDS->GetDescription()) == 0 )
    2286             586 :                 poDS->SetDescription( oOpenInfo.pszFilename );
    2287                 : 
    2288            7643 :             if( poDS->poDriver == NULL )
    2289            6605 :                 poDS->poDriver = poDriver;
    2290                 : 
    2291                 : 
    2292            7643 :             if( CPLGetPID() != GDALGetResponsiblePIDForCurrentThread() )
    2293                 :                 CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s (pid=%d, responsiblePID=%d).",
    2294               0 :                           oOpenInfo.pszFilename, poDS, poDriver->GetDescription(),
    2295               0 :                           (int)CPLGetPID(), (int)GDALGetResponsiblePIDForCurrentThread() );
    2296                 :             else
    2297                 :                 CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s.",
    2298            7643 :                           oOpenInfo.pszFilename, poDS, poDriver->GetDescription() );
    2299                 : 
    2300            7643 :             int* pnRecCount = (int*)CPLGetTLS( CTLS_GDALDATASET_REC_PROTECT_MAP );
    2301            7643 :             if( pnRecCount )
    2302            7643 :                 (*pnRecCount) --;
    2303                 : 
    2304            7643 :             return (GDALDatasetH) poDS;
    2305                 :         }
    2306                 : 
    2307          344240 :         if( CPLGetLastErrorNo() != 0 )
    2308                 :         {
    2309             165 :             int* pnRecCount = (int*)CPLGetTLS( CTLS_GDALDATASET_REC_PROTECT_MAP );
    2310             165 :             if( pnRecCount )
    2311             165 :                 (*pnRecCount) --;
    2312                 : 
    2313             165 :             return NULL;
    2314                 :         }
    2315                 :     }
    2316                 : 
    2317            1213 :     if( oOpenInfo.bStatOK )
    2318                 :         CPLError( CE_Failure, CPLE_OpenFailed,
    2319                 :                   "`%s' not recognised as a supported file format.\n",
    2320              72 :                   oOpenInfo.pszFilename );
    2321                 :     else
    2322                 :         CPLError( CE_Failure, CPLE_OpenFailed,
    2323                 :                   "`%s' does not exist in the file system,\n"
    2324                 :                   "and is not recognised as a supported dataset name.\n",
    2325            1141 :                   oOpenInfo.pszFilename );
    2326                 : 
    2327            1213 :     int* pnRecCount = (int*)CPLGetTLS( CTLS_GDALDATASET_REC_PROTECT_MAP );
    2328            1213 :     if( pnRecCount )
    2329            1213 :         (*pnRecCount) --;
    2330                 : 
    2331            1213 :     return NULL;
    2332                 : }
    2333                 : 
    2334                 : /************************************************************************/
    2335                 : /*                           GDALOpenShared()                           */
    2336                 : /************************************************************************/
    2337                 : 
    2338                 : /**
    2339                 :  * \brief Open a raster file as a GDALDataset.
    2340                 :  *
    2341                 :  * This function works the same as GDALOpen(), but allows the sharing of
    2342                 :  * GDALDataset handles for a dataset with other callers to GDALOpenShared().
    2343                 :  * 
    2344                 :  * In particular, GDALOpenShared() will first consult it's list of currently
    2345                 :  * open and shared GDALDataset's, and if the GetDescription() name for one
    2346                 :  * exactly matches the pszFilename passed to GDALOpenShared() it will be
    2347                 :  * referenced and returned.
    2348                 :  *
    2349                 :  * Starting with GDAL 1.6.0, if GDALOpenShared() is called on the same pszFilename
    2350                 :  * from two different threads, a different GDALDataset object will be returned as
    2351                 :  * it is not safe to use the same dataset from different threads, unless the user
    2352                 :  * does explicitely use mutexes in its code.
    2353                 :  *
    2354                 :  * For drivers supporting the VSI virtual file API, it is possible to open
    2355                 :  * a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
    2356                 :  * (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
    2357                 :  *
    2358                 :  * In some situations (dealing with unverified data), the datasets can be opened in another
    2359                 :  * process through the \ref gdal_api_proxy mechanism.
    2360                 :  *
    2361                 :  * \sa GDALOpen()
    2362                 :  *
    2363                 :  * @param pszFilename the name of the file to access.  In the case of
    2364                 :  * exotic drivers this may not refer to a physical file, but instead contain
    2365                 :  * information for the driver on how to access a dataset.  It should be in 
    2366                 :  * UTF-8 encoding.
    2367                 :  *
    2368                 :  * @param eAccess the desired access, either GA_Update or GA_ReadOnly.  Many
    2369                 :  * drivers support only read only access.
    2370                 :  *
    2371                 :  * @return A GDALDatasetH handle or NULL on failure.  For C++ applications
    2372                 :  * this handle can be cast to a GDALDataset *. 
    2373                 :  */
    2374                 :  
    2375                 : GDALDatasetH CPL_STDCALL 
    2376            5452 : GDALOpenShared( const char *pszFilename, GDALAccess eAccess )
    2377                 : 
    2378                 : {
    2379            5452 :     VALIDATE_POINTER1( pszFilename, "GDALOpenShared", NULL );
    2380                 : 
    2381                 : /* -------------------------------------------------------------------- */
    2382                 : /*      First scan the existing list to see if it could already         */
    2383                 : /*      contain the requested dataset.                                  */
    2384                 : /* -------------------------------------------------------------------- */
    2385                 :     {
    2386            5452 :         CPLMutexHolderD( &hDLMutex );
    2387                 : 
    2388            5452 :         if (phSharedDatasetSet != NULL)
    2389                 :         {
    2390            5197 :             GIntBig nThisPID = GDALGetResponsiblePIDForCurrentThread();
    2391                 :             SharedDatasetCtxt* psStruct;
    2392                 :             SharedDatasetCtxt sStruct;
    2393                 : 
    2394            5197 :             sStruct.nPID = nThisPID;
    2395            5197 :             sStruct.pszDescription = (char*) pszFilename;
    2396            5197 :             sStruct.eAccess = eAccess;
    2397            5197 :             psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
    2398            5197 :             if (psStruct == NULL && eAccess == GA_ReadOnly)
    2399                 :             {
    2400             143 :                 sStruct.eAccess = GA_Update;
    2401             143 :                 psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
    2402                 :             }
    2403            5197 :             if (psStruct)
    2404                 :             {
    2405            5054 :                 psStruct->poDS->Reference();
    2406            5054 :                 return psStruct->poDS;
    2407                 :             }
    2408               0 :         }
    2409                 :     }
    2410                 : 
    2411                 : /* -------------------------------------------------------------------- */
    2412                 : /*      Try opening the the requested dataset.                          */
    2413                 : /* -------------------------------------------------------------------- */
    2414                 :     GDALDataset *poDataset;
    2415                 : 
    2416             398 :     poDataset = (GDALDataset *) GDALOpen( pszFilename, eAccess );
    2417             398 :     if( poDataset != NULL )
    2418                 :     {
    2419             297 :         if (strcmp(pszFilename, poDataset->GetDescription()) != 0)
    2420                 :         {
    2421                 :             CPLError(CE_Warning, CPLE_NotSupported,
    2422                 :                      "A dataset opened by GDALOpenShared should have the same filename (%s) "
    2423                 :                      "and description (%s)",
    2424               2 :                      pszFilename, poDataset->GetDescription());
    2425                 :         }
    2426                 :         else
    2427                 :         {
    2428             295 :             poDataset->MarkAsShared();
    2429                 :         }
    2430                 :     }
    2431                 :     
    2432             398 :     return (GDALDatasetH) poDataset;
    2433                 : }
    2434                 : 
    2435                 : /************************************************************************/
    2436                 : /*                             GDALClose()                              */
    2437                 : /************************************************************************/
    2438                 : 
    2439                 : /**
    2440                 :  * \brief Close GDAL dataset. 
    2441                 :  *
    2442                 :  * For non-shared datasets (opened with GDALOpen()) the dataset is closed
    2443                 :  * using the C++ "delete" operator, recovering all dataset related resources.  
    2444                 :  * For shared datasets (opened with GDALOpenShared()) the dataset is 
    2445                 :  * dereferenced, and closed only if the referenced count has dropped below 1.
    2446                 :  *
    2447                 :  * @param hDS The dataset to close.  May be cast from a "GDALDataset *". 
    2448                 :  */
    2449                 : 
    2450           18254 : void CPL_STDCALL GDALClose( GDALDatasetH hDS )
    2451                 : 
    2452                 : {
    2453           18254 :     VALIDATE_POINTER0( hDS, "GDALClose" );
    2454                 : 
    2455           18254 :     GDALDataset *poDS = (GDALDataset *) hDS;
    2456           18254 :     CPLMutexHolderD( &hDLMutex );
    2457           18254 :     CPLLocaleC  oLocaleForcer;
    2458                 : 
    2459           18254 :     if (poDS->GetShared())
    2460                 :     {
    2461                 : /* -------------------------------------------------------------------- */
    2462                 : /*      If this file is in the shared dataset list then dereference     */
    2463                 : /*      it, and only delete/remote it if the reference count has        */
    2464                 : /*      dropped to zero.                                                */
    2465                 : /* -------------------------------------------------------------------- */
    2466            3977 :         if( poDS->Dereference() > 0 )
    2467                 :             return;
    2468                 : 
    2469             593 :         delete poDS;
    2470                 :         return;
    2471                 :     }
    2472                 : 
    2473                 : /* -------------------------------------------------------------------- */
    2474                 : /*      This is not shared dataset, so directly delete it.              */
    2475                 : /* -------------------------------------------------------------------- */
    2476           14277 :     delete poDS;
    2477                 : }
    2478                 : 
    2479                 : /************************************************************************/
    2480                 : /*                        GDALDumpOpenDataset()                         */
    2481                 : /************************************************************************/
    2482                 : 
    2483               0 : static int GDALDumpOpenSharedDatasetsForeach(void* elt, void* user_data)
    2484                 : {
    2485               0 :     SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
    2486               0 :     FILE *fp = (FILE*) user_data;
    2487                 :     const char *pszDriverName;
    2488               0 :     GDALDataset *poDS = psStruct->poDS;
    2489                 : 
    2490               0 :     if( poDS->GetDriver() == NULL )
    2491               0 :         pszDriverName = "DriverIsNULL";
    2492                 :     else
    2493               0 :         pszDriverName = poDS->GetDriver()->GetDescription();
    2494                 : 
    2495               0 :     poDS->Reference();
    2496                 :     VSIFPrintf( fp, "  %d %c %-6s %7d %dx%dx%d %s\n", 
    2497                 :                 poDS->Dereference(), 
    2498                 :                 poDS->GetShared() ? 'S' : 'N',
    2499                 :                 pszDriverName, 
    2500                 :                 (int)psStruct->nPID,
    2501                 :                 poDS->GetRasterXSize(),
    2502                 :                 poDS->GetRasterYSize(),
    2503                 :                 poDS->GetRasterCount(),
    2504               0 :                 poDS->GetDescription() );
    2505                 : 
    2506               0 :     return TRUE;
    2507                 : }
    2508                 : 
    2509                 : 
    2510               0 : static int GDALDumpOpenDatasetsForeach(void* elt, void* user_data)
    2511                 : {
    2512               0 :     DatasetCtxt* psStruct = (DatasetCtxt*) elt;
    2513               0 :     FILE *fp = (FILE*) user_data;
    2514                 :     const char *pszDriverName;
    2515               0 :     GDALDataset *poDS = psStruct->poDS;
    2516                 : 
    2517                 :     /* Don't list shared datasets. They have already been listed by */
    2518                 :     /* GDALDumpOpenSharedDatasetsForeach */
    2519               0 :     if (poDS->GetShared())
    2520               0 :         return TRUE;
    2521                 : 
    2522               0 :     if( poDS->GetDriver() == NULL )
    2523               0 :         pszDriverName = "DriverIsNULL";
    2524                 :     else
    2525               0 :         pszDriverName = poDS->GetDriver()->GetDescription();
    2526                 : 
    2527               0 :     poDS->Reference();
    2528                 :     VSIFPrintf( fp, "  %d %c %-6s %7d %dx%dx%d %s\n", 
    2529                 :                 poDS->Dereference(), 
    2530                 :                 poDS->GetShared() ? 'S' : 'N',
    2531                 :                 pszDriverName, 
    2532                 :                 -1,
    2533                 :                 poDS->GetRasterXSize(),
    2534                 :                 poDS->GetRasterYSize(),
    2535                 :                 poDS->GetRasterCount(),
    2536               0 :                 poDS->GetDescription() );
    2537                 : 
    2538               0 :     return TRUE;
    2539                 : }
    2540                 : 
    2541                 : /**
    2542                 :  * \brief List open datasets.
    2543                 :  *
    2544                 :  * Dumps a list of all open datasets (shared or not) to the indicated 
    2545                 :  * text file (may be stdout or stderr).   This function is primarily intended
    2546                 :  * to assist in debugging "dataset leaks" and reference counting issues. 
    2547                 :  * The information reported includes the dataset name, referenced count, 
    2548                 :  * shared status, driver name, size, and band count. 
    2549                 :  */
    2550                 : 
    2551             461 : int CPL_STDCALL GDALDumpOpenDatasets( FILE *fp )
    2552                 :    
    2553                 : {
    2554             461 :     VALIDATE_POINTER1( fp, "GDALDumpOpenDatasets", 0 );
    2555                 : 
    2556             461 :     CPLMutexHolderD( &hDLMutex );
    2557                 : 
    2558             461 :     if (phAllDatasetSet != NULL)
    2559                 :     {
    2560               0 :         VSIFPrintf( fp, "Open GDAL Datasets:\n" );
    2561               0 :         CPLHashSetForeach(phAllDatasetSet, GDALDumpOpenDatasetsForeach, fp);
    2562               0 :         if (phSharedDatasetSet != NULL)
    2563                 :         {
    2564               0 :             CPLHashSetForeach(phSharedDatasetSet, GDALDumpOpenSharedDatasetsForeach, fp);
    2565                 :         }
    2566               0 :         return CPLHashSetSize(phAllDatasetSet);
    2567                 :     }
    2568                 :     else
    2569                 :     {
    2570             461 :         return 0;
    2571               0 :     }
    2572                 : }
    2573                 : 
    2574                 : /************************************************************************/
    2575                 : /*                        BeginAsyncReader()                          */
    2576                 : /************************************************************************/
    2577                 : 
    2578                 : /**
    2579                 :  * \brief Sets up an asynchronous data request
    2580                 :  *
    2581                 :  * This method establish an asynchronous raster read request for the
    2582                 :  * indicated window on the dataset into the indicated buffer.  The parameters
    2583                 :  * for windowing, buffer size, buffer type and buffer organization are similar
    2584                 :  * to those for GDALDataset::RasterIO(); however, this call only launches
    2585                 :  * the request and filling the buffer is accomplished via calls to 
    2586                 :  * GetNextUpdatedRegion() on the return GDALAsyncReader session object.
    2587                 :  * 
    2588                 :  * Once all processing for the created session is complete, or if no further
    2589                 :  * refinement of the request is required, the GDALAsyncReader object should
    2590                 :  * be destroyed with the GDALDataset::EndAsyncReader() method. 
    2591                 :  * 
    2592                 :  * Note that the data buffer (pData) will potentially continue to be 
    2593                 :  * updated as long as the session lives, but it is not deallocated when
    2594                 :  * the session (GDALAsyncReader) is destroyed with EndAsyncReader().  It
    2595                 :  * should be deallocated by the application at that point. 
    2596                 :  *
    2597                 :  * Additional information on asynchronous IO in GDAL may be found at: 
    2598                 :  *   http://trac.osgeo.org/gdal/wiki/rfc24_progressive_data_support
    2599                 :  * 
    2600                 :  * This method is the same as the C GDALBeginAsyncReader() function.
    2601                 :  *
    2602                 :  * @param nXOff The pixel offset to the top left corner of the region
    2603                 :  * of the band to be accessed.  This would be zero to start from the left side.
    2604                 :  *
    2605                 :  * @param nYOff The line offset to the top left corner of the region
    2606                 :  * of the band to be accessed.  This would be zero to start from the top.
    2607                 :  *
    2608                 :  * @param nXSize The width of the region of the band to be accessed in pixels.
    2609                 :  *
    2610                 :  * @param nYSize The height of the region of the band to be accessed in lines.
    2611                 :  *
    2612                 :  * @param pBuf The buffer into which the data should be read. This buffer must 
    2613                 :  * contain at least nBufXSize * nBufYSize * nBandCount words of type eBufType.  
    2614                 :  * It is organized in left to right,top to bottom pixel order.  Spacing is 
    2615                 :  * controlled by the nPixelSpace, and nLineSpace parameters.
    2616                 :  *
    2617                 :  * @param nBufXSize the width of the buffer image into which the desired region
    2618                 :  * is to be read, or from which it is to be written.
    2619                 :  *
    2620                 :  * @param nBufYSize the height of the buffer image into which the desired
    2621                 :  * region is to be read, or from which it is to be written.
    2622                 :  *
    2623                 :  * @param eBufType the type of the pixel values in the pData data buffer.  The
    2624                 :  * pixel values will automatically be translated to/from the GDALRasterBand
    2625                 :  * data type as needed.
    2626                 :  *
    2627                 :  * @param nBandCount the number of bands being read or written. 
    2628                 :  *
    2629                 :  * @param panBandMap the list of nBandCount band numbers being read/written.
    2630                 :  * Note band numbers are 1 based.   This may be NULL to select the first 
    2631                 :  * nBandCount bands.
    2632                 :  *
    2633                 :  * @param nPixelSpace The byte offset from the start of one pixel value in
    2634                 :  * pData to the start of the next pixel value within a scanline.  If defaulted
    2635                 :  * (0) the size of the datatype eBufType is used.
    2636                 :  *
    2637                 :  * @param nLineSpace The byte offset from the start of one scanline in
    2638                 :  * pData to the start of the next.  If defaulted the size of the datatype
    2639                 :  * eBufType * nBufXSize is used.
    2640                 :  *
    2641                 :  * @param nBandSpace the byte offset from the start of one bands data to the
    2642                 :  * start of the next.  If defaulted (zero) the value will be 
    2643                 :  * nLineSpace * nBufYSize implying band sequential organization
    2644                 :  * of the data buffer. 
    2645                 :  *
    2646                 :  * @param papszOptions Driver specific control options in a string list or NULL.
    2647                 :  * Consult driver documentation for options supported.
    2648                 :  * 
    2649                 :  * @return The GDALAsyncReader object representing the request.
    2650                 :  */
    2651                 : 
    2652                 : GDALAsyncReader* 
    2653               1 : GDALDataset::BeginAsyncReader(int nXOff, int nYOff,
    2654                 :                               int nXSize, int nYSize,
    2655                 :                               void *pBuf,
    2656                 :                               int nBufXSize, int nBufYSize,
    2657                 :                               GDALDataType eBufType,
    2658                 :                               int nBandCount, int* panBandMap,
    2659                 :                               int nPixelSpace, int nLineSpace,
    2660                 :                               int nBandSpace, char **papszOptions)
    2661                 : {
    2662                 :     // See gdaldefaultasync.cpp
    2663                 : 
    2664                 :     return
    2665                 :         GDALGetDefaultAsyncReader( this, 
    2666                 :                                      nXOff, nYOff, nXSize, nYSize,
    2667                 :                                      pBuf, nBufXSize, nBufYSize, eBufType,
    2668                 :                                      nBandCount, panBandMap,
    2669                 :                                      nPixelSpace, nLineSpace, nBandSpace,
    2670               1 :                                      papszOptions );
    2671                 : }
    2672                 : 
    2673                 : /************************************************************************/
    2674                 : /*                        GDALBeginAsyncReader()                      */
    2675                 : /************************************************************************/
    2676                 : 
    2677                 : GDALAsyncReaderH CPL_STDCALL 
    2678               1 : GDALBeginAsyncReader(GDALDatasetH hDS, int xOff, int yOff,
    2679                 :                        int xSize, int ySize,
    2680                 :                        void *pBuf,
    2681                 :                        int bufXSize, int bufYSize,
    2682                 :                        GDALDataType bufType,
    2683                 :                        int nBandCount, int* bandMap,
    2684                 :                        int nPixelSpace, int nLineSpace,
    2685                 :                        int nBandSpace,
    2686                 :                        char **papszOptions)
    2687                 : 
    2688                 : {
    2689               1 :     VALIDATE_POINTER1( hDS, "GDALDataset", NULL );
    2690                 :     return (GDALAsyncReaderH)((GDALDataset *) hDS)->
    2691                 :         BeginAsyncReader(xOff, yOff,
    2692                 :                            xSize, ySize,
    2693                 :                            pBuf, bufXSize, bufYSize,
    2694                 :                            bufType, nBandCount, bandMap,
    2695                 :                            nPixelSpace, nLineSpace,
    2696               1 :                            nBandSpace, papszOptions);
    2697                 : }
    2698                 : 
    2699                 : /************************************************************************/
    2700                 : /*                        EndAsyncReader()                            */
    2701                 : /************************************************************************/
    2702                 : 
    2703                 : /**
    2704                 :  * End asynchronous request.
    2705                 :  *
    2706                 :  * This method destroys an asynchronous io request and recovers all 
    2707                 :  * resources associated with it.
    2708                 :  * 
    2709                 :  * This method is the same as the C function GDALEndAsyncReader(). 
    2710                 :  *
    2711                 :  * @param poARIO pointer to a GDALAsyncReader
    2712                 :  */
    2713                 : 
    2714               1 : void GDALDataset::EndAsyncReader(GDALAsyncReader *poARIO )
    2715                 : {
    2716               1 :     delete poARIO;
    2717               1 : }
    2718                 : 
    2719                 : /************************************************************************/
    2720                 : /*                        GDALEndAsyncReader()                        */
    2721                 : /************************************************************************/
    2722               1 : void CPL_STDCALL GDALEndAsyncReader(GDALDatasetH hDS, GDALAsyncReaderH hAsyncReaderH)
    2723                 : {
    2724               1 :     VALIDATE_POINTER0( hDS, "GDALDataset" );
    2725               1 :     VALIDATE_POINTER0( hAsyncReaderH, "GDALAsyncReader" );
    2726               1 :     ((GDALDataset *) hDS) -> EndAsyncReader((GDALAsyncReader *)hAsyncReaderH); 
    2727                 : }
    2728                 : 
    2729                 : /************************************************************************/
    2730                 : /*                       CloseDependentDatasets()                       */
    2731                 : /************************************************************************/
    2732                 : 
    2733                 : /**
    2734                 :  * Drop references to any other datasets referenced by this dataset.
    2735                 :  *
    2736                 :  * This method should release any reference to other datasets (e.g. a VRT
    2737                 :  * dataset to its sources), but not close the current dataset itself.
    2738                 :  *
    2739                 :  * If at least, one reference to a dependent dataset has been dropped,
    2740                 :  * this method should return TRUE. Otherwise it *should* return FALSE.
    2741                 :  * (Failure to return the proper value might result in infinite loop)
    2742                 :  *
    2743                 :  * This method can be called several times on a given dataset. After
    2744                 :  * the first time, it should not do anything and return FALSE.
    2745                 :  *
    2746                 :  * The driver implementation may choose to destroy its raster bands,
    2747                 :  * so be careful not to call any method on the raster bands afterwards.
    2748                 :  *
    2749                 :  * Basically the only safe action you can do after calling CloseDependantDatasets()
    2750                 :  * is to call the destructor.
    2751                 :  *
    2752                 :  * Note: the only legitimate caller of CloseDependantDatasets() is
    2753                 :  * GDALDriverManager::~GDALDriverManager()
    2754                 :  *
    2755                 :  * @return TRUE if at least one reference to another dataset has been dropped.
    2756                 :  */
    2757            1184 : int GDALDataset::CloseDependentDatasets()
    2758                 : {
    2759            1184 :     return oOvManager.CloseDependentDatasets();
    2760                 : }
    2761                 : 
    2762                 : /************************************************************************/
    2763                 : /*                            ReportError()                             */
    2764                 : /************************************************************************/
    2765                 : 
    2766                 : /**
    2767                 :  * \brief Emits an error related to a dataset.
    2768                 :  *
    2769                 :  * This function is a wrapper for regular CPLError(). The only difference
    2770                 :  * with CPLError() is that it prepends the error message with the dataset
    2771                 :  * name.
    2772                 :  *
    2773                 :  * @param eErrClass one of CE_Warning, CE_Failure or CE_Fatal.
    2774                 :  * @param err_no the error number (CPLE_*) from cpl_error.h.
    2775                 :  * @param fmt a printf() style format string.  Any additional arguments
    2776                 :  * will be treated as arguments to fill in this format in a manner
    2777                 :  * similar to printf().
    2778                 :  *
    2779                 :  * @since GDAL 1.9.0
    2780                 :  */
    2781                 : 
    2782               4 : void GDALDataset::ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)
    2783                 : {
    2784                 :     va_list args;
    2785                 : 
    2786               4 :     va_start(args, fmt);
    2787                 : 
    2788                 :     char szNewFmt[256];
    2789               4 :     const char* pszDSName = GetDescription();
    2790               4 :     if (strlen(fmt) + strlen(pszDSName) + 3 >= sizeof(szNewFmt) - 1)
    2791               0 :         pszDSName = CPLGetFilename(pszDSName);
    2792               7 :     if (pszDSName[0] != '\0' &&
    2793                 :         strlen(fmt) + strlen(pszDSName) + 3 < sizeof(szNewFmt) - 1)
    2794                 :     {
    2795                 :         snprintf(szNewFmt, sizeof(szNewFmt), "%s: %s",
    2796               3 :                  pszDSName, fmt);
    2797               3 :         CPLErrorV( eErrClass, err_no, szNewFmt, args );
    2798                 :     }
    2799                 :     else
    2800                 :     {
    2801               1 :         CPLErrorV( eErrClass, err_no, fmt, args );
    2802                 :     }
    2803               4 :     va_end(args);
    2804               4 : }

Generated by: LCOV version 1.7