CPLErr PostGISRasterRasterBand::ComputeRasterMinMax( int bApproxOK, double* adfMinMax ) { if( nRasterXSize < 1024 && nRasterYSize < 1024 ) return VRTSourcedRasterBand::ComputeRasterMinMax(bApproxOK, adfMinMax); int nOverviewCount = GetOverviewCount(); for(int i = 0; i < nOverviewCount; i++) { if( GetOverview(i)->GetXSize() < 1024 && GetOverview(i)->GetYSize() < 1024 ) return GetOverview(i)->ComputeRasterMinMax(bApproxOK, adfMinMax); } return CE_Failure; }
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. */ /* -------------------------------------------------------------------- */ if( pszInitName == NULL ) pszInitName = CPLStrdup(poDS->GetDescription()); if( !EQUAL(pszInitName,":::VIRTUAL:::") && GDALCanFileAcceptSidecarFile(pszInitName) ) { if( bInitNameIsOVR ) osOvrFilename = pszInitName; else osOvrFilename.Printf( "%s.ovr", pszInitName ); std::vector<char> achOvrFilename; achOvrFilename.resize(osOvrFilename.size() + 1); memcpy(&(achOvrFilename[0]), osOvrFilename.c_str(), osOvrFilename.size() + 1); bool bExists = CPL_TO_BOOL( CPLCheckForFile( &achOvrFilename[0], papszInitSiblingFiles ) ); osOvrFilename = &achOvrFilename[0]; #if !defined(WIN32) if( !bInitNameIsOVR && !bExists && !papszInitSiblingFiles ) { osOvrFilename.Printf( "%s.OVR", pszInitName ); memcpy(&(achOvrFilename[0]), osOvrFilename.c_str(), osOvrFilename.size() + 1); bExists = CPL_TO_BOOL( CPLCheckForFile( &achOvrFilename[0], papszInitSiblingFiles ) ); osOvrFilename = &achOvrFilename[0]; if( !bExists ) osOvrFilename.Printf( "%s.ovr", pszInitName ); } #endif if( bExists ) { poODS = static_cast<GDALDataset *>( GDALOpenEx( osOvrFilename, GDAL_OF_RASTER | (poDS->GetAccess() == GA_Update ? GDAL_OF_UPDATE : 0), NULL, NULL, papszInitSiblingFiles ) ); } } /* -------------------------------------------------------------------- */ /* 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:::") && GDALCanFileAcceptSidecarFile(pszInitName) ) { bool 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 ) { const bool bUseRRD = CPLTestBool(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 (i.e. proxy) or local */ /* subdataset overview dataset. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem( "OVERVIEW_FILE", "OVERVIEWS" ); if( pszProxyOvrFilename != NULL ) { if( STARTS_WITH_CI(pszProxyOvrFilename, ":::BASE:::") ) { const CPLString osPath = CPLGetPath(poDS->GetDescription()); osOvrFilename = CPLFormFilename( osPath, pszProxyOvrFilename+10, NULL ); } else { osOvrFilename = pszProxyOvrFilename; } CPLPushErrorHandler(CPLQuietErrorHandler); poODS = static_cast<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 ) { const int nOverviewCount = GetOverviewCount(1); for( int iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand * const poBand = GetOverview( 1, iOver ); GDALDataset * const poOverDS = poBand != NULL ? poBand->GetDataset() : NULL; if( poOverDS != NULL ) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } }
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; } } } }
CPLErr JP2LuraRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg* psExtraArg) { JP2LuraDataset *poGDS = reinterpret_cast<JP2LuraDataset *>(poDS); const int nBufTypeSize = GDALGetDataTypeSizeBytes(eBufType); if (eRWFlag != GF_Read) return CE_Failure; #ifdef DEBUG_VERBOSE CPLDebug("JP2Lura", "RasterIO(nBand=%d,nLevel=%d %d,%d,%dx%d -> %dx%d)", nBand, poGDS->iLevel, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize); #endif if( eBufType != eDataType || nPixelSpace != nBufTypeSize || nLineSpace != nPixelSpace * nBufXSize ) { return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); } // Use cached data if( poGDS->sOutputData.nXOff == nXOff && poGDS->sOutputData.nYOff == nYOff && poGDS->sOutputData.nXSize == nXSize && poGDS->sOutputData.nYSize == nYSize && poGDS->sOutputData.nBufXSize == nBufXSize && poGDS->sOutputData.nBufYSize == nBufYSize && poGDS->sOutputData.eBufType == eBufType ) { if (poGDS->sOutputData.pDatacache[nBand - 1] != nullptr) { #ifdef DEBUG_VERBOSE CPLDebug("JP2Lura", "Using cached data"); #endif memcpy(pData, poGDS->sOutputData.pDatacache[nBand - 1], static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize); return CE_None; } } /* ==================================================================== */ /* Do we have overviews that would be appropriate to satisfy */ /* this request? */ /* ==================================================================== */ if ((nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0 && eRWFlag == GF_Read) { int nOverview; GDALRasterIOExtraArg sExtraArg; GDALCopyRasterIOExtraArg(&sExtraArg, psExtraArg); nOverview = GDALBandGetBestOverviewLevel2( this, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, &sExtraArg); if (nOverview >= 0) { GDALRasterBand* poOverviewBand = GetOverview(nOverview); if (poOverviewBand == nullptr) return CE_Failure; return poOverviewBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, &sExtraArg); } } if( nBufXSize != nXSize || nBufYSize != nYSize ) { return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); } JP2_Error error = 0; const short factor = 1 << poGDS->iLevel; JP2_Rect comp_region; comp_region.ulLeft = nXOff; comp_region.ulRight = nXOff + nXSize; comp_region.ulTop = nYOff; comp_region.ulBottom = nYOff + nYSize; error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Scale_Down, factor); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } poGDS->sOutputData.pimage = reinterpret_cast<unsigned char*>(pData); poGDS->sOutputData.nXOff = nXOff; poGDS->sOutputData.nYOff = nYOff; poGDS->sOutputData.nXSize = nXSize; poGDS->sOutputData.nYSize = nYSize; poGDS->sOutputData.nBufXSize = nBufXSize; poGDS->sOutputData.nBufYSize = nBufYSize; poGDS->sOutputData.eBufType = eBufType; poGDS->sOutputData.nBand = nBand; poGDS->sOutputData.nBands = poGDS->nBands; if( poGDS->sOutputData.pDatacache == nullptr ) { poGDS->sOutputData.pDatacache = reinterpret_cast<unsigned char**> (CPLCalloc( poGDS->nBands, sizeof(unsigned char*))); } for (int i = 0; i < poGDS->nBands; i++) { if (poGDS->sOutputData.pDatacache[i] != nullptr) { VSIFree(poGDS->sOutputData.pDatacache[i]); poGDS->sOutputData.pDatacache[i] = nullptr; } if (i == nBand-1) continue; poGDS->sOutputData.pDatacache[i] = reinterpret_cast<unsigned char*>(VSIMalloc( static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize)); } /*++++++++++++++++++++++++++++++++++++++++++++++*/ /* Set the callback function and parameter */ /*++++++++++++++++++++++++++++++++++++++++++++++*/ error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Output_Parameter, reinterpret_cast<JP2_Property_Value>(&(poGDS->sOutputData))); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Output_Function, reinterpret_cast<JP2_Property_Value>( GDALJP2Lura_Callback_Decompress_Write)); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } error = JP2_Decompress_Region(poGDS->sOutputData.handle, comp_region); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error during decompress region (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } return CE_None; }
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; }