Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdaldefaultoverviews.cpp

00001 /******************************************************************************
00002  * $Id: gdaldefaultoverviews_cpp-source.html,v 1.8 2001/07/05 13:24:08 warmerda Exp $
00003  *
00004  * Project:  GDAL Core
00005  * Purpose:  Helper code to implement overview support in different drivers.
00006  * Author:   Frank Warmerdam, warmerda@home.com
00007  *
00008  ******************************************************************************
00009  * Copyright (c) 2000, Frank Warmerdam
00010  *
00011  * Permission is hereby granted, free of charge, to any person obtaining a
00012  * copy of this software and associated documentation files (the "Software"),
00013  * to deal in the Software without restriction, including without limitation
00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00015  * and/or sell copies of the Software, and to permit persons to whom the
00016  * Software is furnished to do so, subject to the following conditions:
00017  *
00018  * The above copyright notice and this permission notice shall be included
00019  * in all copies or substantial portions of the Software.
00020  *
00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00022  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00027  * DEALINGS IN THE SOFTWARE.
00028  ******************************************************************************
00029  *
00030  * $Log: gdaldefaultoverviews_cpp-source.html,v $
00030  * Revision 1.8  2001/07/05 13:24:08  warmerda
00030  * *** empty log message ***
00030  *
00031  * Revision 1.6  2001/06/22 21:00:38  warmerda
00032  * fixed several problems with regenerating existing overviews
00033  *
00034  * Revision 1.5  2001/06/22 13:52:03  warmerda
00035  * fixed bug when refreshing overviews during build
00036  *
00037  * Revision 1.4  2001/06/20 16:08:54  warmerda
00038  * GDALDefaultOverviews now remembers ovr filename, and allows explicit setting
00039  *
00040  * Revision 1.3  2000/06/19 18:48:49  warmerda
00041  * fixed message
00042  *
00043  * Revision 1.2  2000/06/19 14:42:27  warmerda
00044  * Don't close old overviews till after we have identified which already
00045  * exist, otherwise multiple copies of overviews may be created.
00046  *
00047  * Revision 1.1  2000/04/21 21:54:05  warmerda
00048  * New
00049  *
00050  */
00051 
00052 #include "gdal_priv.h"
00053 
00054 /************************************************************************/
00055 /*                        GDALDefaultOverviews()                        */
00056 /************************************************************************/
00057 
00058 GDALDefaultOverviews::GDALDefaultOverviews()
00059 
00060 {
00061     poDS = NULL;
00062     poODS = NULL;
00063     pszOvrFilename = NULL;
00064 }
00065 
00066 /************************************************************************/
00067 /*                       ~GDALDefaultOverviews()                        */
00068 /************************************************************************/
00069 
00070 GDALDefaultOverviews::~GDALDefaultOverviews()
00071 
00072 {
00073     if( poODS != NULL )
00074     {
00075         poODS->FlushCache();
00076         delete poODS;
00077     }
00078     CPLFree( pszOvrFilename );
00079 }
00080 
00081 /************************************************************************/
00082 /*                             Initialize()                             */
00083 /************************************************************************/
00084 
00085 void GDALDefaultOverviews::Initialize( GDALDataset *poDS,
00086                                        const char * pszBasename,
00087                                        int bNameIsOVR )
00088 
00089 {
00090     VSIStatBuf sStatBuf;
00091 
00092 /* -------------------------------------------------------------------- */
00093 /*      If we were already initialized, destroy the old overview        */
00094 /*      file handle.                                                    */
00095 /* -------------------------------------------------------------------- */
00096     if( this->poODS != NULL )
00097     {
00098         delete poODS;
00099     }
00100 
00101 /* -------------------------------------------------------------------- */
00102 /*      Open overview dataset if it exists.                             */
00103 /* -------------------------------------------------------------------- */
00104     this->poDS = poDS;
00105     
00106     if( pszBasename == NULL )
00107         pszBasename = poDS->GetDescription();
00108 
00109     CPLFree( pszOvrFilename );
00110     pszOvrFilename = (char *) CPLMalloc(strlen(pszBasename)+5);
00111     if( bNameIsOVR )
00112         strcpy( pszOvrFilename, pszBasename );
00113     else
00114         sprintf( pszOvrFilename, "%s.ovr", pszBasename );
00115 
00116     if( VSIStat( pszOvrFilename, &sStatBuf ) == 0 )
00117         poODS = (GDALDataset *) GDALOpen( pszOvrFilename, poDS->GetAccess() );
00118 }
00119 
00120 /************************************************************************/
00121 /*                          GetOverviewCount()                          */
00122 /************************************************************************/
00123 
00124 int GDALDefaultOverviews::GetOverviewCount( int nBand )
00125 
00126 {
00127     GDALRasterBand * poBand;
00128 
00129     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
00130         return 0;
00131 
00132     poBand = poODS->GetRasterBand( nBand );
00133     if( poBand == NULL )
00134         return 0;
00135     else
00136         return poBand->GetOverviewCount() + 1;
00137 }
00138 
00139 /************************************************************************/
00140 /*                            GetOverview()                             */
00141 /************************************************************************/
00142 
00143 GDALRasterBand *
00144 GDALDefaultOverviews::GetOverview( int nBand, int iOverview )
00145 
00146 {
00147     GDALRasterBand * poBand;
00148 
00149     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
00150         return NULL;
00151 
00152     poBand = poODS->GetRasterBand( nBand );
00153     if( poBand == NULL )
00154         return NULL;
00155 
00156     if( iOverview == 0 )
00157         return poBand;
00158     else if( iOverview-1 >= poBand->GetOverviewCount() )
00159         return NULL;
00160     else
00161         return poBand->GetOverview( iOverview-1 );
00162 }
00163 
00164 /************************************************************************/
00165 /*                         GDALOvLevelAdjust()                          */
00166 /*                                                                      */
00167 /*      Some overview levels cannot be achieved closely enough to be    */
00168 /*      recognised as the desired overview level.  This function        */
00169 /*      will adjust an overview level to one that is achievable on      */
00170 /*      the given raster size.                                          */
00171 /*                                                                      */
00172 /*      For instance a 1200x1200 image on which a 256 level overview    */
00173 /*      is request will end up generating a 5x5 overview.  However,     */
00174 /*      this will appear to the system be a level 240 overview.         */
00175 /*      This function will adjust 256 to 240 based on knowledge of      */
00176 /*      the image size.                                                 */
00177 /************************************************************************/
00178 
00179 static int GDALOvLevelAdjust( int nOvLevel, int nXSize )
00180 
00181 {
00182     int nOXSize = (nXSize + nOvLevel - 1) / nOvLevel;
00183     
00184     return (int) (0.5 + nXSize / (double) nOXSize);
00185 }
00186     
00187 /************************************************************************/
00188 /*                     GDALDefaultBuildOverviews()                      */
00189 /************************************************************************/
00190 
00191 CPLErr
00192 GDALDefaultOverviews::BuildOverviews( 
00193     const char * pszBasename,
00194     const char * pszResampling, 
00195     int nOverviews, int * panOverviewList,
00196     int nBands, int * panBandList,
00197     GDALProgressFunc pfnProgress, void * pProgressData)
00198 
00199 {
00200     GDALRasterBand **pahBands;
00201     CPLErr       eErr;
00202     int          i;
00203 
00204 /* -------------------------------------------------------------------- */
00205 /*      Our TIFF overview support currently only works safely if all    */
00206 /*      bands are handled at the same time.                             */
00207 /* -------------------------------------------------------------------- */
00208     if( nBands != poDS->GetRasterCount() )
00209     {
00210         CPLError( CE_Failure, CPLE_NotSupported,
00211                   "Generation of overviews in external TIFF currently only"
00212                   " supported when operating on all bands.\n" 
00213                   "Operation failed.\n" );
00214         return CE_Failure;
00215     }
00216 
00217 /* -------------------------------------------------------------------- */
00218 /*      If a basename is provided, use it to override the internal      */
00219 /*      overview filename.                                              */
00220 /* -------------------------------------------------------------------- */
00221     if( pszBasename == NULL && pszOvrFilename == NULL )
00222         pszBasename = poDS->GetDescription();
00223 
00224     if( pszBasename != NULL )
00225     {
00226         CPLFree( pszOvrFilename );
00227         pszOvrFilename = (char *) CPLMalloc(strlen(pszBasename)+5);
00228         sprintf( pszOvrFilename, "%s.ovr", pszBasename );
00229     }
00230 
00231 /* -------------------------------------------------------------------- */
00232 /*      Establish which of the overview levels we already have, and     */
00233 /*      which are new.  We assume that band 1 of the file is            */
00234 /*      representative.                                                 */
00235 /* -------------------------------------------------------------------- */
00236     int   nNewOverviews, *panNewOverviewList = NULL;
00237     GDALRasterBand *poBand = poDS->GetRasterBand( 1 );
00238 
00239     nNewOverviews = 0;
00240     panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews);
00241     for( i = 0; i < nOverviews && poBand != NULL; i++ )
00242     {
00243         int   j;
00244 
00245         for( j = 0; j < poBand->GetOverviewCount(); j++ )
00246         {
00247             int    nOvFactor;
00248             GDALRasterBand * poOverview = poBand->GetOverview( j );
00249  
00250             nOvFactor = (int) 
00251                 (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
00252 
00253             if( nOvFactor == panOverviewList[i] 
00254                 || nOvFactor == GDALOvLevelAdjust( panOverviewList[i], 
00255                                                    poBand->GetXSize() ) )
00256                 panOverviewList[i] *= -1;
00257         }
00258 
00259         if( panOverviewList[i] > 0 )
00260             panNewOverviewList[nNewOverviews++] = panOverviewList[i];
00261     }
00262 
00263 /* -------------------------------------------------------------------- */
00264 /*      If we have an existing overview file open, close it now.        */
00265 /* -------------------------------------------------------------------- */
00266     if( poODS != NULL )
00267     {
00268         delete poODS;
00269         poODS = NULL;
00270     }
00271 
00272 /* -------------------------------------------------------------------- */
00273 /*      Build band list.                                                */
00274 /* -------------------------------------------------------------------- */
00275     pahBands = (GDALRasterBand **) CPLCalloc(sizeof(GDALRasterBand *),nBands);
00276     for( i = 0; i < nBands; i++ )
00277         pahBands[i] = poDS->GetRasterBand( panBandList[i] );
00278 
00279 /* -------------------------------------------------------------------- */
00280 /*      Build new overviews.                                            */
00281 /* -------------------------------------------------------------------- */
00282 
00283     eErr = GTIFFBuildOverviews( pszOvrFilename, nBands, pahBands, 
00284                                 nNewOverviews, panNewOverviewList, 
00285                                 pszResampling, pfnProgress, pProgressData );
00286 
00287 /* -------------------------------------------------------------------- */
00288 /*      Refresh old overviews that were listed.                         */
00289 /* -------------------------------------------------------------------- */
00290     GDALRasterBand **papoOverviewBands;
00291 
00292     if( eErr == CE_None )
00293     {
00294         poODS = (GDALDataset *) GDALOpen( pszOvrFilename, GA_Update );
00295         if( poODS == NULL )
00296             eErr = CE_Failure;
00297     }
00298 
00299     papoOverviewBands = (GDALRasterBand **) 
00300         CPLCalloc(sizeof(void*),nOverviews);
00301 
00302     for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
00303     {
00304         poBand = poDS->GetRasterBand( panBandList[iBand] );
00305 
00306         nNewOverviews = 0;
00307         for( i = 0; i < nOverviews && poBand != NULL; i++ )
00308         {
00309             int   j;
00310             
00311             for( j = 0; j < poBand->GetOverviewCount(); j++ )
00312             {
00313                 int    nOvFactor;
00314                 GDALRasterBand * poOverview = poBand->GetOverview( j );
00315 
00316                 nOvFactor = (int) 
00317                     (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
00318 
00319                 if( nOvFactor == - panOverviewList[i] 
00320                     || nOvFactor == GDALOvLevelAdjust( -panOverviewList[i], 
00321                                                        poBand->GetXSize() ) )
00322                 {
00323                     panOverviewList[i] *= -1;
00324                     papoOverviewBands[nNewOverviews++] = poOverview;
00325                 }
00326             }
00327         }
00328 
00329         if( nNewOverviews > 0 )
00330         {
00331             eErr = GDALRegenerateOverviews( poBand, 
00332                                             nNewOverviews, papoOverviewBands,
00333                                             pszResampling, 
00334                                             GDALDummyProgress, NULL );
00335         }
00336     }
00337 
00338 /* -------------------------------------------------------------------- */
00339 /*      Cleanup                                                         */
00340 /* -------------------------------------------------------------------- */
00341     CPLFree( papoOverviewBands );
00342     CPLFree( panNewOverviewList );
00343     CPLFree( pahBands );
00344 
00345     return eErr;
00346 }
00347 

Generated at Thu Jul 5 09:16:12 2001 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000