00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00030 00030 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041
00042
00043 #include "gdal_priv.h"
00044
00045
00046
00047
00048
00049 GDALDefaultOverviews::GDALDefaultOverviews()
00050
00051 {
00052 poDS = NULL;
00053 poODS = NULL;
00054 }
00055
00056
00057
00058
00059
00060 GDALDefaultOverviews::~GDALDefaultOverviews()
00061
00062 {
00063 if( poODS != NULL )
00064 {
00065 poODS->FlushCache();
00066 delete poODS;
00067 }
00068 }
00069
00070
00071
00072
00073
00074 void GDALDefaultOverviews::Initialize( GDALDataset *poDS,
00075 const char * pszBasename )
00076
00077 {
00078 char * pszTIFFFilename;
00079 VSIStatBuf sStatBuf;
00080
00081
00082
00083
00084
00085 if( this->poODS != NULL )
00086 {
00087 delete poODS;
00088 }
00089
00090
00091
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
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
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
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
00171
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
00184
00185
00186 if( pszBasename == NULL )
00187 pszBasename = poDS->GetDescription();
00188
00189
00190
00191
00192
00193 pszTIFFFilename = (char *) CPLMalloc(strlen(pszBasename)+5);
00194 sprintf( pszTIFFFilename, "%s.ovr", pszBasename );
00195
00196
00197
00198
00199
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
00228
00229 if( poODS != NULL )
00230 {
00231 delete poODS;
00232 poODS = NULL;
00233 }
00234
00235
00236
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
00244
00245
00246 eErr = GTIFFBuildOverviews( pszTIFFFilename, nBands, pahBands,
00247 nNewOverviews, panNewOverviewList,
00248 pszResampling, pfnProgress, pProgressData );
00249
00250
00251
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
00300
00301 CPLFree( papoOverviewBands );
00302 CPLFree( panNewOverviewList );
00303 CPLFree( pahBands );
00304 CPLFree( pszTIFFFilename );
00305
00306 return eErr;
00307 }
00308