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.5 2000/11/06 04:49:01 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.5  2000/11/06 04:49:01  warmerda
00030  * *** empty log message ***
00030  *
00031  * Revision 1.3  2000/06/19 18:48:49  warmerda
00032  * fixed message
00033  *
00034  * Revision 1.2  2000/06/19 14:42:27  warmerda
00035  * Don't close old overviews till after we have identified which already
00036  * exist, otherwise multiple copies of overviews may be created.
00037  *
00038  * Revision 1.1  2000/04/21 21:54:05  warmerda
00039  * New
00040  *
00041  */
00042 
00043 #include "gdal_priv.h"
00044 
00045 /************************************************************************/
00046 /*                        GDALDefaultOverviews()                        */
00047 /************************************************************************/
00048 
00049 GDALDefaultOverviews::GDALDefaultOverviews()
00050 
00051 {
00052     poDS = NULL;
00053     poODS = NULL;
00054 }
00055 
00056 /************************************************************************/
00057 /*                       ~GDALDefaultOverviews()                        */
00058 /************************************************************************/
00059 
00060 GDALDefaultOverviews::~GDALDefaultOverviews()
00061 
00062 {
00063     if( poODS != NULL )
00064     {
00065         poODS->FlushCache();
00066         delete poODS;
00067     }
00068 }
00069 
00070 /************************************************************************/
00071 /*                             Initialize()                             */
00072 /************************************************************************/
00073 
00074 void GDALDefaultOverviews::Initialize( GDALDataset *poDS,
00075                                        const char * pszBasename )
00076 
00077 {
00078     char * pszTIFFFilename;
00079     VSIStatBuf sStatBuf;
00080 
00081 /* -------------------------------------------------------------------- */
00082 /*      If we were already initialized, destroy the old overview        */
00083 /*      file handle.                                                    */
00084 /* -------------------------------------------------------------------- */
00085     if( this->poODS != NULL )
00086     {
00087         delete poODS;
00088     }
00089 
00090 /* -------------------------------------------------------------------- */
00091 /*      Open overview dataset if it exists.                             */
00092 /* -------------------------------------------------------------------- */
00093     this->poDS = poDS;
00094     
00095     if( pszBasename == NULL )
00096         pszBasename = poDS->GetDescription();
00097 
00098     pszTIFFFilename = (char *) CPLMalloc(strlen(pszBasename)+5);
00099     sprintf( pszTIFFFilename, "%s.ovr", pszBasename );
00100 
00101     if( VSIStat( pszTIFFFilename, &sStatBuf ) == 0 )
00102         poODS = (GDALDataset *) GDALOpen( pszTIFFFilename, poDS->GetAccess() );
00103 
00104     CPLFree( pszTIFFFilename );
00105 }
00106 
00107 /************************************************************************/
00108 /*                          GetOverviewCount()                          */
00109 /************************************************************************/
00110 
00111 int GDALDefaultOverviews::GetOverviewCount( int nBand )
00112 
00113 {
00114     GDALRasterBand * poBand;
00115 
00116     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
00117         return 0;
00118 
00119     poBand = poODS->GetRasterBand( nBand );
00120     if( poBand == NULL )
00121         return 0;
00122     else
00123         return poBand->GetOverviewCount() + 1;
00124 }
00125 
00126 /************************************************************************/
00127 /*                            GetOverview()                             */
00128 /************************************************************************/
00129 
00130 GDALRasterBand *
00131 GDALDefaultOverviews::GetOverview( int nBand, int iOverview )
00132 
00133 {
00134     GDALRasterBand * poBand;
00135 
00136     if( poODS == NULL || nBand < 1 || nBand > poODS->GetRasterCount() )
00137         return NULL;
00138 
00139     poBand = poODS->GetRasterBand( nBand );
00140     if( poBand == NULL )
00141         return NULL;
00142 
00143     if( iOverview == 0 )
00144         return poBand;
00145     else if( iOverview-1 >= poBand->GetOverviewCount() )
00146         return NULL;
00147     else
00148         return poBand->GetOverview( iOverview-1 );
00149 }
00150     
00151 /************************************************************************/
00152 /*                     GDALDefaultBuildOverviews()                      */
00153 /************************************************************************/
00154 
00155 CPLErr
00156 GDALDefaultOverviews::BuildOverviews( 
00157     const char * pszBasename,
00158     const char * pszResampling, 
00159     int nOverviews, int * panOverviewList,
00160     int nBands, int * panBandList,
00161     GDALProgressFunc pfnProgress, void * pProgressData)
00162 
00163 {
00164     char * pszTIFFFilename;
00165     GDALRasterBand **pahBands;
00166     CPLErr       eErr;
00167     int          i;
00168 
00169 /* -------------------------------------------------------------------- */
00170 /*      Our TIFF overview support currently only works safely if all    */
00171 /*      bands are handled at the same time.                             */
00172 /* -------------------------------------------------------------------- */
00173     if( nBands != poDS->GetRasterCount() )
00174     {
00175         CPLError( CE_Failure, CPLE_NotSupported,
00176                   "Generation of overviews in external TIFF currently only"
00177                   " supported when operating on all bands.\n" 
00178                   "Operation failed.\n" );
00179         return CE_Failure;
00180     }
00181 
00182 /* -------------------------------------------------------------------- */
00183 /*      By default we assume that the dataset name is a suitable        */
00184 /*      filesystem object to associate with if nothing is provided.     */
00185 /* -------------------------------------------------------------------- */
00186     if( pszBasename == NULL )
00187         pszBasename = poDS->GetDescription();
00188 
00189 /* -------------------------------------------------------------------- */
00190 /*      Generate the TIFF filename.  This approach may not work well    */
00191 /*      on Windows.                                                     */
00192 /* -------------------------------------------------------------------- */
00193     pszTIFFFilename = (char *) CPLMalloc(strlen(pszBasename)+5);
00194     sprintf( pszTIFFFilename, "%s.ovr", pszBasename );
00195 
00196 /* -------------------------------------------------------------------- */
00197 /*      Establish which of the overview levels we already have, and     */
00198 /*      which are new.  We assume that band 1 of the file is            */
00199 /*      representative.                                                 */
00200 /* -------------------------------------------------------------------- */
00201     int   nNewOverviews, *panNewOverviewList = NULL;
00202     GDALRasterBand *poBand = poDS->GetRasterBand( 1 );
00203 
00204     nNewOverviews = 0;
00205     panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews);
00206     for( i = 0; i < nOverviews && poBand != NULL; i++ )
00207     {
00208         int   j;
00209 
00210         for( j = 0; j < poBand->GetOverviewCount(); j++ )
00211         {
00212             int    nOvFactor;
00213             GDALRasterBand * poOverview = poBand->GetOverview( j );
00214 
00215             nOvFactor = (int) 
00216                 (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
00217 
00218             if( nOvFactor == panOverviewList[i] )
00219                 panOverviewList[i] *= -1;
00220         }
00221 
00222         if( panOverviewList[i] > 0 )
00223             panNewOverviewList[nNewOverviews++] = panOverviewList[i];
00224     }
00225 
00226 /* -------------------------------------------------------------------- */
00227 /*      If we have an existing overview file open, close it now.        */
00228 /* -------------------------------------------------------------------- */
00229     if( poODS != NULL )
00230     {
00231         delete poODS;
00232         poODS = NULL;
00233     }
00234 
00235 /* -------------------------------------------------------------------- */
00236 /*      Build band list.                                                */
00237 /* -------------------------------------------------------------------- */
00238     pahBands = (GDALRasterBand **) CPLCalloc(sizeof(GDALRasterBand *),nBands);
00239     for( i = 0; i < nBands; i++ )
00240         pahBands[i] = poDS->GetRasterBand( panBandList[i] );
00241 
00242 /* -------------------------------------------------------------------- */
00243 /*      Build new overviews.                                            */
00244 /* -------------------------------------------------------------------- */
00245 
00246     eErr = GTIFFBuildOverviews( pszTIFFFilename, nBands, pahBands, 
00247                                 nNewOverviews, panNewOverviewList, 
00248                                 pszResampling, pfnProgress, pProgressData );
00249 
00250 /* -------------------------------------------------------------------- */
00251 /*      Refresh old overviews that were listed.                         */
00252 /* -------------------------------------------------------------------- */
00253     GDALRasterBand **papoOverviewBands;
00254 
00255     if( eErr == CE_None )
00256     {
00257         poODS = (GDALDataset *) GDALOpen( pszTIFFFilename, GA_Update );
00258         if( poODS == NULL )
00259             eErr = CE_Failure;
00260     }
00261 
00262     papoOverviewBands = (GDALRasterBand **) 
00263         CPLCalloc(sizeof(void*),nOverviews);
00264 
00265     for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
00266     {
00267         poBand = poDS->GetRasterBand( panBandList[iBand] );
00268 
00269         nNewOverviews = 0;
00270         for( i = 0; i < nOverviews && poBand != NULL; i++ )
00271         {
00272             int   j;
00273             
00274             for( j = 0; j < poBand->GetOverviewCount(); j++ )
00275             {
00276                 int    nOvFactor;
00277                 GDALRasterBand * poOverview = poBand->GetOverview( j );
00278 
00279                 nOvFactor = (int) 
00280                     (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize());
00281 
00282                 if( nOvFactor == -1 * panOverviewList[i] )
00283                 {
00284                     panOverviewList[i] *= -1;
00285                     papoOverviewBands[nNewOverviews++] = poBand;
00286                 }
00287             }
00288         }
00289 
00290         if( nNewOverviews > 0 )
00291         {
00292             eErr = GDALRegenerateOverviews( poBand, 
00293                                             nNewOverviews, papoOverviewBands,
00294                                             pszResampling, NULL, NULL );
00295         }
00296     }
00297 
00298 /* -------------------------------------------------------------------- */
00299 /*      Cleanup                                                         */
00300 /* -------------------------------------------------------------------- */
00301     CPLFree( papoOverviewBands );
00302     CPLFree( panNewOverviewList );
00303     CPLFree( pahBands );
00304     CPLFree( pszTIFFFilename );
00305 
00306     return eErr;
00307 }
00308 

doxygen1.2.3-20001105 Dimitri van Heesch, © 1997-2000