CPLErr GDALDefaultOverviews::BuildOverviews( const char * pszBasename, const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; if( nOverviews == 0 ) return CleanOverviews(); /* -------------------------------------------------------------------- */ /* If we don't already have an overview file, we need to decide */ /* what format to use. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { bOvrIsAux = CPLTestBool(CPLGetConfigOption( "USE_RRD", "NO" )); if( bOvrIsAux ) { osOvrFilename = CPLResetExtension(poDS->GetDescription(),"aux"); VSIStatBufL sStatBuf; if( VSIStatExL( osOvrFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 ) osOvrFilename.Printf( "%s.aux", poDS->GetDescription() ); } } /* -------------------------------------------------------------------- */ /* If we already have the overviews open, but they are */ /* read-only, then try and reopen them read-write. */ /* -------------------------------------------------------------------- */ else if( poODS->GetAccess() == GA_ReadOnly ) { GDALClose( poODS ); poODS = static_cast<GDALDataset *>( GDALOpen( osOvrFilename, GA_Update )); if( poODS == NULL ) return CE_Failure; } /* -------------------------------------------------------------------- */ /* Our TIFF overview support currently only works safely if all */ /* bands are handled at the same time. */ /* -------------------------------------------------------------------- */ if( !bOvrIsAux && nBands != poDS->GetRasterCount() ) { CPLError( CE_Failure, CPLE_NotSupported, "Generation of overviews in external TIFF currently only " "supported when operating on all bands. " "Operation failed." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* If a basename is provided, use it to override the internal */ /* overview filename. */ /* -------------------------------------------------------------------- */ if( pszBasename == NULL && osOvrFilename.length() == 0 ) pszBasename = poDS->GetDescription(); if( pszBasename != NULL ) { if( bOvrIsAux ) osOvrFilename.Printf( "%s.aux", pszBasename ); else osOvrFilename.Printf( "%s.ovr", pszBasename ); } /* -------------------------------------------------------------------- */ /* Establish which of the overview levels we already have, and */ /* which are new. We assume that band 1 of the file is */ /* representative. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poBand = poDS->GetRasterBand( 1 ); int nNewOverviews = 0; int *panNewOverviewList = static_cast<int *>( CPLCalloc(sizeof(int), nOverviews) ); double dfAreaNewOverviews = 0; double dfAreaRefreshedOverviews = 0; for( int i = 0; i < nOverviews && poBand != NULL; i++ ) { for( int j = 0; j < poBand->GetOverviewCount(); j++ ) { GDALRasterBand * poOverview = poBand->GetOverview( j ); if( poOverview == NULL ) continue; int nOvFactor = GDALComputeOvFactor(poOverview->GetXSize(), poBand->GetXSize(), poOverview->GetYSize(), poBand->GetYSize()); if( nOvFactor == panOverviewList[i] || nOvFactor == GDALOvLevelAdjust2( panOverviewList[i], poBand->GetXSize(), poBand->GetYSize() ) ) { panOverviewList[i] *= -1; } } const double dfArea = 1.0 / (panOverviewList[i] * panOverviewList[i]); dfAreaRefreshedOverviews += dfArea; if( panOverviewList[i] > 0 ) { dfAreaNewOverviews += dfArea; panNewOverviewList[nNewOverviews++] = panOverviewList[i]; } } /* -------------------------------------------------------------------- */ /* Build band list. */ /* -------------------------------------------------------------------- */ GDALRasterBand **pahBands = static_cast<GDALRasterBand **>( CPLCalloc(sizeof(GDALRasterBand *), nBands) ); for( int i = 0; i < nBands; i++ ) pahBands[i] = poDS->GetRasterBand( panBandList[i] ); /* -------------------------------------------------------------------- */ /* Build new overviews - Imagine. Keep existing file open if */ /* we have it. But mark all overviews as in need of */ /* regeneration, since HFAAuxBuildOverviews() doesn't actually */ /* produce the imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; void* pScaledProgress = GDALCreateScaledProgress( 0, dfAreaNewOverviews / dfAreaRefreshedOverviews, pfnProgress, pProgressData ); if( bOvrIsAux ) { if( nNewOverviews == 0 ) { /* if we call HFAAuxBuildOverviews() with nNewOverviews == 0 */ /* because that there's no new, this will wipe existing */ /* overviews (#4831) */ // eErr = CE_None; } else { eErr = HFAAuxBuildOverviews( osOvrFilename, poDS, &poODS, nBands, panBandList, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); } for( int j = 0; j < nOverviews; j++ ) { if( panOverviewList[j] > 0 ) panOverviewList[j] *= -1; } } /* -------------------------------------------------------------------- */ /* Build new overviews - TIFF. Close TIFF files while we */ /* operate on it. */ /* -------------------------------------------------------------------- */ else { if( poODS != NULL ) { delete poODS; poODS = NULL; } eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); // Probe for proxy overview filename. if( eErr == CE_Failure ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem("FILENAME","ProxyOverviewRequest"); if( pszProxyOvrFilename != NULL ) { osOvrFilename = pszProxyOvrFilename; eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); } } if( eErr == CE_None ) { poODS = static_cast<GDALDataset *>( GDALOpen( osOvrFilename, GA_Update ) ); if( poODS == NULL ) eErr = CE_Failure; } } GDALDestroyScaledProgress( pScaledProgress ); /* -------------------------------------------------------------------- */ /* Refresh old overviews that were listed. */ /* -------------------------------------------------------------------- */ GDALRasterBand **papoOverviewBands = static_cast<GDALRasterBand **>( CPLCalloc(sizeof(void*), nOverviews) ); for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { poBand = poDS->GetRasterBand( panBandList[iBand] ); nNewOverviews = 0; for( int i = 0; i < nOverviews && poBand != NULL; i++ ) { for( int j = 0; j < poBand->GetOverviewCount(); j++ ) { GDALRasterBand * poOverview = poBand->GetOverview( j ); if( poOverview == NULL ) continue; int bHasNoData = FALSE; double noDataValue = poBand->GetNoDataValue(&bHasNoData); if( bHasNoData ) poOverview->SetNoDataValue(noDataValue); const int nOvFactor = GDALComputeOvFactor(poOverview->GetXSize(), poBand->GetXSize(), poOverview->GetYSize(), poBand->GetYSize()); if( nOvFactor == - panOverviewList[i] || (panOverviewList[i] < 0 && nOvFactor == GDALOvLevelAdjust2( -panOverviewList[i], poBand->GetXSize(), poBand->GetYSize() )) ) { papoOverviewBands[nNewOverviews++] = poOverview; break; } } } if( nNewOverviews > 0 ) { const double dfOffset = dfAreaNewOverviews / dfAreaRefreshedOverviews; const double dfScale = 1.0 - dfOffset; pScaledProgress = GDALCreateScaledProgress( dfOffset + dfScale * iBand / nBands, dfOffset + dfScale * (iBand+1) / nBands, pfnProgress, pProgressData ); eErr = GDALRegenerateOverviews( (GDALRasterBandH) poBand, nNewOverviews, (GDALRasterBandH*)papoOverviewBands, pszResampling, GDALScaledProgress, pScaledProgress ); GDALDestroyScaledProgress( pScaledProgress ); } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( papoOverviewBands ); CPLFree( panNewOverviewList ); CPLFree( pahBands ); /* -------------------------------------------------------------------- */ /* If we have a mask file, we need to build its overviews too. */ /* -------------------------------------------------------------------- */ if( HaveMaskFile() && poMaskDS ) { // Some config option are not compatible with mask overviews // so unset them, and define more sensible values. const bool bJPEG = EQUAL(CPLGetConfigOption("COMPRESS_OVERVIEW", ""), "JPEG"); const bool bPHOTOMETRIC_YCBCR = EQUAL(CPLGetConfigOption("PHOTOMETRIC_OVERVIEW", ""), "YCBCR"); if( bJPEG ) CPLSetThreadLocalConfigOption("COMPRESS_OVERVIEW", "DEFLATE"); if( bPHOTOMETRIC_YCBCR ) CPLSetThreadLocalConfigOption("PHOTOMETRIC_OVERVIEW", ""); poMaskDS->BuildOverviews( pszResampling, nOverviews, panOverviewList, 0, NULL, pfnProgress, pProgressData ); // Restore config option. if( bJPEG ) CPLSetThreadLocalConfigOption("COMPRESS_OVERVIEW", "JPEG"); if( bPHOTOMETRIC_YCBCR ) CPLSetThreadLocalConfigOption("PHOTOMETRIC_OVERVIEW", "YCBCR"); if( bOwnMaskDS ) { // Reset the poMask member of main dataset bands, since it // will become invalid after poMaskDS closing. for( int iBand = 1; iBand <= poDS->GetRasterCount(); iBand ++ ) { GDALRasterBand *poOtherBand = poDS->GetRasterBand(iBand); if( poOtherBand != NULL ) poOtherBand->InvalidateMaskBand(); } GDALClose( poMaskDS ); } // force next request to reread mask file. poMaskDS = NULL; bOwnMaskDS = false; bCheckedForMask = false; } /* -------------------------------------------------------------------- */ /* If we have an overview dataset, then mark all the overviews */ /* with the base dataset Used later for finding overviews */ /* masks. Uggg. */ /* -------------------------------------------------------------------- */ if( poODS ) { const int nOverviewCount = GetOverviewCount(1); for( int iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poOtherBand = GetOverview( 1, iOver ); GDALDataset *poOverDS = poOtherBand != NULL ? poOtherBand->GetDataset() : NULL; if( poOverDS != NULL ) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } return eErr; }
void GDALDefaultOverviews::OverviewScan() { if( bCheckedForOverviews || poDS == NULL ) return; bCheckedForOverviews = true; CPLDebug( "GDAL", "GDALDefaultOverviews::OverviewScan()" ); /* -------------------------------------------------------------------- */ /* Open overview dataset if it exists. */ /* -------------------------------------------------------------------- */ int bExists; if( pszInitName == NULL ) pszInitName = CPLStrdup(poDS->GetDescription()); if( !EQUAL(pszInitName,":::VIRTUAL:::") ) { if( bInitNameIsOVR ) osOvrFilename = pszInitName; else osOvrFilename.Printf( "%s.ovr", pszInitName ); bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), papszInitSiblingFiles ); #if !defined(WIN32) if( !bInitNameIsOVR && !bExists && !papszInitSiblingFiles ) { osOvrFilename.Printf( "%s.OVR", pszInitName ); bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), papszInitSiblingFiles ); if( !bExists ) osOvrFilename.Printf( "%s.ovr", pszInitName ); } #endif if( bExists ) { GDALOpenInfo oOpenInfo(osOvrFilename, poDS->GetAccess(), papszInitSiblingFiles); poODS = (GDALDataset*) GDALOpenInternal( oOpenInfo, NULL ); } } /* -------------------------------------------------------------------- */ /* We didn't find that, so try and find a corresponding aux */ /* file. Check that we are the dependent file of the aux */ /* file. */ /* */ /* We only use the .aux file for overviews if they already have */ /* overviews existing, or if USE_RRD is set true. */ /* -------------------------------------------------------------------- */ if( !poODS && !EQUAL(pszInitName,":::VIRTUAL:::") ) { int bTryFindAssociatedAuxFile = TRUE; if( papszInitSiblingFiles ) { CPLString osAuxFilename = CPLResetExtension( pszInitName, "aux"); int iSibling = CSLFindString( papszInitSiblingFiles, CPLGetFilename(osAuxFilename) ); if( iSibling < 0 ) { osAuxFilename = pszInitName; osAuxFilename += ".aux"; iSibling = CSLFindString( papszInitSiblingFiles, CPLGetFilename(osAuxFilename) ); if( iSibling < 0 ) bTryFindAssociatedAuxFile = FALSE; } } if (bTryFindAssociatedAuxFile) { poODS = GDALFindAssociatedAuxFile( pszInitName, poDS->GetAccess(), poDS ); } if( poODS ) { int bUseRRD = CSLTestBoolean(CPLGetConfigOption("USE_RRD","NO")); bOvrIsAux = TRUE; if( GetOverviewCount(1) == 0 && !bUseRRD ) { bOvrIsAux = FALSE; GDALClose( poODS ); poODS = NULL; } else { osOvrFilename = poODS->GetDescription(); } } } /* -------------------------------------------------------------------- */ /* If we still don't have an overview, check to see if we have */ /* overview metadata referencing a remote (ie. proxy) or local */ /* subdataset overview dataset. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem( "OVERVIEW_FILE", "OVERVIEWS" ); if( pszProxyOvrFilename != NULL ) { if( EQUALN(pszProxyOvrFilename,":::BASE:::",10) ) { CPLString osPath = CPLGetPath(poDS->GetDescription()); osOvrFilename = CPLFormFilename( osPath, pszProxyOvrFilename+10, NULL ); } else osOvrFilename = pszProxyOvrFilename; CPLPushErrorHandler(CPLQuietErrorHandler); poODS = (GDALDataset *) GDALOpen(osOvrFilename,poDS->GetAccess()); CPLPopErrorHandler(); } } /* -------------------------------------------------------------------- */ /* If we have an overview dataset, then mark all the overviews */ /* with the base dataset Used later for finding overviews */ /* masks. Uggg. */ /* -------------------------------------------------------------------- */ if( poODS ) { int nOverviewCount = GetOverviewCount(1); int iOver; for( iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poBand = GetOverview( 1, iOver ); GDALDataset *poOverDS = NULL; if( poBand != NULL ) poOverDS = poBand->GetDataset(); if( poOverDS != NULL ) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } }
int GDALDefaultOverviews::HaveMaskFile( char ** papszSiblingFiles, const char *pszBasename ) { /* -------------------------------------------------------------------- */ /* Have we already checked for masks? */ /* -------------------------------------------------------------------- */ if( bCheckedForMask ) return poMaskDS != NULL; if( papszSiblingFiles == NULL ) papszSiblingFiles = papszInitSiblingFiles; /* -------------------------------------------------------------------- */ /* Are we an overview? If so we need to find the corresponding */ /* overview in the base files mask file (if there is one). */ /* -------------------------------------------------------------------- */ if( poBaseDS != NULL && poBaseDS->oOvManager.HaveMaskFile() ) { int iOver, nOverviewCount = 0; GDALRasterBand *poBaseBand = poBaseDS->GetRasterBand(1); GDALRasterBand *poBaseMask = NULL; if( poBaseBand != NULL ) poBaseMask = poBaseBand->GetMaskBand(); if( poBaseMask ) nOverviewCount = poBaseMask->GetOverviewCount(); for( iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poOverBand = poBaseMask->GetOverview( iOver ); if (poOverBand == NULL) continue; if( poOverBand->GetXSize() == poDS->GetRasterXSize() && poOverBand->GetYSize() == poDS->GetRasterYSize() ) { poMaskDS = poOverBand->GetDataset(); break; } } bCheckedForMask = TRUE; bOwnMaskDS = FALSE; CPLAssert( poMaskDS != poDS ); return poMaskDS != NULL; } /* -------------------------------------------------------------------- */ /* Are we even initialized? If not, we apparently don't want */ /* to support overviews and masks. */ /* -------------------------------------------------------------------- */ if( poDS == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Check for .msk file. */ /* -------------------------------------------------------------------- */ CPLString osMskFilename; bCheckedForMask = TRUE; if( pszBasename == NULL ) pszBasename = poDS->GetDescription(); // Don't bother checking for masks of masks. if( EQUAL(CPLGetExtension(pszBasename),"msk") ) return FALSE; osMskFilename.Printf( "%s.msk", pszBasename ); int bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), papszSiblingFiles ); #if !defined(WIN32) if( !bExists && !papszSiblingFiles ) { osMskFilename.Printf( "%s.MSK", pszBasename ); bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), papszSiblingFiles ); } #endif if( !bExists ) return FALSE; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(osMskFilename, poDS->GetAccess(), papszInitSiblingFiles); poMaskDS = (GDALDataset *) GDALOpenInternal( oOpenInfo, NULL ); CPLAssert( poMaskDS != poDS ); if( poMaskDS == NULL ) return FALSE; bOwnMaskDS = TRUE; return TRUE; }
CPLErr GDALDefaultOverviews::BuildOverviews( const char * pszBasename, const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData) { GDALRasterBand **pahBands; CPLErr eErr; int i; if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; if( nOverviews == 0 ) return CleanOverviews(); /* -------------------------------------------------------------------- */ /* If we don't already have an overview file, we need to decide */ /* what format to use. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { bOvrIsAux = CSLTestBoolean(CPLGetConfigOption( "USE_RRD", "NO" )); if( bOvrIsAux ) { VSIStatBufL sStatBuf; osOvrFilename = CPLResetExtension(poDS->GetDescription(),"aux"); if( VSIStatL( osOvrFilename, &sStatBuf ) == 0 ) osOvrFilename.Printf( "%s.aux", poDS->GetDescription() ); } } /* -------------------------------------------------------------------- */ /* If we already have the overviews open, but they are */ /* read-only, then try and reopen them read-write. */ /* -------------------------------------------------------------------- */ else if( poODS->GetAccess() == GA_ReadOnly ) { GDALClose( poODS ); poODS = (GDALDataset *) GDALOpen( osOvrFilename, GA_Update ); if( poODS == NULL ) return CE_Failure; } /* -------------------------------------------------------------------- */ /* Our TIFF overview support currently only works safely if all */ /* bands are handled at the same time. */ /* -------------------------------------------------------------------- */ if( !bOvrIsAux && nBands != poDS->GetRasterCount() ) { CPLError( CE_Failure, CPLE_NotSupported, "Generation of overviews in external TIFF currently only" " supported when operating on all bands.\n" "Operation failed.\n" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* If a basename is provided, use it to override the internal */ /* overview filename. */ /* -------------------------------------------------------------------- */ if( pszBasename == NULL && osOvrFilename.length() == 0 ) pszBasename = poDS->GetDescription(); if( pszBasename != NULL ) { if( bOvrIsAux ) osOvrFilename.Printf( "%s.aux", pszBasename ); else osOvrFilename.Printf( "%s.ovr", pszBasename ); } /* -------------------------------------------------------------------- */ /* Establish which of the overview levels we already have, and */ /* which are new. We assume that band 1 of the file is */ /* representative. */ /* -------------------------------------------------------------------- */ int nNewOverviews, *panNewOverviewList = NULL; GDALRasterBand *poBand = poDS->GetRasterBand( 1 ); nNewOverviews = 0; panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews); for( i = 0; i < nOverviews && poBand != NULL; i++ ) { int j; for( j = 0; j < poBand->GetOverviewCount(); j++ ) { int nOvFactor; GDALRasterBand * poOverview = poBand->GetOverview( j ); nOvFactor = (int) (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize()); if( nOvFactor == panOverviewList[i] || nOvFactor == GDALOvLevelAdjust( panOverviewList[i], poBand->GetXSize() ) ) panOverviewList[i] *= -1; } if( panOverviewList[i] > 0 ) panNewOverviewList[nNewOverviews++] = panOverviewList[i]; } /* -------------------------------------------------------------------- */ /* Build band list. */ /* -------------------------------------------------------------------- */ pahBands = (GDALRasterBand **) CPLCalloc(sizeof(GDALRasterBand *),nBands); for( i = 0; i < nBands; i++ ) pahBands[i] = poDS->GetRasterBand( panBandList[i] ); /* -------------------------------------------------------------------- */ /* Build new overviews - Imagine. Keep existing file open if */ /* we have it. But mark all overviews as in need of */ /* regeneration, since HFAAuxBuildOverviews() doesn't actually */ /* produce the imagery. */ /* -------------------------------------------------------------------- */ #ifndef WIN32CE if( bOvrIsAux ) { eErr = HFAAuxBuildOverviews( osOvrFilename, poDS, &poODS, nBands, panBandList, nNewOverviews, panNewOverviewList, pszResampling, pfnProgress, pProgressData ); int j; for( j = 0; j < nOverviews; j++ ) { if( panOverviewList[j] > 0 ) panOverviewList[j] *= -1; } } /* -------------------------------------------------------------------- */ /* Build new overviews - TIFF. Close TIFF files while we */ /* operate on it. */ /* -------------------------------------------------------------------- */ else #endif /* WIN32CE */ { if( poODS != NULL ) { delete poODS; poODS = NULL; } eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, pfnProgress, pProgressData ); // Probe for proxy overview filename. if( eErr == CE_Failure ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem("FILENAME","ProxyOverviewRequest"); if( pszProxyOvrFilename != NULL ) { osOvrFilename = pszProxyOvrFilename; eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, pfnProgress, pProgressData ); } } if( eErr == CE_None ) { poODS = (GDALDataset *) GDALOpen( osOvrFilename, GA_Update ); if( poODS == NULL ) eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Refresh old overviews that were listed. */ /* -------------------------------------------------------------------- */ GDALRasterBand **papoOverviewBands; papoOverviewBands = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews); for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { poBand = poDS->GetRasterBand( panBandList[iBand] ); nNewOverviews = 0; for( i = 0; i < nOverviews && poBand != NULL; i++ ) { int j; for( j = 0; j < poBand->GetOverviewCount(); j++ ) { int nOvFactor; GDALRasterBand * poOverview = poBand->GetOverview( j ); int bHasNoData; double noDataValue = poBand->GetNoDataValue(&bHasNoData); if (bHasNoData) poOverview->SetNoDataValue(noDataValue); nOvFactor = (int) (0.5 + poBand->GetXSize() / (double) poOverview->GetXSize()); if( nOvFactor == - panOverviewList[i] || nOvFactor == GDALOvLevelAdjust( -panOverviewList[i], poBand->GetXSize() ) ) { papoOverviewBands[nNewOverviews++] = poOverview; break; } } } if( nNewOverviews > 0 ) { eErr = GDALRegenerateOverviews( (GDALRasterBandH) poBand, nNewOverviews, (GDALRasterBandH*)papoOverviewBands, pszResampling, pfnProgress, pProgressData ); } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( papoOverviewBands ); CPLFree( panNewOverviewList ); CPLFree( pahBands ); /* -------------------------------------------------------------------- */ /* If we have a mask file, we need to build it's overviews */ /* too. */ /* -------------------------------------------------------------------- */ if( HaveMaskFile() && poMaskDS ) { poMaskDS->BuildOverviews( pszResampling, nOverviews, panOverviewList, 0, NULL, pfnProgress, pProgressData ); if( bOwnMaskDS ) GDALClose( poMaskDS ); // force next request to reread mask file. poMaskDS = NULL; bOwnMaskDS = FALSE; bCheckedForMask = FALSE; } /* -------------------------------------------------------------------- */ /* If we have an overview dataset, then mark all the overviews */ /* with the base dataset Used later for finding overviews */ /* masks. Uggg. */ /* -------------------------------------------------------------------- */ if( poODS ) { int nOverviewCount = GetOverviewCount(1); int iOver; for( iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poBand = GetOverview( 1, iOver ); GDALDataset *poOverDS = NULL; if( poBand != NULL ) poOverDS = poBand->GetDataset(); if (poOverDS != NULL) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } return eErr; }