LTP GCOV extension - code coverage report
Current view: directory - gcore - gdaldefaultoverviews.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 343
Code covered: 82.2 % Executed lines: 282

       1                 : /******************************************************************************
       2                 :  * $Id: gdaldefaultoverviews.cpp 19429 2010-04-17 00:41:48Z warmerdam $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Helper code to implement overview and mask support for many 
       6                 :  *           drivers with no inherent format support.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2000, 2007, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "gdal_priv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: gdaldefaultoverviews.cpp 19429 2010-04-17 00:41:48Z warmerdam $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                        GDALDefaultOverviews()                        */
      38                 : /************************************************************************/
      39                 : 
      40           13509 : GDALDefaultOverviews::GDALDefaultOverviews()
      41                 : 
      42                 : {
      43           13509 :     poDS = NULL;
      44           13509 :     poODS = NULL;
      45           13509 :     bOvrIsAux = FALSE;
      46                 : 
      47           13509 :     bCheckedForMask = FALSE;
      48           13509 :     bCheckedForOverviews = FALSE;
      49                 : 
      50           13509 :     poMaskDS = NULL;
      51                 : 
      52           13509 :     bOwnMaskDS = FALSE;
      53           13509 :     poBaseDS = NULL;
      54                 : 
      55           13509 :     papszInitSiblingFiles = NULL;
      56           13509 :     pszInitName = NULL;
      57           13509 : }
      58                 : 
      59                 : /************************************************************************/
      60                 : /*                       ~GDALDefaultOverviews()                        */
      61                 : /************************************************************************/
      62                 : 
      63           13509 : GDALDefaultOverviews::~GDALDefaultOverviews()
      64                 : 
      65                 : {
      66           13509 :     CPLFree( pszInitName );
      67           13509 :     CSLDestroy( papszInitSiblingFiles );
      68                 : 
      69           13509 :     if( poODS != NULL )
      70                 :     {
      71             171 :         poODS->FlushCache();
      72             171 :         GDALClose( poODS );
      73             171 :         poODS = NULL;
      74                 :     }
      75                 : 
      76           13509 :     if( poMaskDS != NULL )
      77                 :     {
      78              13 :         if( bOwnMaskDS )
      79                 :         {
      80              10 :             poMaskDS->FlushCache();
      81              10 :             GDALClose( poMaskDS );
      82                 :         }
      83              13 :         poMaskDS = NULL;
      84                 :     }
      85           13509 : }
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                           IsInitialized()                            */
      89                 : /*                                                                      */
      90                 : /*      Returns TRUE if we are initialized.                             */
      91                 : /************************************************************************/
      92                 : 
      93          303197 : int GDALDefaultOverviews::IsInitialized()
      94                 : 
      95                 : {
      96          303197 :     OverviewScan();
      97          303197 :     return poDS != NULL;
      98                 : }
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                             Initialize()                             */
     102                 : /************************************************************************/
     103                 : 
     104                 : void GDALDefaultOverviews::Initialize( GDALDataset *poDSIn,
     105                 :                                        const char * pszBasename,
     106                 :                                        char **papszSiblingFiles,
     107            6713 :                                        int bNameIsOVR )
     108                 : 
     109                 : {
     110            6713 :     poDS = poDSIn;
     111                 :     
     112                 : /* -------------------------------------------------------------------- */
     113                 : /*      If we were already initialized, destroy the old overview        */
     114                 : /*      file handle.                                                    */
     115                 : /* -------------------------------------------------------------------- */
     116            6713 :     if( poODS != NULL )
     117                 :     {
     118               0 :         GDALClose( poODS );
     119               0 :         poODS = NULL;
     120                 : 
     121               0 :         CPLDebug( "GDAL", "GDALDefaultOverviews::Initialize() called twice - this is odd and perhaps dangerous!" );
     122                 :     }
     123                 : 
     124                 : /* -------------------------------------------------------------------- */
     125                 : /*      Store the initialization information for later use in           */
     126                 : /*      OverviewScan()                                                  */
     127                 : /* -------------------------------------------------------------------- */
     128            6713 :     bCheckedForOverviews = FALSE;
     129                 : 
     130            6713 :     CPLFree( pszInitName );
     131            6713 :     pszInitName = NULL;
     132            6713 :     if( pszBasename != NULL )
     133            6713 :         pszInitName = CPLStrdup(pszBasename);
     134            6713 :     bInitNameIsOVR = bNameIsOVR;
     135                 : 
     136            6713 :     CSLDestroy( papszInitSiblingFiles );
     137            6713 :     papszInitSiblingFiles = NULL;
     138            6713 :     if( papszSiblingFiles != NULL )
     139              47 :         papszInitSiblingFiles = CSLDuplicate(papszSiblingFiles);
     140            6713 : }
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                            OverviewScan()                            */
     144                 : /*                                                                      */
     145                 : /*      This is called to scan for overview files when a first          */
     146                 : /*      request is made with regard to overviews.  It uses the          */
     147                 : /*      pszInitName, bInitNameIsOVR and papszInitSiblingFiles           */
     148                 : /*      information that was stored at Initialization() time.           */
     149                 : /************************************************************************/
     150                 : 
     151          303197 : void GDALDefaultOverviews::OverviewScan()
     152                 : 
     153                 : {
     154          303197 :     if( bCheckedForOverviews || poDS == NULL )
     155          301332 :         return;
     156                 : 
     157            1865 :     bCheckedForOverviews = true;
     158                 : 
     159            1865 :     CPLDebug( "GDAL", "GDALDefaultOverviews::OverviewScan()" );
     160                 : 
     161                 : /* -------------------------------------------------------------------- */
     162                 : /*      Open overview dataset if it exists.                             */
     163                 : /* -------------------------------------------------------------------- */
     164                 :     int bExists;
     165                 : 
     166            1865 :     if( pszInitName == NULL )
     167               0 :         pszInitName = CPLStrdup(poDS->GetDescription());
     168                 : 
     169            1865 :     if( !EQUAL(pszInitName,":::VIRTUAL:::") )
     170                 :     {
     171            1752 :         if( bInitNameIsOVR )
     172               0 :             osOvrFilename = pszInitName;
     173                 :         else
     174            1752 :             osOvrFilename.Printf( "%s.ovr", pszInitName );
     175                 : 
     176                 :         bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), 
     177            1752 :                                    papszInitSiblingFiles );
     178                 : 
     179                 : #if !defined(WIN32)
     180            1752 :         if( !bInitNameIsOVR && !bExists && !papszInitSiblingFiles )
     181                 :         {
     182            1642 :             osOvrFilename.Printf( "%s.OVR", pszInitName );
     183                 :             bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), 
     184            1642 :                                        papszInitSiblingFiles );
     185            1642 :             if( !bExists )
     186            1642 :                 osOvrFilename.Printf( "%s.ovr", pszInitName );
     187                 :         }
     188                 : #endif
     189                 : 
     190            1752 :         if( bExists )
     191                 :         {
     192              96 :             poODS = (GDALDataset*) GDALOpen( osOvrFilename, poDS->GetAccess() );
     193                 :         }
     194                 :     }
     195                 : 
     196                 : /* -------------------------------------------------------------------- */
     197                 : /*      We didn't find that, so try and find a corresponding aux        */
     198                 : /*      file.  Check that we are the dependent file of the aux          */
     199                 : /*      file.                                                           */
     200                 : /*                                                                      */
     201                 : /*      We only use the .aux file for overviews if they already have    */
     202                 : /*      overviews existing, or if USE_RRD is set true.                  */
     203                 : /* -------------------------------------------------------------------- */
     204            1865 :     if( !poODS && !EQUAL(pszInitName,":::VIRTUAL:::") )
     205                 :     {
     206                 :         poODS = GDALFindAssociatedAuxFile( pszInitName, poDS->GetAccess(),
     207            1656 :                                            poDS );
     208                 : 
     209            1656 :         if( poODS )
     210                 :         {
     211               2 :             int bUseRRD = CSLTestBoolean(CPLGetConfigOption("USE_RRD","NO"));
     212                 :             
     213               2 :             bOvrIsAux = TRUE;
     214               2 :             if( GetOverviewCount(1) == 0 && !bUseRRD )
     215                 :             {
     216               0 :                 bOvrIsAux = FALSE;
     217               0 :                 GDALClose( poODS );
     218               0 :                 poODS = NULL;
     219                 :             }
     220                 :             else
     221                 :             {
     222               2 :                 osOvrFilename = poODS->GetDescription();
     223                 :             }
     224                 :         }
     225                 :     }
     226                 : 
     227                 : /* -------------------------------------------------------------------- */
     228                 : /*      If we still don't have an overview, check to see if we have     */
     229                 : /*      overview metadata referencing a remote (ie. proxy) or local     */
     230                 : /*      subdataset overview dataset.                                    */
     231                 : /* -------------------------------------------------------------------- */
     232            1865 :     if( poODS == NULL )
     233                 :     {
     234                 :         const char *pszProxyOvrFilename = 
     235            1767 :             poDS->GetMetadataItem( "OVERVIEW_FILE", "OVERVIEWS" );
     236                 : 
     237            1767 :         if( pszProxyOvrFilename != NULL )
     238                 :         {
     239               6 :             if( EQUALN(pszProxyOvrFilename,":::BASE:::",10) )
     240                 :             {
     241               0 :                 CPLString osPath = CPLGetPath(poDS->GetDescription());
     242                 : 
     243                 :                 osOvrFilename =
     244               0 :                     CPLFormFilename( osPath, pszProxyOvrFilename+10, NULL );
     245                 :             }
     246                 :             else
     247               6 :                 osOvrFilename = pszProxyOvrFilename;
     248                 : 
     249               6 :             poODS = (GDALDataset *) GDALOpen(osOvrFilename,poDS->GetAccess());
     250                 :         }
     251                 :     }
     252                 : 
     253                 : /* -------------------------------------------------------------------- */
     254                 : /*      If we have an overview dataset, then mark all the overviews     */
     255                 : /*      with the base dataset  Used later for finding overviews         */
     256                 : /*      masks.  Uggg.                                                   */
     257                 : /* -------------------------------------------------------------------- */
     258            1865 :     if( poODS )
     259                 :     {
     260             104 :         int nOverviewCount = GetOverviewCount(1);
     261                 :         int iOver;
     262                 : 
     263             229 :         for( iOver = 0; iOver < nOverviewCount; iOver++ )
     264                 :         {
     265             125 :             GDALRasterBand *poBand = GetOverview( 1, iOver );
     266             125 :             GDALDataset    *poOverDS = NULL;
     267                 : 
     268             125 :             if( poBand != NULL )
     269             125 :                 poOverDS = poBand->GetDataset();
     270                 :             
     271             125 :             if( poOverDS != NULL )
     272                 :             {
     273             123 :                 poOverDS->oOvManager.poBaseDS = poDS;
     274             123 :                 poOverDS->oOvManager.poDS = poOverDS;
     275                 :             }
     276                 :         }
     277                 :     }
     278                 : }
     279                 : 
     280                 : /************************************************************************/
     281                 : /*                          GetOverviewCount()                          */
     282                 : /************************************************************************/
     283                 : 
     284          299852 : int GDALDefaultOverviews::GetOverviewCount( int nBand )
     285                 : 
     286                 : {
     287                 :     GDALRasterBand * poBand;
     288                 : 
     289          299852 :     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
     290          299311 :         return 0;
     291                 : 
     292             541 :     poBand = poODS->GetRasterBand( nBand );
     293             541 :     if( poBand == NULL )
     294               0 :         return 0;
     295                 :     else
     296                 :     {
     297             541 :         if( bOvrIsAux )
     298               8 :             return poBand->GetOverviewCount();
     299                 :         else
     300             533 :             return poBand->GetOverviewCount() + 1;
     301                 :     }
     302                 : }
     303                 : 
     304                 : /************************************************************************/
     305                 : /*                            GetOverview()                             */
     306                 : /************************************************************************/
     307                 : 
     308                 : GDALRasterBand *
     309             505 : GDALDefaultOverviews::GetOverview( int nBand, int iOverview )
     310                 : 
     311                 : {
     312                 :     GDALRasterBand * poBand;
     313                 : 
     314             505 :     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
     315               0 :         return NULL;
     316                 : 
     317             505 :     poBand = poODS->GetRasterBand( nBand );
     318             505 :     if( poBand == NULL )
     319               0 :         return NULL;
     320                 : 
     321             505 :     if( bOvrIsAux )
     322               8 :         return poBand->GetOverview( iOverview );
     323                 : 
     324                 :     else // TIFF case, base is overview 0.
     325                 :     {
     326             497 :         if( iOverview == 0 )
     327             365 :             return poBand;
     328             132 :         else if( iOverview-1 >= poBand->GetOverviewCount() )
     329               0 :             return NULL;
     330                 :         else
     331             132 :             return poBand->GetOverview( iOverview-1 );
     332                 :     }
     333                 : }
     334                 : 
     335                 : /************************************************************************/
     336                 : /*                         GDALOvLevelAdjust()                          */
     337                 : /*                                                                      */
     338                 : /*      Some overview levels cannot be achieved closely enough to be    */
     339                 : /*      recognised as the desired overview level.  This function        */
     340                 : /*      will adjust an overview level to one that is achievable on      */
     341                 : /*      the given raster size.                                          */
     342                 : /*                                                                      */
     343                 : /*      For instance a 1200x1200 image on which a 256 level overview    */
     344                 : /*      is request will end up generating a 5x5 overview.  However,     */
     345                 : /*      this will appear to the system be a level 240 overview.         */
     346                 : /*      This function will adjust 256 to 240 based on knowledge of      */
     347                 : /*      the image size.                                                 */
     348                 : /************************************************************************/
     349                 : 
     350             214 : int GDALOvLevelAdjust( int nOvLevel, int nXSize )
     351                 : 
     352                 : {
     353             214 :     int nOXSize = (nXSize + nOvLevel - 1) / nOvLevel;
     354                 :     
     355             214 :     return (int) (0.5 + nXSize / (double) nOXSize);
     356                 : }
     357                 : 
     358                 : /************************************************************************/
     359                 : /*                           CleanOverviews()                           */
     360                 : /*                                                                      */
     361                 : /*      Remove all existing overviews.                                  */
     362                 : /************************************************************************/
     363                 : 
     364               5 : CPLErr GDALDefaultOverviews::CleanOverviews()
     365                 : 
     366                 : {
     367                 :     // Anything to do?
     368               5 :     if( poODS == NULL )
     369               2 :         return CE_None;
     370                 : 
     371                 :     // Delete the overview file(s). 
     372                 :     GDALDriver *poOvrDriver;
     373                 : 
     374               3 :     poOvrDriver = poODS->GetDriver();
     375               3 :     GDALClose( poODS );
     376               3 :     poODS = NULL;
     377                 : 
     378                 :     CPLErr eErr;
     379               3 :     if( poOvrDriver != NULL )
     380               3 :         eErr = poOvrDriver->Delete( osOvrFilename );
     381                 :     else
     382               0 :         eErr = CE_None;
     383                 : 
     384                 :     // Reset the saved overview filename. 
     385               3 :     if( !EQUAL(poDS->GetDescription(),":::VIRTUAL:::") )
     386                 :     {
     387               3 :         int bUseRRD = CSLTestBoolean(CPLGetConfigOption("USE_RRD","NO"));
     388                 : 
     389               3 :         if( bUseRRD )
     390               0 :             osOvrFilename = CPLResetExtension( poDS->GetDescription(), "aux" );
     391                 :         else
     392               3 :             osOvrFilename.Printf( "%s.ovr", poDS->GetDescription() );
     393                 :     }
     394                 :     else
     395               0 :         osOvrFilename = "";
     396                 : 
     397               3 :     return eErr;
     398                 : }
     399                 :     
     400                 : /************************************************************************/
     401                 : /*                      BuildOverviewsSubDataset()                      */
     402                 : /************************************************************************/
     403                 : 
     404                 : CPLErr
     405                 : GDALDefaultOverviews::BuildOverviewsSubDataset( 
     406                 :     const char * pszPhysicalFile,
     407                 :     const char * pszResampling, 
     408                 :     int nOverviews, int * panOverviewList,
     409                 :     int nBands, int * panBandList,
     410               4 :     GDALProgressFunc pfnProgress, void * pProgressData)
     411                 : 
     412                 : {
     413               4 :     if( osOvrFilename.length() == 0 && nOverviews > 0 )
     414                 :     {
     415               4 :         int iSequence = 0;
     416                 :         VSIStatBufL sStatBuf;
     417                 : 
     418               4 :         for( iSequence = 0; iSequence < 100; iSequence++ )
     419                 :         {
     420               4 :             osOvrFilename.Printf( "%s_%d.ovr", pszPhysicalFile, iSequence );
     421               4 :             if( VSIStatL( osOvrFilename, &sStatBuf ) != 0 )
     422                 :             {
     423               4 :                 CPLString osAdjustedOvrFilename;
     424                 : 
     425               4 :                 if( poDS->GetMOFlags() & GMO_PAM_CLASS )
     426                 :                 {
     427                 :                     osAdjustedOvrFilename.Printf( ":::BASE:::%s_%d.ovr",
     428                 :                                                   CPLGetFilename(pszPhysicalFile),
     429               4 :                                                   iSequence );
     430                 :                 }
     431                 :                 else
     432               0 :                     osAdjustedOvrFilename = osOvrFilename;
     433                 : 
     434                 :                 poDS->SetMetadataItem( "OVERVIEW_FILE", 
     435                 :                                        osAdjustedOvrFilename, 
     436               4 :                                        "OVERVIEWS" );
     437               4 :                 break;
     438                 :             }
     439                 :         }
     440                 : 
     441               4 :         if( iSequence == 100 )
     442               0 :             osOvrFilename = "";
     443                 :     }
     444                 : 
     445                 :     return BuildOverviews( NULL, pszResampling, nOverviews, panOverviewList,
     446               4 :                            nBands, panBandList, pfnProgress, pProgressData );
     447                 : }
     448                 : 
     449                 : /************************************************************************/
     450                 : /*                           BuildOverviews()                           */
     451                 : /************************************************************************/
     452                 : 
     453                 : CPLErr
     454                 : GDALDefaultOverviews::BuildOverviews( 
     455                 :     const char * pszBasename,
     456                 :     const char * pszResampling, 
     457                 :     int nOverviews, int * panOverviewList,
     458                 :     int nBands, int * panBandList,
     459              76 :     GDALProgressFunc pfnProgress, void * pProgressData)
     460                 : 
     461                 : {
     462                 :     GDALRasterBand **pahBands;
     463                 :     CPLErr       eErr;
     464                 :     int          i;
     465                 : 
     466              76 :     if( pfnProgress == NULL )
     467               0 :         pfnProgress = GDALDummyProgress;
     468                 : 
     469              76 :     if( nOverviews == 0 )
     470               4 :         return CleanOverviews();
     471                 : 
     472                 : /* -------------------------------------------------------------------- */
     473                 : /*      If we don't already have an overview file, we need to decide    */
     474                 : /*      what format to use.                                             */
     475                 : /* -------------------------------------------------------------------- */
     476              72 :     if( poODS == NULL )
     477                 :     {
     478              72 :         bOvrIsAux = CSLTestBoolean(CPLGetConfigOption( "USE_RRD", "NO" ));
     479              72 :         if( bOvrIsAux )
     480                 :         {
     481                 :             VSIStatBufL sStatBuf;
     482                 : 
     483               2 :             osOvrFilename = CPLResetExtension(poDS->GetDescription(),"aux");
     484                 : 
     485               2 :             if( VSIStatL( osOvrFilename, &sStatBuf ) == 0 )
     486               0 :                 osOvrFilename.Printf( "%s.aux", poDS->GetDescription() );
     487                 :         }
     488                 :     }
     489                 : /* -------------------------------------------------------------------- */
     490                 : /*      If we already have the overviews open, but they are             */
     491                 : /*      read-only, then try and reopen them read-write.                 */
     492                 : /* -------------------------------------------------------------------- */
     493               0 :     else if( poODS->GetAccess() == GA_ReadOnly )
     494                 :     {
     495               0 :         GDALClose( poODS );
     496               0 :         poODS = (GDALDataset *) GDALOpen( osOvrFilename, GA_Update );
     497               0 :         if( poODS == NULL )
     498               0 :             return CE_Failure;
     499                 :     }
     500                 : 
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Our TIFF overview support currently only works safely if all    */
     503                 : /*      bands are handled at the same time.                             */
     504                 : /* -------------------------------------------------------------------- */
     505              72 :     if( !bOvrIsAux && nBands != poDS->GetRasterCount() )
     506                 :     {
     507                 :         CPLError( CE_Failure, CPLE_NotSupported,
     508                 :                   "Generation of overviews in external TIFF currently only"
     509                 :                   " supported when operating on all bands.\n" 
     510               0 :                   "Operation failed.\n" );
     511               0 :         return CE_Failure;
     512                 :     }
     513                 : 
     514                 : /* -------------------------------------------------------------------- */
     515                 : /*      If a basename is provided, use it to override the internal      */
     516                 : /*      overview filename.                                              */
     517                 : /* -------------------------------------------------------------------- */
     518              72 :     if( pszBasename == NULL && osOvrFilename.length() == 0  )
     519               0 :         pszBasename = poDS->GetDescription();
     520                 : 
     521              72 :     if( pszBasename != NULL )
     522                 :     {
     523               0 :         if( bOvrIsAux )
     524               0 :             osOvrFilename.Printf( "%s.aux", pszBasename );
     525                 :         else
     526               0 :             osOvrFilename.Printf( "%s.ovr", pszBasename );
     527                 :     }
     528                 : 
     529                 : /* -------------------------------------------------------------------- */
     530                 : /*      Establish which of the overview levels we already have, and     */
     531                 : /*      which are new.  We assume that band 1 of the file is            */
     532                 : /*      representative.                                                 */
     533                 : /* -------------------------------------------------------------------- */
     534              72 :     int   nNewOverviews, *panNewOverviewList = NULL;
     535              72 :     GDALRasterBand *poBand = poDS->GetRasterBand( 1 );
     536                 : 
     537              72 :     nNewOverviews = 0;
     538              72 :     panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews);
     539             161 :     for( i = 0; i < nOverviews && poBand != NULL; i++ )
     540                 :     {
     541                 :         int   j;
     542                 : 
     543              89 :         for( j = 0; j < poBand->GetOverviewCount(); j++ )
     544                 :         {
     545                 :             int    nOvFactor;
     546               0 :             GDALRasterBand * poOverview = poBand->GetOverview( j );
     547               0 :             if (poOverview == NULL)
     548               0 :                 continue;
     549                 :  
     550                 :             nOvFactor = (int) 
     551               0 :                 (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
     552                 : 
     553               0 :             if( nOvFactor == panOverviewList[i] 
     554                 :                 || nOvFactor == GDALOvLevelAdjust( panOverviewList[i], 
     555                 :                                                    poBand->GetXSize() ) )
     556               0 :                 panOverviewList[i] *= -1;
     557                 :         }
     558                 : 
     559              89 :         if( panOverviewList[i] > 0 )
     560              89 :             panNewOverviewList[nNewOverviews++] = panOverviewList[i];
     561                 :     }
     562                 : 
     563                 : /* -------------------------------------------------------------------- */
     564                 : /*      Build band list.                                                */
     565                 : /* -------------------------------------------------------------------- */
     566              72 :     pahBands = (GDALRasterBand **) CPLCalloc(sizeof(GDALRasterBand *),nBands);
     567             175 :     for( i = 0; i < nBands; i++ )
     568             103 :         pahBands[i] = poDS->GetRasterBand( panBandList[i] );
     569                 : 
     570                 : /* -------------------------------------------------------------------- */
     571                 : /*      Build new overviews - Imagine.  Keep existing file open if      */
     572                 : /*      we have it.  But mark all overviews as in need of               */
     573                 : /*      regeneration, since HFAAuxBuildOverviews() doesn't actually     */
     574                 : /*      produce the imagery.                                            */
     575                 : /* -------------------------------------------------------------------- */
     576                 : 
     577                 : #ifndef WIN32CE
     578                 : 
     579              72 :     if( bOvrIsAux )
     580                 :     {
     581                 :         eErr = HFAAuxBuildOverviews( osOvrFilename, poDS, &poODS,
     582                 :                                      nBands, panBandList,
     583                 :                                      nNewOverviews, panNewOverviewList, 
     584                 :                                      pszResampling, 
     585               2 :                                      pfnProgress, pProgressData );
     586                 : 
     587                 :         int j;
     588                 :         
     589               4 :         for( j = 0; j < nOverviews; j++ )
     590                 :         {
     591               2 :             if( panOverviewList[j] > 0 )
     592               2 :                 panOverviewList[j] *= -1;
     593                 :         }
     594                 :     }
     595                 : 
     596                 : /* -------------------------------------------------------------------- */
     597                 : /*      Build new overviews - TIFF.  Close TIFF files while we          */
     598                 : /*      operate on it.                                                  */
     599                 : /* -------------------------------------------------------------------- */
     600                 :     else
     601                 : #endif /* WIN32CE */
     602                 :     {
     603              70 :         if( poODS != NULL )
     604                 :         {
     605               0 :             delete poODS;
     606               0 :             poODS = NULL;
     607                 :         }
     608                 : 
     609                 :         eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, 
     610                 :                                     nNewOverviews, panNewOverviewList, 
     611              70 :                                     pszResampling, pfnProgress, pProgressData );
     612                 :         
     613                 :         // Probe for proxy overview filename. 
     614              70 :         if( eErr == CE_Failure )
     615                 :         {
     616                 :             const char *pszProxyOvrFilename = 
     617               2 :                 poDS->GetMetadataItem("FILENAME","ProxyOverviewRequest");
     618                 : 
     619               2 :             if( pszProxyOvrFilename != NULL )
     620                 :             {
     621               0 :                 osOvrFilename = pszProxyOvrFilename;
     622                 :                 eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, 
     623                 :                                             nNewOverviews, panNewOverviewList, 
     624                 :                                             pszResampling, 
     625               0 :                                             pfnProgress, pProgressData );
     626                 :             }
     627                 :         }
     628                 : 
     629              70 :         if( eErr == CE_None )
     630                 :         {
     631              68 :             poODS = (GDALDataset *) GDALOpen( osOvrFilename, GA_Update );
     632              68 :             if( poODS == NULL )
     633               0 :                 eErr = CE_Failure;
     634                 :         }
     635                 :     }
     636                 : 
     637                 : /* -------------------------------------------------------------------- */
     638                 : /*      Refresh old overviews that were listed.                         */
     639                 : /* -------------------------------------------------------------------- */
     640                 :     GDALRasterBand **papoOverviewBands;
     641                 : 
     642                 :     papoOverviewBands = (GDALRasterBand **) 
     643              72 :         CPLCalloc(sizeof(void*),nOverviews);
     644                 : 
     645             173 :     for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
     646                 :     {
     647             101 :         poBand = poDS->GetRasterBand( panBandList[iBand] );
     648                 : 
     649             101 :         nNewOverviews = 0;
     650             240 :         for( i = 0; i < nOverviews && poBand != NULL; i++ )
     651                 :         {
     652                 :             int   j;
     653                 :             
     654             340 :             for( j = 0; j < poBand->GetOverviewCount(); j++ )
     655                 :             {
     656                 :                 int    nOvFactor;
     657             209 :                 GDALRasterBand * poOverview = poBand->GetOverview( j );
     658             209 :                 if (poOverview == NULL)
     659               0 :                     continue;
     660                 : 
     661                 :                 int bHasNoData;
     662             209 :                 double noDataValue = poBand->GetNoDataValue(&bHasNoData);
     663                 : 
     664             209 :                 if (bHasNoData)
     665               7 :                   poOverview->SetNoDataValue(noDataValue);
     666                 : 
     667                 :                 nOvFactor = (int) 
     668             209 :                     (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
     669                 : 
     670             209 :                 if( nOvFactor == - panOverviewList[i] 
     671                 :                     || nOvFactor == GDALOvLevelAdjust( -panOverviewList[i], 
     672                 :                                                        poBand->GetXSize() ) )
     673                 :                 {
     674               8 :                     papoOverviewBands[nNewOverviews++] = poOverview;
     675               8 :                     break;
     676                 :                 }
     677                 :             }
     678                 :         }
     679                 : 
     680             101 :         if( nNewOverviews > 0 )
     681                 :         {
     682                 :             eErr = GDALRegenerateOverviews( (GDALRasterBandH) poBand, 
     683                 :                                             nNewOverviews, 
     684                 :                                             (GDALRasterBandH*)papoOverviewBands,
     685                 :                                             pszResampling, 
     686               6 :                                             pfnProgress, pProgressData );
     687                 :         }
     688                 :     }
     689                 : 
     690                 : /* -------------------------------------------------------------------- */
     691                 : /*      Cleanup                                                         */
     692                 : /* -------------------------------------------------------------------- */
     693              72 :     CPLFree( papoOverviewBands );
     694              72 :     CPLFree( panNewOverviewList );
     695              72 :     CPLFree( pahBands );
     696                 : 
     697                 : /* -------------------------------------------------------------------- */
     698                 : /*      If we have a mask file, we need to build it's overviews         */
     699                 : /*      too.                                                            */
     700                 : /* -------------------------------------------------------------------- */
     701              72 :     if( HaveMaskFile() && poMaskDS )
     702                 :     {
     703                 :         poMaskDS->BuildOverviews( pszResampling, nOverviews, panOverviewList,
     704               1 :                                   0, NULL, pfnProgress, pProgressData );
     705               1 :         if( bOwnMaskDS )
     706               1 :             GDALClose( poMaskDS );
     707                 : 
     708                 :         // force next request to reread mask file.
     709               1 :         poMaskDS = NULL;
     710               1 :         bOwnMaskDS = FALSE;
     711               1 :         bCheckedForMask = FALSE;
     712                 :     }
     713                 : 
     714                 : /* -------------------------------------------------------------------- */
     715                 : /*      If we have an overview dataset, then mark all the overviews     */
     716                 : /*      with the base dataset  Used later for finding overviews         */
     717                 : /*      masks.  Uggg.                                                   */
     718                 : /* -------------------------------------------------------------------- */
     719              72 :     if( poODS )
     720                 :     {
     721              70 :         int nOverviewCount = GetOverviewCount(1);
     722                 :         int iOver;
     723                 : 
     724             157 :         for( iOver = 0; iOver < nOverviewCount; iOver++ )
     725                 :         {
     726              87 :             GDALRasterBand *poBand = GetOverview( 1, iOver );
     727              87 :             GDALDataset    *poOverDS = NULL;
     728                 : 
     729              87 :             if( poBand != NULL )
     730              87 :                 poOverDS = poBand->GetDataset();
     731                 : 
     732              87 :             if (poOverDS != NULL)
     733                 :             {
     734              85 :                 poOverDS->oOvManager.poBaseDS = poDS;
     735              85 :                 poOverDS->oOvManager.poDS = poOverDS;
     736                 :             }
     737                 :         }
     738                 :     }
     739                 : 
     740              72 :     return eErr;
     741                 : }
     742                 : 
     743                 : /************************************************************************/
     744                 : /*                           CreateMaskBand()                           */
     745                 : /************************************************************************/
     746                 : 
     747               3 : CPLErr GDALDefaultOverviews::CreateMaskBand( int nFlags, int nBand )
     748                 : 
     749                 : {
     750               3 :     if( nBand < 1 )
     751               3 :         nFlags |= GMF_PER_DATASET;
     752                 : 
     753                 : /* -------------------------------------------------------------------- */
     754                 : /*      ensure existing file gets opened if there is one.               */
     755                 : /* -------------------------------------------------------------------- */
     756               3 :     HaveMaskFile();
     757                 : 
     758                 : /* -------------------------------------------------------------------- */
     759                 : /*      Try creating the mask file.                                     */
     760                 : /* -------------------------------------------------------------------- */
     761               3 :     if( poMaskDS == NULL )
     762                 :     {
     763               3 :         CPLString osMskFilename;
     764               3 :         GDALDriver *poDr = (GDALDriver *) GDALGetDriverByName( "GTiff" );
     765               3 :         char **papszOpt = NULL;
     766                 :         int  nBX, nBY;
     767                 :         int  nBands;
     768                 :         
     769               3 :         if( poDr == NULL )
     770               0 :             return CE_Failure;
     771                 : 
     772               3 :         GDALRasterBand *poTBand = poDS->GetRasterBand(1);
     773               3 :         if( poTBand == NULL )
     774               0 :             return CE_Failure;
     775                 : 
     776               3 :         if( nFlags & GMF_PER_DATASET )
     777               3 :             nBands = 1;
     778                 :         else
     779               0 :             nBands = poDS->GetRasterCount();
     780                 : 
     781                 : 
     782               3 :         papszOpt = CSLSetNameValue( papszOpt, "COMPRESS", "DEFLATE" );
     783               3 :         papszOpt = CSLSetNameValue( papszOpt, "INTERLEAVE", "BAND" );
     784                 : 
     785               3 :         poTBand->GetBlockSize( &nBX, &nBY );
     786                 : 
     787                 :         // try to create matching tile size if legal in TIFF.
     788               3 :         if( (nBX % 16) == 0 && (nBY % 16) == 0 )
     789                 :         {
     790               0 :             papszOpt = CSLSetNameValue( papszOpt, "TILED", "YES" );
     791                 :             papszOpt = CSLSetNameValue( papszOpt, "BLOCKXSIZE",
     792               0 :                                         CPLString().Printf("%d",nBX) );
     793                 :             papszOpt = CSLSetNameValue( papszOpt, "BLOCKYSIZE",
     794               0 :                                         CPLString().Printf("%d",nBY) );
     795                 :         }
     796                 : 
     797               3 :         osMskFilename.Printf( "%s.msk", poDS->GetDescription() );
     798                 :         poMaskDS = poDr->Create( osMskFilename, 
     799                 :                                  poDS->GetRasterXSize(),
     800                 :                                  poDS->GetRasterYSize(),
     801               3 :                                  nBands, GDT_Byte, papszOpt );
     802               3 :         CSLDestroy( papszOpt );
     803                 : 
     804               3 :         if( poMaskDS == NULL ) // presumably error already issued.
     805               0 :             return CE_Failure;
     806                 : 
     807               3 :         bOwnMaskDS = TRUE;
     808                 :     }
     809                 :         
     810                 : /* -------------------------------------------------------------------- */
     811                 : /*      Save the mask flags for this band.                              */
     812                 : /* -------------------------------------------------------------------- */
     813               3 :     if( nBand > poMaskDS->GetRasterCount() )
     814                 :     {
     815                 :         CPLError( CE_Failure, CPLE_AppDefined,
     816                 :                   "Attempt to create a mask band for band %d of %s,\n"
     817                 :                   "but the .msk file has a PER_DATASET mask.", 
     818               0 :                   nBand, poDS->GetDescription() );
     819               0 :         return CE_Failure;
     820                 :     }
     821                 :     
     822                 :     int iBand; 
     823                 : 
     824              16 :     for( iBand = 0; iBand < poDS->GetRasterCount(); iBand++ )
     825                 :     {
     826                 :         // we write only the info for this band, unless we are
     827                 :         // using PER_DATASET in which case we write for all.
     828                 :         if( nBand != iBand + 1 && !(nFlags | GMF_PER_DATASET) )
     829                 :             continue;
     830                 : 
     831                 :         poMaskDS->SetMetadataItem( 
     832                 :             CPLString().Printf("INTERNAL_MASK_FLAGS_%d", iBand+1 ),
     833               5 :             CPLString().Printf("%d", nFlags ) );
     834                 :     }
     835                 : 
     836               3 :     return CE_None;
     837                 : }
     838                 : 
     839                 : /************************************************************************/
     840                 : /*                            GetMaskBand()                             */
     841                 : /************************************************************************/
     842                 : 
     843              10 : GDALRasterBand *GDALDefaultOverviews::GetMaskBand( int nBand )
     844                 : 
     845                 : {
     846              10 :     int nFlags = GetMaskFlags( nBand );
     847                 : 
     848              10 :     if( nFlags == 0x8000 ) // secret code meaning we don't handle this band.
     849               0 :         return NULL;
     850                 :         
     851              10 :     if( nFlags & GMF_PER_DATASET )
     852              10 :         return poMaskDS->GetRasterBand(1);
     853                 : 
     854               0 :     if( nBand > 0 )
     855               0 :         return poMaskDS->GetRasterBand( nBand );
     856                 :     else 
     857               0 :         return NULL;
     858                 : }
     859                 : 
     860                 : /************************************************************************/
     861                 : /*                            GetMaskFlags()                            */
     862                 : /************************************************************************/
     863                 : 
     864              20 : int GDALDefaultOverviews::GetMaskFlags( int nBand )
     865                 : 
     866                 : {
     867                 : /* -------------------------------------------------------------------- */
     868                 : /*      Fetch this band's metadata entry.  They are of the form:        */
     869                 : /*        INTERNAL_MASK_FLAGS_n: flags                                  */
     870                 : /* -------------------------------------------------------------------- */
     871              20 :     if( !HaveMaskFile() )
     872               0 :         return 0;
     873                 :     
     874                 :     const char *pszValue = 
     875                 :         poMaskDS->GetMetadataItem( 
     876              20 :             CPLString().Printf( "INTERNAL_MASK_FLAGS_%d", MAX(nBand,1)) );
     877                 : 
     878              20 :     if( pszValue == NULL )
     879               0 :         return 0x8000;
     880                 :     else
     881              20 :         return atoi(pszValue);
     882                 : }
     883                 : 
     884                 : /************************************************************************/
     885                 : /*                            HaveMaskFile()                            */
     886                 : /*                                                                      */
     887                 : /*      Check for a mask file if we haven't already done so.            */
     888                 : /*      Returns TRUE if we have one, otherwise FALSE.                   */
     889                 : /************************************************************************/
     890                 : 
     891                 : int GDALDefaultOverviews::HaveMaskFile( char ** papszSiblingFiles,
     892            2077 :                                         const char *pszBasename )
     893                 : 
     894                 : {
     895                 : /* -------------------------------------------------------------------- */
     896                 : /*      Have we already checked for masks?                              */
     897                 : /* -------------------------------------------------------------------- */
     898            2077 :     if( bCheckedForMask )
     899             279 :         return poMaskDS != NULL;
     900                 : 
     901            1798 :     if( papszSiblingFiles == NULL )
     902            1798 :         papszSiblingFiles = papszInitSiblingFiles;
     903                 : 
     904                 : /* -------------------------------------------------------------------- */
     905                 : /*      Are we an overview?  If so we need to find the corresponding    */
     906                 : /*      overview in the base files mask file (if there is one).         */
     907                 : /* -------------------------------------------------------------------- */
     908            1798 :     if( poBaseDS != NULL && poBaseDS->oOvManager.HaveMaskFile() )
     909                 :     {
     910               3 :         int iOver, nOverviewCount = 0;
     911               3 :         GDALRasterBand *poBaseBand = poBaseDS->GetRasterBand(1);
     912               3 :         GDALRasterBand *poBaseMask = NULL;
     913                 : 
     914               3 :         if( poBaseBand != NULL )
     915               3 :             poBaseMask = poBaseBand->GetMaskBand();
     916               3 :         if( poBaseMask )
     917               3 :             nOverviewCount = poBaseMask->GetOverviewCount();
     918                 : 
     919               5 :         for( iOver = 0; iOver < nOverviewCount; iOver++ )
     920                 :         {
     921               5 :             GDALRasterBand *poOverBand = poBaseMask->GetOverview( iOver );
     922               5 :             if (poOverBand == NULL)
     923               0 :                 continue;
     924                 :             
     925               5 :             if( poOverBand->GetXSize() == poDS->GetRasterXSize() 
     926                 :                 && poOverBand->GetYSize() == poDS->GetRasterYSize() )
     927                 :             {
     928               3 :                 poMaskDS = poOverBand->GetDataset();
     929               3 :                 break;
     930                 :             }
     931                 :         }
     932                 : 
     933               3 :         bCheckedForMask = TRUE;
     934               3 :         bOwnMaskDS = FALSE;
     935                 :         
     936               3 :         CPLAssert( poMaskDS != poDS );
     937                 : 
     938               3 :         return poMaskDS != NULL;
     939                 :     }
     940                 : 
     941                 : /* -------------------------------------------------------------------- */
     942                 : /*      Are we even initialized?  If not, we apparently don't want      */
     943                 : /*      to support overviews and masks.                                 */
     944                 : /* -------------------------------------------------------------------- */
     945            1795 :     if( !IsInitialized() )
     946             138 :         return FALSE;
     947                 : 
     948                 : /* -------------------------------------------------------------------- */
     949                 : /*      Check for .msk file.                                            */
     950                 : /* -------------------------------------------------------------------- */
     951            1657 :     CPLString osMskFilename;
     952            1657 :     bCheckedForMask = TRUE;
     953                 : 
     954            1657 :     if( pszBasename == NULL )
     955            1657 :         pszBasename = poDS->GetDescription();
     956                 : 
     957                 :     // Don't bother checking for masks of masks. 
     958            1657 :     if( EQUAL(CPLGetExtension(pszBasename),".msk") )
     959            1657 :         return FALSE;
     960                 : 
     961            1657 :     osMskFilename.Printf( "%s.msk", pszBasename );
     962                 : 
     963                 :     int bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), 
     964            1657 :                                    papszSiblingFiles );
     965                 : 
     966                 : #if !defined(WIN32)
     967            1657 :     if( !bExists && !papszSiblingFiles )
     968                 :     {
     969            1637 :         osMskFilename.Printf( "%s.MSK", pszBasename );
     970                 :         bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), 
     971            1637 :                                    papszSiblingFiles );
     972                 :     }
     973                 : #endif
     974                 : 
     975            1657 :     if( !bExists )
     976            1649 :         return FALSE;
     977                 : 
     978                 : /* -------------------------------------------------------------------- */
     979                 : /*      Open the file.                                                  */
     980                 : /* -------------------------------------------------------------------- */
     981               8 :     poMaskDS = (GDALDataset *) GDALOpen( osMskFilename, poDS->GetAccess() );
     982               8 :     CPLAssert( poMaskDS != poDS );
     983                 : 
     984               8 :     if( poMaskDS == NULL )
     985               0 :         return FALSE;
     986                 : 
     987               8 :     bOwnMaskDS = TRUE;
     988                 :     
     989               8 :     return TRUE;
     990                 : }

Generated by: LTP GCOV extension version 1.5