LCOV - code coverage report
Current view: directory - gcore - gdaldataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 518 395 76.3 %
Date: 2010-01-09 Functions: 75 60 80.0 %

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

Generated by: LCOV version 1.7