static CPLString CPLFindLocalXSD(const char* pszXSDFilename) { CPLString osTmp; const char *pszSchemasOpenGIS = CPLGetConfigOption("GDAL_OPENGIS_SCHEMAS", NULL); if (pszSchemasOpenGIS != NULL) { int nLen = (int)strlen(pszSchemasOpenGIS); if (nLen > 0 && pszSchemasOpenGIS[nLen-1] == '/') { osTmp = pszSchemasOpenGIS; osTmp += pszXSDFilename; } else { osTmp = pszSchemasOpenGIS; osTmp += "/"; osTmp += pszXSDFilename; } } else if ((pszSchemasOpenGIS = CPLFindFile( "gdal", "SCHEMAS_OPENGIS_NET" )) != NULL) { osTmp = pszSchemasOpenGIS; osTmp += "/"; osTmp += pszXSDFilename; } VSIStatBufL sStatBuf; if( VSIStatExL(osTmp, &sStatBuf, VSI_STAT_EXISTS_FLAG) == 0 ) return osTmp; return ""; }
int VSISubFileFilesystemHandler::Stat( const char * pszFilename, VSIStatBufL * psStatBuf, int nFlags ) { CPLString osSubFilePath; vsi_l_offset nOff, nSize; memset( psStatBuf, 0, sizeof(VSIStatBufL) ); if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) ) { errno = ENOENT; return -1; } int nResult = VSIStatExL( osSubFilePath, psStatBuf, nFlags ); if( nResult == 0 ) { if( nSize != 0 ) psStatBuf->st_size = (long)nSize; else psStatBuf->st_size -= (long)nOff; } return nResult; }
int VSISubFileFilesystemHandler::Stat( const char * pszFilename, VSIStatBufL * psStatBuf, int nFlags ) { if( !STARTS_WITH_CI(pszFilename, "/vsisubfile/") ) return -1; CPLString osSubFilePath; vsi_l_offset nOff = 0; vsi_l_offset nSize = 0; memset( psStatBuf, 0, sizeof(VSIStatBufL) ); if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) ) { errno = ENOENT; return -1; } const int nResult = VSIStatExL( osSubFilePath, psStatBuf, nFlags ); if( nResult == 0 ) { if( nSize != 0 ) psStatBuf->st_size = nSize; else psStatBuf->st_size -= nOff; } return nResult; }
int OGROpenFileGDBDataSource::FileExists(const char* pszFilename) { if( m_papszFiles ) return CSLFindString(m_papszFiles, CPLGetFilename(pszFilename)) >= 0; else { VSIStatBufL sStat; return VSIStatExL(pszFilename, &sStat, VSI_STAT_EXISTS_FLAG) == 0; } }
CPLErr GDALDefaultOverviews::BuildOverviewsSubDataset( const char * pszPhysicalFile, const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData) { if( osOvrFilename.length() == 0 && nOverviews > 0 ) { VSIStatBufL sStatBuf; int iSequence = 0; // Used after for. for( iSequence = 0; iSequence < 100; iSequence++ ) { osOvrFilename.Printf( "%s_%d.ovr", pszPhysicalFile, iSequence ); if( VSIStatExL( osOvrFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 ) { CPLString osAdjustedOvrFilename; if( poDS->GetMOFlags() & GMO_PAM_CLASS ) { osAdjustedOvrFilename.Printf( ":::BASE:::%s_%d.ovr", CPLGetFilename(pszPhysicalFile), iSequence ); } else { osAdjustedOvrFilename = osOvrFilename; } poDS->SetMetadataItem( "OVERVIEW_FILE", osAdjustedOvrFilename, "OVERVIEWS" ); break; } } if( iSequence == 100 ) osOvrFilename = ""; } return BuildOverviews( NULL, pszResampling, nOverviews, panOverviewList, nBands, panBandList, pfnProgress, pProgressData ); }
int VSISparseFileFilesystemHandler::Stat( const char * pszFilename, VSIStatBufL * psStatBuf, int nFlags ) { VSIVirtualHandle *poFile = Open( pszFilename, "r" ); memset( psStatBuf, 0, sizeof(VSIStatBufL) ); if( poFile == NULL ) return -1; poFile->Seek( 0, SEEK_END ); size_t nLength = (size_t) poFile->Tell(); delete poFile; int nResult = VSIStatExL( pszFilename + strlen("/vsisparse/"), psStatBuf, nFlags ); psStatBuf->st_size = nLength; return nResult; }
static int OGRSQLiteVFSAccess (sqlite3_vfs* pVFS, const char *zName, int flags, int *pResOut) { #ifdef DEBUG_IO CPLDebug("SQLITE", "OGRSQLiteVFSAccess(%s, %d)", zName, flags); #endif VSIStatBufL sStatBufL; int nRet; if (flags == SQLITE_ACCESS_EXISTS) { /* Do not try to check the presence of a journal on /vsicurl ! */ if ( strncmp(zName, "/vsicurl/", 9) == 0 && strlen(zName) > strlen("-journal") && strcmp(zName + strlen(zName) - strlen("-journal"), "-journal") == 0 ) nRet = -1; else nRet = VSIStatExL(zName, &sStatBufL, VSI_STAT_EXISTS_FLAG); } else if (flags == SQLITE_ACCESS_READ) { VSILFILE* fp = VSIFOpenL(zName, "rb"); nRet = fp ? 0 : -1; if (fp) VSIFCloseL(fp); } else if (flags == SQLITE_ACCESS_READWRITE) { VSILFILE* fp = VSIFOpenL(zName, "rb+"); nRet = fp ? 0 : -1; if (fp) VSIFCloseL(fp); } else nRet = -1; *pResOut = (nRet == 0); return SQLITE_OK; }
CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" ); /* -------------------------------------------------------------------- */ /* Various kinds of metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; CPLSetXMLValue( psTree, "#dataType", GDALGetDataTypeName( GetRasterDataType() ) ); if( nBand > 0 ) CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) ); psMD = oMDMD.Serialize(); if( psMD != NULL ) CPLAddXMLChild( psTree, psMD ); if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( bNoDataValueSet ) { if (CPLIsNan(dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan"); else CPLSetXMLValue( psTree, "NoDataValue", CPLSPrintf( "%.14E", dfNoDataValue ) ); } if( bHideNoDataValue ) CPLSetXMLValue( psTree, "HideNoDataValue", CPLSPrintf( "%d", bHideNoDataValue ) ); if( pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", pszUnitType ); if( dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", CPLSPrintf( "%.16g", dfOffset ) ); if( dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", CPLSPrintf( "%.16g", dfScale ) ); if( eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( eColorInterp ) ); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ ) { CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category", papszCategoryNames[iEntry] ); if( psLastChild == NULL ) psCT_XML->psChild = psNode; else psLastChild->psNext = psNode; psLastChild = psNode; } } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element, "Entry" ); if( psLastChild == NULL ) psCT_XML->psChild = psEntry_XML; else psLastChild->psNext = psEntry_XML; psLastChild = psEntry_XML; poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) ); } } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ for( int iOvr = 0; iOvr < (int)apoOverviews.size(); iOvr ++ ) { CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element, "Overview" ); int bRelativeToVRT; const char *pszRelativePath; VSIStatBufL sStat; if( VSIStatExL( apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 ) { pszRelativePath = apoOverviews[iOvr].osFilename; bRelativeToVRT = FALSE; } else { pszRelativePath = CPLExtractRelativePath( pszVRTPath, apoOverviews[iOvr].osFilename, &bRelativeToVRT ); } CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath ); CPLCreateXMLNode( CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ), CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); CPLSetXMLValue( psOVR_XML, "SourceBand", CPLSPrintf("%d",apoOverviews[iOvr].nBand) ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ if( poMaskBand != NULL ) { CPLXMLNode *psBandTree = poMaskBand->SerializeToXML(pszVRTPath); if( psBandTree != NULL ) { CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element, "MaskBand" ); CPLAddXMLChild( psMaskBandElement, psBandTree ); } } return psTree; }
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; }
int OGRSelafinDataSource::Open(const char * pszFilename, int bUpdateIn, int bCreate) { // Check if a range is set and extract it and the filename const char *pszc=pszFilename; if (*pszFilename==0) return FALSE; while (*pszc) ++pszc; if (*(pszc-1)==']') { --pszc; while (pszc!=pszFilename && *pszc!='[') pszc--; if (pszc==pszFilename) return FALSE; poRange.setRange(pszc); } pszName = CPLStrdup( pszFilename ); pszName[pszc-pszFilename]=0; bUpdate = bUpdateIn; if (bCreate && EQUAL(pszName, "/vsistdout/")) return TRUE; /* For writable /vsizip/, do nothing more */ if (bCreate && STARTS_WITH(pszName, "/vsizip/")) return TRUE; CPLString osFilename(pszName); CPLString osBaseFilename = CPLGetFilename(pszName); // Determine what sort of object this is. VSIStatBufL sStatBuf; if (VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0) return FALSE; // Is this a single Selafin file? if (VSI_ISREG(sStatBuf.st_mode)) return OpenTable( pszName ); // Is this a single a ZIP file with only a Selafin file inside ? if( STARTS_WITH(osFilename, "/vsizip/") && VSI_ISREG(sStatBuf.st_mode) ) { char** papszFiles = VSIReadDir(osFilename); if (CSLCount(papszFiles) != 1) { CSLDestroy(papszFiles); return FALSE; } osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL); CSLDestroy(papszFiles); return OpenTable( osFilename ); } #ifdef notdef // Otherwise it has to be a directory. if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; // Scan through for entries which look like Selafin files int nNotSelafinCount = 0, i; char **papszNames = VSIReadDir( osFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) { nNotSelafinCount++; continue; } if( !OpenTable( oSubFilename ) ) { CPLDebug("Selafin", "Cannot open %s", oSubFilename.c_str()); nNotSelafinCount++; continue; } } CSLDestroy( papszNames ); // We presume that this is indeed intended to be a Selafin datasource if over half the files were Selafin files. return nNotSelafinCount < nLayers; #else return FALSE; #endif }
CPLErr GTIFFBuildOverviews( const char * pszFilename, int nBands, GDALRasterBand **papoBandList, int nOverviews, int * panOverviewList, const char * pszResampling, GDALProgressFunc pfnProgress, void * pProgressData ) { TIFF *hOTIFF; int nBitsPerPixel=0, nCompression=COMPRESSION_NONE, nPhotometric=0; int nSampleFormat=0, nPlanarConfig, iOverview, iBand; int nXSize=0, nYSize=0; if( nBands == 0 || nOverviews == 0 ) return CE_None; if (!GTiffOneTimeInit()) return CE_Failure; /* -------------------------------------------------------------------- */ /* Verify that the list of bands is suitable for emitting in */ /* TIFF file. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < nBands; iBand++ ) { int nBandBits, nBandFormat; GDALRasterBand *hBand = papoBandList[iBand]; switch( hBand->GetRasterDataType() ) { case GDT_Byte: nBandBits = 8; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_UInt16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_UInt32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_Float32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_Float64: nBandBits = 64; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_CInt16: nBandBits = 32; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CInt32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CFloat32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; case GDT_CFloat64: nBandBits = 128; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; default: CPLAssert( FALSE ); return CE_Failure; } if( hBand->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) ) { nBandBits = atoi(hBand->GetMetadataItem("NBITS","IMAGE_STRUCTURE")); if( nBandBits == 1 && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) nBandBits = 8; } if( iBand == 0 ) { nBitsPerPixel = nBandBits; nSampleFormat = nBandFormat; nXSize = hBand->GetXSize(); nYSize = hBand->GetYSize(); } else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } else if( hBand->GetColorTable() != NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of multiple colormapped bands." ); return CE_Failure; } else if( hBand->GetXSize() != nXSize || hBand->GetYSize() != nYSize ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of different sized bands." ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Use specified compression method. */ /* -------------------------------------------------------------------- */ const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", NULL ); if( pszCompress != NULL && pszCompress[0] != '\0' ) { nCompression = GTIFFGetCompressionMethod(pszCompress, "COMPRESS_OVERVIEW"); if (nCompression < 0) return CE_Failure; } if( nCompression == COMPRESSION_JPEG && nBitsPerPixel > 8 ) { if( nBitsPerPixel > 16 ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " JPEG compressed overviews of nBitsPerPixel > 16." ); return CE_Failure; } nBitsPerPixel = 12; } /* -------------------------------------------------------------------- */ /* Figure out the planar configuration to use. */ /* -------------------------------------------------------------------- */ if( nBands == 1 ) nPlanarConfig = PLANARCONFIG_CONTIG; else nPlanarConfig = PLANARCONFIG_SEPARATE; const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", NULL ); if (pszInterleave != NULL && pszInterleave[0] != '\0') { if( EQUAL( pszInterleave, "PIXEL" ) ) nPlanarConfig = PLANARCONFIG_CONTIG; else if( EQUAL( pszInterleave, "BAND" ) ) nPlanarConfig = PLANARCONFIG_SEPARATE; else { CPLError( CE_Failure, CPLE_AppDefined, "INTERLEAVE_OVERVIEW=%s unsupported, value must be PIXEL or BAND. ignoring", pszInterleave ); } } /* -------------------------------------------------------------------- */ /* Figure out the photometric interpretation to use. */ /* -------------------------------------------------------------------- */ if( nBands == 3 ) nPhotometric = PHOTOMETRIC_RGB; else if( papoBandList[0]->GetColorTable() != NULL && !EQUALN(pszResampling,"AVERAGE_BIT2",12) ) { nPhotometric = PHOTOMETRIC_PALETTE; /* should set the colormap up at this point too! */ } else nPhotometric = PHOTOMETRIC_MINISBLACK; const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", NULL ); if (pszPhotometric != NULL && pszPhotometric[0] != '\0') { if( EQUAL( pszPhotometric, "MINISBLACK" ) ) nPhotometric = PHOTOMETRIC_MINISBLACK; else if( EQUAL( pszPhotometric, "MINISWHITE" ) ) nPhotometric = PHOTOMETRIC_MINISWHITE; else if( EQUAL( pszPhotometric, "RGB" )) { nPhotometric = PHOTOMETRIC_RGB; } else if( EQUAL( pszPhotometric, "CMYK" )) { nPhotometric = PHOTOMETRIC_SEPARATED; } else if( EQUAL( pszPhotometric, "YCBCR" )) { nPhotometric = PHOTOMETRIC_YCBCR; /* Because of subsampling, setting YCBCR without JPEG compression leads */ /* to a crash currently. Would need to make GTiffRasterBand::IWriteBlock() */ /* aware of subsampling so that it doesn't overrun buffer size returned */ /* by libtiff */ if ( nCompression != COMPRESSION_JPEG ) { CPLError(CE_Failure, CPLE_NotSupported, "Currently, PHOTOMETRIC_OVERVIEW=YCBCR requires COMPRESS_OVERVIEW=JPEG"); return CE_Failure; } if (pszInterleave != NULL && pszInterleave[0] != '\0' && nPlanarConfig == PLANARCONFIG_SEPARATE) { CPLError(CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires INTERLEAVE_OVERVIEW=PIXEL"); return CE_Failure; } else { nPlanarConfig = PLANARCONFIG_CONTIG; } /* YCBCR strictly requires 3 bands. Not less, not more */ /* Issue an explicit error message as libtiff one is a bit cryptic : */ /* JPEGLib:Bogus input colorspace */ if ( nBands != 3 ) { CPLError(CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires a source raster with only 3 bands (RGB)"); return CE_Failure; } } else if( EQUAL( pszPhotometric, "CIELAB" )) { nPhotometric = PHOTOMETRIC_CIELAB; } else if( EQUAL( pszPhotometric, "ICCLAB" )) { nPhotometric = PHOTOMETRIC_ICCLAB; } else if( EQUAL( pszPhotometric, "ITULAB" )) { nPhotometric = PHOTOMETRIC_ITULAB; } else { CPLError( CE_Warning, CPLE_IllegalArg, "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.\n", pszPhotometric ); } } /* -------------------------------------------------------------------- */ /* Figure out the predictor value to use. */ /* -------------------------------------------------------------------- */ int nPredictor = PREDICTOR_NONE; if ( nCompression == COMPRESSION_LZW || nCompression == COMPRESSION_ADOBE_DEFLATE ) { const char* pszPredictor = CPLGetConfigOption( "PREDICTOR_OVERVIEW", NULL ); if( pszPredictor != NULL ) { nPredictor = atoi( pszPredictor ); } } /* -------------------------------------------------------------------- */ /* Create the file, if it does not already exist. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; VSILFILE* fpL = NULL; if( VSIStatExL( pszFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 ) { /* -------------------------------------------------------------------- */ /* Compute the uncompressed size. */ /* -------------------------------------------------------------------- */ double dfUncompressedOverviewSize = 0; int nDataTypeSize = GDALGetDataTypeSize(papoBandList[0]->GetRasterDataType())/8; for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { int nOXSize, nOYSize; nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; dfUncompressedOverviewSize += nOXSize * ((double)nOYSize) * nBands * nDataTypeSize; } if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { #ifndef BIGTIFF_SUPPORT CPLError( CE_Failure, CPLE_NotSupported, "The overview file would be larger than 4GB\n" "but this is the largest size a TIFF can be, and BigTIFF is unavailable.\n" "Creation failed." ); return CE_Failure; #endif } /* -------------------------------------------------------------------- */ /* Should the file be created as a bigtiff file? */ /* -------------------------------------------------------------------- */ const char *pszBIGTIFF = CPLGetConfigOption( "BIGTIFF_OVERVIEW", NULL ); if( pszBIGTIFF == NULL ) pszBIGTIFF = "IF_NEEDED"; int bCreateBigTIFF = FALSE; if( EQUAL(pszBIGTIFF,"IF_NEEDED") ) { if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) bCreateBigTIFF = TRUE; } else if( EQUAL(pszBIGTIFF,"IF_SAFER") ) { /* Look at the size of the base image and suppose that */ /* the added overview levels won't be more than 1/2 of */ /* the size of the base image. The theory says 1/3 of the */ /* base image size if the overview levels are 2, 4, 8, 16... */ /* Thus take 1/2 as the security margin for 1/3 */ double dfUncompressedImageSize = nXSize * ((double)nYSize) * nBands * nDataTypeSize; if( dfUncompressedImageSize * .5 > 4200000000.0 ) bCreateBigTIFF = TRUE; } else { bCreateBigTIFF = CSLTestBoolean( pszBIGTIFF ); if (!bCreateBigTIFF && nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { CPLError( CE_Failure, CPLE_NotSupported, "The overview file will be larger than 4GB, so BigTIFF is necessary.\n" "Creation failed."); return CE_Failure; } } #ifndef BIGTIFF_SUPPORT if( bCreateBigTIFF ) { CPLError( CE_Warning, CPLE_NotSupported, "BigTIFF requested, but GDAL built without BigTIFF\n" "enabled libtiff, request ignored." ); bCreateBigTIFF = FALSE; } #endif if( bCreateBigTIFF ) CPLDebug( "GTiff", "File being created as a BigTIFF." ); fpL = VSIFOpenL( pszFilename, "w+" ); if( fpL == NULL ) hOTIFF = NULL; else hOTIFF = VSI_TIFFOpen( pszFilename, (bCreateBigTIFF) ? "w+8" : "w+", fpL ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in VSI_TIFFOpen().\n", pszFilename ); if( fpL != NULL ) VSIFCloseL(fpL); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Otherwise just open it for update access. */ /* -------------------------------------------------------------------- */ else { fpL = VSIFOpenL( pszFilename, "r+" ); if( fpL == NULL ) hOTIFF = NULL; else hOTIFF = VSI_TIFFOpen( pszFilename, "r+", fpL ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in VSI_TIFFOpen().\n", pszFilename ); if( fpL != NULL ) VSIFCloseL(fpL); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Do we have a palette? If so, create a TIFF compatible version. */ /* -------------------------------------------------------------------- */ unsigned short *panRed=NULL, *panGreen=NULL, *panBlue=NULL; if( nPhotometric == PHOTOMETRIC_PALETTE ) { GDALColorTable *poCT = papoBandList[0]->GetColorTable(); int nColorCount; if( nBitsPerPixel <= 8 ) nColorCount = 256; else nColorCount = 65536; panRed = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panGreen = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panBlue = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); for( int iColor = 0; iColor < nColorCount; iColor++ ) { GDALColorEntry sRGB; if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) ) { panRed[iColor] = (unsigned short) (257 * sRGB.c1); panGreen[iColor] = (unsigned short) (257 * sRGB.c2); panBlue[iColor] = (unsigned short) (257 * sRGB.c3); } } } /* -------------------------------------------------------------------- */ /* Do we need some metadata for the overviews? */ /* -------------------------------------------------------------------- */ CPLString osMetadata; GDALDataset *poBaseDS = papoBandList[0]->GetDataset(); GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata ); /* -------------------------------------------------------------------- */ /* Loop, creating overviews. */ /* -------------------------------------------------------------------- */ int nOvrBlockXSize, nOvrBlockYSize; GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize); for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { int nOXSize, nOYSize; nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; GTIFFWriteDirectory(hOTIFF, FILETYPE_REDUCEDIMAGE, nOXSize, nOYSize, nBitsPerPixel, nPlanarConfig, nBands, nOvrBlockXSize, nOvrBlockYSize, TRUE, nCompression, nPhotometric, nSampleFormat, nPredictor, panRed, panGreen, panBlue, 0, NULL, /* FIXME? how can we fetch extrasamples */ osMetadata ); } if (panRed) { CPLFree(panRed); CPLFree(panGreen); CPLFree(panBlue); panRed = panGreen = panBlue = NULL; } XTIFFClose( hOTIFF ); VSIFCloseL(fpL); fpL = NULL; /* -------------------------------------------------------------------- */ /* Open the overview dataset so that we can get at the overview */ /* bands. */ /* -------------------------------------------------------------------- */ GDALDataset *hODS; CPLErr eErr = CE_None; hODS = (GDALDataset *) GDALOpen( pszFilename, GA_Update ); if( hODS == NULL ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Do we need to set the jpeg quality? */ /* -------------------------------------------------------------------- */ TIFF *hTIFF = (TIFF*) hODS->GetInternalHandle(NULL); if( nCompression == COMPRESSION_JPEG && CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", NULL ) != NULL ) { int nJpegQuality = atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75")); TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality ); GTIFFSetJpegQuality((GDALDatasetH)hODS, nJpegQuality); } /* -------------------------------------------------------------------- */ /* Loop writing overview data. */ /* -------------------------------------------------------------------- */ if (nCompression != COMPRESSION_NONE && nPlanarConfig == PLANARCONFIG_CONTIG && GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) == FALSE && papoBandList[0]->GetColorTable() == NULL && (EQUALN(pszResampling, "NEAR", 4) || EQUAL(pszResampling, "AVERAGE") || EQUAL(pszResampling, "GAUSS") || EQUAL(pszResampling, "CUBIC") || EQUAL(pszResampling, "CUBICSPLINE") || EQUAL(pszResampling, "LANCZOS") || EQUAL(pszResampling, "BILINEAR"))) { /* In the case of pixel interleaved compressed overviews, we want to generate */ /* the overviews for all the bands block by block, and not band after band, */ /* in order to write the block once and not loose space in the TIFF file */ GDALRasterBand ***papapoOverviewBands; papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands); for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand = hODS->GetRasterBand( iBand+1 ); papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews); papapoOverviewBands[iBand][0] = hDstBand; int bHasNoData; double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData); if (bHasNoData) hDstBand->SetNoDataValue(noDataValue); for( int i = 0; i < nOverviews-1 && eErr == CE_None; i++ ) { papapoOverviewBands[iBand][i+1] = hDstBand->GetOverview(i); if (papapoOverviewBands[iBand][i+1] == NULL) eErr = CE_Failure; else { if (bHasNoData) papapoOverviewBands[iBand][i+1]->SetNoDataValue(noDataValue); } } } if (eErr == CE_None) eErr = GDALRegenerateOverviewsMultiBand(nBands, papoBandList, nOverviews, papapoOverviewBands, pszResampling, pfnProgress, pProgressData ); for( iBand = 0; iBand < nBands; iBand++ ) { CPLFree(papapoOverviewBands[iBand]); } CPLFree(papapoOverviewBands); } else { GDALRasterBand **papoOverviews; papoOverviews = (GDALRasterBand **) CPLCalloc(sizeof(void*),128); for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand; int nDstOverviews; hDstBand = hODS->GetRasterBand( iBand+1 ); int bHasNoData; double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData); if (bHasNoData) hDstBand->SetNoDataValue(noDataValue); papoOverviews[0] = hDstBand; nDstOverviews = hDstBand->GetOverviewCount() + 1; CPLAssert( nDstOverviews < 128 ); nDstOverviews = MIN(128,nDstOverviews); for( int i = 0; i < nDstOverviews-1 && eErr == CE_None; i++ ) { papoOverviews[i+1] = hDstBand->GetOverview(i); if (papoOverviews[i+1] == NULL) eErr = CE_Failure; else { if (bHasNoData) papoOverviews[i+1]->SetNoDataValue(noDataValue); } } void *pScaledProgressData; pScaledProgressData = GDALCreateScaledProgress( iBand / (double) nBands, (iBand+1) / (double) nBands, pfnProgress, pProgressData ); if (eErr == CE_None) eErr = GDALRegenerateOverviews( (GDALRasterBandH) hSrcBand, nDstOverviews, (GDALRasterBandH *) papoOverviews, pszResampling, GDALScaledProgress, pScaledProgressData); GDALDestroyScaledProgress( pScaledProgressData ); } CPLFree( papoOverviews ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) hODS->FlushCache(); delete hODS; pfnProgress( 1.0, NULL, pProgressData ); return eErr; }
int OGRTigerDataSource::Open( const char * pszFilename, int bTestOpen, char ** papszLimitedFileList ) { pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ VSIStatBufL stat; if( VSIStatExL( pszFilename, &stat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s is neither a file or directory, Tiger access failed.\n", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are Tiger files. */ /* -------------------------------------------------------------------- */ char **papszFileList = nullptr; if( VSI_ISREG(stat.st_mode) ) { char szModule[128]; if( strlen(CPLGetFilename(pszFilename)) == 0 ) { return FALSE; } pszPath = CPLStrdup( CPLGetPath(pszFilename) ); strncpy( szModule, CPLGetFilename(pszFilename), sizeof(szModule)-1 ); /* Make sure the buffer is 0 terminated */ szModule[sizeof(szModule)-1] = '\0'; /* And now remove last character of filename */ szModule[strlen(szModule)-1] = '\0'; papszFileList = CSLAddString( papszFileList, szModule ); } else { char **candidateFileList = VSIReadDir( pszFilename ); pszPath = CPLStrdup( pszFilename ); for( int i = 0; candidateFileList != nullptr && candidateFileList[i] != nullptr; i++ ) { size_t nCandidateLen = strlen(candidateFileList[i]); if( papszLimitedFileList != nullptr && CSLFindString(papszLimitedFileList, CPLGetBasename(candidateFileList[i])) == -1 ) { continue; } if( nCandidateLen > 4 && candidateFileList[i][nCandidateLen-4] == '.' && candidateFileList[i][nCandidateLen-1] == '1') { char szModule[128]; snprintf( szModule, sizeof(szModule), "%s", candidateFileList[i] ); const size_t nLen = strlen(szModule); if( nLen ) szModule[nLen-1] = '\0'; papszFileList = CSLAddString(papszFileList, szModule); } } CSLDestroy( candidateFileList ); if( CSLCount(papszFileList) == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No candidate Tiger files (TGR*.RT1) found in\n" "directory: %s", pszFilename ); CSLDestroy(papszFileList); return FALSE; } } /* -------------------------------------------------------------------- */ /* Loop over all these files trying to open them. In testopen */ /* mode we first read the first 80 characters, to verify that */ /* it looks like an Tiger file. Note that we don't keep the file */ /* open ... we don't want to occupy a lot of file handles when */ /* handling a whole directory. */ /* -------------------------------------------------------------------- */ papszModules = nullptr; for( int i = 0; papszFileList && papszFileList[i] != nullptr; i++ ) { if( bTestOpen || i == 0 ) { char *l_pszFilename = BuildFilename( papszFileList[i], "1" ); VSILFILE *fp = VSIFOpenL( l_pszFilename, "rb" ); CPLFree( l_pszFilename ); if( fp == nullptr ) continue; char szHeader[500] = {}; if( VSIFReadL( szHeader, sizeof(szHeader)-1, 1, fp ) < 1 ) { VSIFCloseL( fp ); continue; } VSIFCloseL( fp ); char *pszRecStart = szHeader; szHeader[sizeof(szHeader)-1] = '\0'; bool bIsGDT = false; if( STARTS_WITH_CI(pszRecStart, "Copyright (C)") && strstr(pszRecStart,"Geographic Data Tech") != nullptr ) { bIsGDT = true; while( *pszRecStart != '\0' && *pszRecStart != 10 && *pszRecStart != 13 ) pszRecStart++; while( *pszRecStart == 10 || *pszRecStart == 13 ) pszRecStart++; } if( pszRecStart[0] != '1' ) continue; if( !isdigit(pszRecStart[1]) || !isdigit(pszRecStart[2]) || !isdigit(pszRecStart[3]) || !isdigit(pszRecStart[4]) ) continue; nVersionCode = atoi(TigerFileBase::GetField( pszRecStart, 2, 5 )); nVersion = TigerClassifyVersion( nVersionCode ); nVersion = TigerCheckVersion( nVersion, papszFileList[i] ); CPLDebug( "OGR", "Tiger Version Code=%d, Classified as %s ", nVersionCode, TigerVersionString(nVersion) ); if( nVersionCode != 0 && nVersionCode != 2 && nVersionCode != 3 && nVersionCode != 5 && nVersionCode != 21 && nVersionCode != 24 && pszRecStart[3] != '9' && pszRecStart[3] != DIGIT_ZERO && !bIsGDT ) continue; // we could (and should) add a bunch more validation here. } papszModules = CSLAddString( papszModules, papszFileList[i] ); } CSLDestroy( papszFileList ); nModules = CSLCount( papszModules ); if( nModules == 0 || papszModules == nullptr ) { if( !bTestOpen ) { if( VSI_ISREG(stat.st_mode) ) CPLError( CE_Failure, CPLE_OpenFailed, "No TIGER/Line files (TGR*.RT1) found in\n" "directory: %s", pszFilename ); else CPLError( CE_Failure, CPLE_OpenFailed, "File %s does not appear to be a TIGER/Line .RT1 file.", pszFilename ); } return FALSE; } /* -------------------------------------------------------------------- */ /* Do we have a user provided version override? */ /* -------------------------------------------------------------------- */ const char *pszRequestedVersion = CPLGetConfigOption( "TIGER_VERSION", nullptr ); if( pszRequestedVersion != nullptr ) { if( STARTS_WITH_CI(pszRequestedVersion, "TIGER_") ) { int iCode = 1; // Used after for. for( ; iCode < TIGER_Unknown; iCode++ ) { if( EQUAL(TigerVersionString((TigerVersion)iCode), pszRequestedVersion) ) { nVersion = (TigerVersion) iCode; break; } } if( iCode == TIGER_Unknown ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to recognise TIGER_VERSION setting: %s", pszRequestedVersion ); return FALSE; } CPLDebug( "OGR", "OVERRIDE Tiger Version %s ", TigerVersionString(nVersion) ); } else { nVersionCode = atoi(pszRequestedVersion); nVersion = TigerClassifyVersion( nVersionCode ); CPLDebug( "OGR", "OVERRIDE Tiger Version Code=%d, Classified as %s ", nVersionCode, TigerVersionString(nVersion) ); } } /* -------------------------------------------------------------------- */ /* Create the layers which appear to exist. */ /* -------------------------------------------------------------------- */ // RT1, RT2, RT3 AddLayer( new OGRTigerLayer( this, new TigerCompleteChain( this, papszModules[0]) )); /* should we have kept track of whether we encountered an RT4 file? */ // RT4 AddLayer( new OGRTigerLayer( this, new TigerAltName( this, papszModules[0]) )); // RT5 AddLayer( new OGRTigerLayer( this, new TigerFeatureIds( this, papszModules[0]) )); // RT6 AddLayer( new OGRTigerLayer( this, new TigerZipCodes( this, papszModules[0]) )); // RT7 AddLayer( new OGRTigerLayer( this, new TigerLandmarks( this, papszModules[0]) )); // RT8 AddLayer( new OGRTigerLayer( this, new TigerAreaLandmarks( this, papszModules[0]) )); // RT9 if (nVersion < TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerKeyFeatures( this, papszModules[0]) )); } // RTA, RTS AddLayer( new OGRTigerLayer( this, new TigerPolygon( this, papszModules[0]) )); // RTB if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerPolygonCorrections( this, papszModules[0]) )); } // RTC AddLayer( new OGRTigerLayer( this, new TigerEntityNames( this, papszModules[0]) )); // RTE if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerPolygonEconomic( this, papszModules[0]) )); } // RTH AddLayer( new OGRTigerLayer( this, new TigerIDHistory( this, papszModules[0]) )); // RTI AddLayer( new OGRTigerLayer( this, new TigerPolyChainLink( this, papszModules[0]) )); // RTM AddLayer( new OGRTigerLayer( this, new TigerSpatialMetadata( this, papszModules[0] ) ) ); // RTP AddLayer( new OGRTigerLayer( this, new TigerPIP( this, papszModules[0]) )); // RTR AddLayer( new OGRTigerLayer( this, new TigerTLIDRange( this, papszModules[0]) )); // RTT if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerZeroCellID( this, papszModules[0]) )); } // RTU if (nVersion >= TIGER_2002) { AddLayer( new OGRTigerLayer( this, new TigerOverUnder( this, papszModules[0]) )); } // RTZ AddLayer( new OGRTigerLayer( this, new TigerZipPlus4( this, papszModules[0]) )); return TRUE; }
const char *CPLFormCIFilename( const char * pszPath, const char * pszBasename, const char * pszExtension ) { // On case insensitive filesystems, just default to // CPLFormFilename() if( !VSIIsCaseSensitiveFS(pszPath) ) return CPLFormFilename( pszPath, pszBasename, pszExtension ); const char *pszAddedExtSep = ""; char *pszFilename; const char *pszFullPath; int nLen = strlen(pszBasename)+2, i; VSIStatBufL sStatBuf; int nStatRet; if( pszExtension != NULL ) nLen += strlen(pszExtension); pszFilename = (char *) CPLMalloc(nLen); if( pszExtension == NULL ) pszExtension = ""; else if( pszExtension[0] != '.' && strlen(pszExtension) > 0 ) pszAddedExtSep = "."; sprintf( pszFilename, "%s%s%s", pszBasename, pszAddedExtSep, pszExtension ); pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); if( nStatRet != 0 ) { for( i = 0; pszFilename[i] != '\0'; i++ ) { if( islower(pszFilename[i]) ) pszFilename[i] = (char) toupper(pszFilename[i]); } pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); } if( nStatRet != 0 ) { for( i = 0; pszFilename[i] != '\0'; i++ ) { if( isupper(pszFilename[i]) ) pszFilename[i] = (char) tolower(pszFilename[i]); } pszFullPath = CPLFormFilename( pszPath, pszFilename, NULL ); nStatRet = VSIStatExL( pszFullPath, &sStatBuf, VSI_STAT_EXISTS_FLAG ); } if( nStatRet != 0 ) pszFullPath = CPLFormFilename( pszPath, pszBasename, pszExtension ); CPLFree( pszFilename ); return pszFullPath; }
GDALDataset *RDataset::Open( GDALOpenInfo * poOpenInfo ) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if( poOpenInfo->pabyHeader == nullptr ) return nullptr; #else // During fuzzing, do not use Identify to reject crazy content. if( !Identify(poOpenInfo) ) return nullptr; #endif // Confirm the requested access is supported. if( poOpenInfo->eAccess == GA_Update ) { CPLError(CE_Failure, CPLE_NotSupported, "The R driver does not support update access to existing" " datasets."); return nullptr; } // Do we need to route the file through the decompression machinery? const bool bCompressed = memcmp(poOpenInfo->pabyHeader, "\037\213\b", 3) == 0; const CPLString osAdjustedFilename = std::string(bCompressed ? "/vsigzip/" : "") + poOpenInfo->pszFilename; // Establish this as a dataset and open the file using VSI*L. RDataset *poDS = new RDataset(); poDS->fp = VSIFOpenL(osAdjustedFilename, "r"); if( poDS->fp == nullptr ) { delete poDS; return nullptr; } poDS->bASCII = STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader), "RDA2\nA\n"); // Confirm this is a version 2 file. VSIFSeekL(poDS->fp, 7, SEEK_SET); if( poDS->ReadInteger() != R_LISTSXP ) { delete poDS; CPLError(CE_Failure, CPLE_OpenFailed, "It appears %s is not a version 2 R object file after all!", poOpenInfo->pszFilename); return nullptr; } // Skip the version values. poDS->ReadInteger(); poDS->ReadInteger(); // Confirm we have a numeric vector object in a pairlist. CPLString osObjName; int nObjCode = 0; if( !poDS->ReadPair(osObjName, nObjCode) ) { delete poDS; return nullptr; } if( nObjCode % 256 != R_REALSXP ) { delete poDS; CPLError(CE_Failure, CPLE_OpenFailed, "Failed to find expected numeric vector object."); return nullptr; } poDS->SetMetadataItem("R_OBJECT_NAME", osObjName); // Read the count. const int nValueCount = poDS->ReadInteger(); if( nValueCount < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "nValueCount < 0: %d", nValueCount); delete poDS; return nullptr; } poDS->nStartOfData = VSIFTellL(poDS->fp); // TODO(schwehr): Factor in the size of doubles. VSIStatBufL stat; const int dStatSuccess = VSIStatExL(osAdjustedFilename, &stat, VSI_STAT_SIZE_FLAG); if( dStatSuccess != 0 || static_cast<vsi_l_offset>(nValueCount) > stat.st_size - poDS->nStartOfData ) { CPLError( CE_Failure, CPLE_AppDefined, "Corrupt file. " "Object claims to be larger than available bytes. " "%d > " CPL_FRMT_GUIB, nValueCount, stat.st_size - poDS->nStartOfData); delete poDS; return nullptr; } // Read/Skip ahead to attributes. if( poDS->bASCII ) { poDS->padfMatrixValues = static_cast<double *>(VSIMalloc2(nValueCount, sizeof(double))); if (poDS->padfMatrixValues == nullptr) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d doubles", nValueCount); delete poDS; return nullptr; } for( int iValue = 0; iValue < nValueCount; iValue++ ) poDS->padfMatrixValues[iValue] = poDS->ReadFloat(); } else { VSIFSeekL(poDS->fp, 8 * nValueCount, SEEK_CUR); } // Read pairs till we run out, trying to find a few items that // have special meaning to us. poDS->nRasterXSize = 0; poDS->nRasterYSize = 0; int nBandCount = 0; while( poDS->ReadPair(osObjName, nObjCode) && nObjCode != 254 ) { if( osObjName == "dim" && nObjCode % 256 == R_INTSXP ) { const int nCount = poDS->ReadInteger(); if( nCount == 2 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = 1; } else if( nCount == 3 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = poDS->ReadInteger(); } else { CPLError(CE_Failure, CPLE_AppDefined, "R 'dim' dimension wrong."); delete poDS; return nullptr; } } else if( nObjCode % 256 == R_REALSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadFloat(); } } else if( nObjCode % 256 == R_INTSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadInteger(); } } else if( nObjCode % 256 == R_STRSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadString(); } } else if( nObjCode % 256 == R_CHARSXP ) { poDS->ReadString(); } } if( poDS->nRasterXSize == 0 ) { delete poDS; CPLError(CE_Failure, CPLE_AppDefined, "Failed to find dim dimension information for R dataset."); return nullptr; } if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBandCount, TRUE)) { delete poDS; return nullptr; } GIntBig result = 0; bool ok = SafeMult(nBandCount, poDS->nRasterXSize, &result); ok &= SafeMult(result, poDS->nRasterYSize, &result); if( !ok || nValueCount < result ) { CPLError(CE_Failure, CPLE_AppDefined, "Not enough pixel data."); delete poDS; return nullptr; } // Create the raster band object(s). for( int iBand = 0; iBand < nBandCount; iBand++ ) { GDALRasterBand *poBand = nullptr; if( poDS->bASCII ) poBand = new RRasterBand( poDS, iBand + 1, poDS->padfMatrixValues + iBand * poDS->nRasterXSize * poDS->nRasterYSize); else poBand = new RawRasterBand( poDS, iBand + 1, poDS->fp, poDS->nStartOfData + poDS->nRasterXSize * poDS->nRasterYSize * 8 * iBand, 8, poDS->nRasterXSize * 8, GDT_Float64, !CPL_IS_LSB, TRUE, FALSE); poDS->SetBand(iBand + 1, poBand); } // Initialize any PAM information. poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); // Check for overviews. poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); return poDS; }
int main( int argc, char ** argv ) { GDALDatasetH *pahSrcDS = NULL; int nSrcCount = 0; int i; /* Check that we are running against at least GDAL 1.6 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1600) { fprintf(stderr, "At least, GDAL >= 1.6.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); GDALExit(1); } EarlySetConfigOptions(argc, argv); /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) GDALExit( -argc ); for( int i = 0; argv != NULL && argv[i] != NULL; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[i],"--help") ) { Usage(NULL); } } /* -------------------------------------------------------------------- */ /* Set optimal setting for best performance with huge input VRT. */ /* The rationale for 450 is that typical Linux process allow */ /* only 1024 file descriptors per process and we need to keep some */ /* spare for shared libraries, etc. so let's go down to 900. */ /* And some datasets may need 2 file descriptors, so divide by 2 */ /* for security. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", NULL) == NULL ) { CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "450"); } GDALWarpAppOptionsForBinary* psOptionsForBinary = GDALWarpAppOptionsForBinaryNew(); GDALWarpAppOptions *psOptions = GDALWarpAppOptionsNew(argv + 1, psOptionsForBinary); CSLDestroy( argv ); if( psOptions == NULL ) { Usage(NULL); } if( psOptionsForBinary->pszDstFilename == NULL ) { Usage("No target filename specified."); } if ( CSLCount(psOptionsForBinary->papszSrcFiles) == 1 && strcmp(psOptionsForBinary->papszSrcFiles[0], psOptionsForBinary->pszDstFilename) == 0 && psOptionsForBinary->bOverwrite) { CPLError(CE_Failure, CPLE_IllegalArg, "Source and destination datasets must be different.\n"); GDALExit(1); } /* -------------------------------------------------------------------- */ /* Open Source files. */ /* -------------------------------------------------------------------- */ for(i = 0; psOptionsForBinary->papszSrcFiles[i] != NULL; i++) { nSrcCount++; pahSrcDS = (GDALDatasetH *) CPLRealloc(pahSrcDS, sizeof(GDALDatasetH) * nSrcCount); pahSrcDS[nSrcCount-1] = GDALOpenEx( psOptionsForBinary->papszSrcFiles[i], GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, NULL, (const char* const* )psOptionsForBinary->papszOpenOptions, NULL ); if( pahSrcDS[nSrcCount-1] == NULL ) GDALExit(2); } /* -------------------------------------------------------------------- */ /* Does the output dataset already exist? */ /* -------------------------------------------------------------------- */ /* FIXME ? source filename=target filename and -overwrite is definitely */ /* an error. But I can't imagine of a valid case (without -overwrite), */ /* where it would make sense. In doubt, let's keep that dubious possibility... */ int bOutStreaming = FALSE; if( strcmp(psOptionsForBinary->pszDstFilename, "/vsistdout/") == 0 ) { psOptionsForBinary->bQuiet = TRUE; bOutStreaming = TRUE; } #ifdef S_ISFIFO else { VSIStatBufL sStat; if( VSIStatExL(psOptionsForBinary->pszDstFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG) == 0 && S_ISFIFO(sStat.st_mode) ) { bOutStreaming = TRUE; } } #endif GDALDatasetH hDstDS = NULL; if( bOutStreaming ) { GDALWarpAppOptionsSetWarpOption(psOptions, "STREAMABLE_OUTPUT", "YES"); } else { CPLPushErrorHandler( CPLQuietErrorHandler ); hDstDS = GDALOpenEx( psOptionsForBinary->pszDstFilename, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR | GDAL_OF_UPDATE, NULL, psOptionsForBinary->papszDestOpenOptions, NULL ); CPLPopErrorHandler(); } if( hDstDS != NULL && psOptionsForBinary->bOverwrite ) { GDALClose(hDstDS); hDstDS = NULL; } if( hDstDS != NULL && psOptionsForBinary->bCreateOutput ) { CPLError( CE_Failure, CPLE_AppDefined, "Output dataset %s exists,\n" "but some commandline options were provided indicating a new dataset\n" "should be created. Please delete existing dataset and run again.\n", psOptionsForBinary->pszDstFilename ); GDALExit(1); } /* Avoid overwriting an existing destination file that cannot be opened in */ /* update mode with a new GTiff file */ if ( !bOutStreaming && hDstDS == NULL && !psOptionsForBinary->bOverwrite ) { CPLPushErrorHandler( CPLQuietErrorHandler ); hDstDS = GDALOpen( psOptionsForBinary->pszDstFilename, GA_ReadOnly ); CPLPopErrorHandler(); if (hDstDS) { CPLError( CE_Failure, CPLE_AppDefined, "Output dataset %s exists, but cannot be opened in update mode\n", psOptionsForBinary->pszDstFilename ); GDALClose(hDstDS); GDALExit(1); } } if( !(psOptionsForBinary->bQuiet) ) { GDALWarpAppOptionsSetProgress(psOptions, GDALTermProgress, NULL); } if (hDstDS == NULL && !psOptionsForBinary->bQuiet && !psOptionsForBinary->bFormatExplicitlySet) CheckExtensionConsistency(psOptionsForBinary->pszDstFilename, psOptionsForBinary->pszFormat); int bUsageError = FALSE; GDALDatasetH hOutDS = GDALWarp(psOptionsForBinary->pszDstFilename, hDstDS, nSrcCount, pahSrcDS, psOptions, &bUsageError); if( bUsageError ) Usage(); int nRetCode = (hOutDS) ? 0 : 1; GDALWarpAppOptionsFree(psOptions); GDALWarpAppOptionsForBinaryFree(psOptionsForBinary); for(i = 0; i < nSrcCount; i++) { GDALClose(pahSrcDS[i]); } CPLFree(pahSrcDS); GDALClose( hOutDS ? hOutDS : hDstDS ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); #ifdef OGR_ENABLED OGRCleanupAll(); #endif return nRetCode; }
int OGRShapeDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen, int bForceSingleFileDataSource ) { VSIStatBufL stat; CPLAssert( nLayers == 0 ); pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; bSingleFileDataSource = bForceSingleFileDataSource; /* -------------------------------------------------------------------- */ /* If bSingleFileDataSource is TRUE we don't try to do anything else. */ /* This is only utilized when the OGRShapeDriver::Create() */ /* method wants to create a stub OGRShapeDataSource for a */ /* single shapefile. The driver will take care of creating the */ /* file by calling CreateLayer(). */ /* -------------------------------------------------------------------- */ if( bSingleFileDataSource ) return TRUE; /* -------------------------------------------------------------------- */ /* Is the given path a directory or a regular file? */ /* -------------------------------------------------------------------- */ if( VSIStatExL( pszNewName, &stat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s is neither a file or directory, Shape access failed.\n", pszNewName ); return FALSE; } /* -------------------------------------------------------------------- */ /* Build a list of filenames we figure are Shape files. */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { if( !OpenFile( pszNewName, bUpdate, bTestOpen ) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open shapefile %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszNewName ); return FALSE; } bSingleFileDataSource = TRUE; return TRUE; } else { char **papszCandidates = CPLReadDir( pszNewName ); int iCan, nCandidateCount = CSLCount( papszCandidates ); int bMightBeOldCoverage = FALSE; for( iCan = 0; iCan < nCandidateCount; iCan++ ) { char *pszFilename; const char *pszCandidate = papszCandidates[iCan]; if( EQUAL(pszCandidate,"ARC") ) bMightBeOldCoverage = TRUE; if( strlen(pszCandidate) < 4 || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".shp") ) continue; pszFilename = CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL)); if( !OpenFile( pszFilename, bUpdate, bTestOpen ) && !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open shapefile %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszFilename ); CPLFree( pszFilename ); return FALSE; } CPLFree( pszFilename ); } // Try and .dbf files without apparent associated shapefiles. for( iCan = 0; iCan < nCandidateCount; iCan++ ) { char *pszFilename; const char *pszCandidate = papszCandidates[iCan]; const char *pszLayerName; int iLayer, bGotAlready = FALSE; // We don't consume .dbf files in a directory that looks like // an old style Arc/Info (for PC?) that unless we found at least // some shapefiles. See Bug 493. if( bMightBeOldCoverage && nLayers == 0 ) continue; if( strlen(pszCandidate) < 4 || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".dbf") ) continue; pszLayerName = CPLGetBasename(pszCandidate); for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName, GetLayer(iLayer)->GetLayerDefn()->GetName()) ) bGotAlready = TRUE; } if( bGotAlready ) continue; // We don't want to access .dbf files with an associated .tab // file, or it will never get recognised as a mapinfo dataset. int iCan2, bFoundTAB = FALSE; for( iCan2 = 0; iCan2 < nCandidateCount; iCan2++ ) { const char *pszCandidate2 = papszCandidates[iCan2]; if( EQUALN(pszCandidate2,pszLayerName,strlen(pszLayerName)) && EQUAL(pszCandidate2 + strlen(pszLayerName), ".tab") ) bFoundTAB = TRUE; } if( bFoundTAB ) continue; pszFilename = CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL)); if( !OpenFile( pszFilename, bUpdate, bTestOpen ) && !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open dbf file %s.\n" "It may be corrupt or read-only file accessed in update mode.\n", pszFilename ); CPLFree( pszFilename ); return FALSE; } CPLFree( pszFilename ); } CSLDestroy( papszCandidates ); if( !bTestOpen && nLayers == 0 && !bUpdate ) { CPLError( CE_Failure, CPLE_OpenFailed, "No Shapefiles found in directory %s\n", pszNewName ); } } return nLayers > 0 || bUpdate; }
int VSIStatL( const char * pszFilename, VSIStatBufL *psStatBuf ) { return VSIStatExL(pszFilename, psStatBuf, 0); }
GDALOpenInfo::GDALOpenInfo(const char *pszFilenameIn, GDALAccess eAccessIn, char **papszSiblingsIn) { /* -------------------------------------------------------------------- */ /* Ensure that C: is treated as C:\ so we can stat it on */ /* Windows. Similar to what is done in CPLStat(). */ /* -------------------------------------------------------------------- */ #ifdef WIN32 if (strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':') { char szAltPath[10]; strcpy(szAltPath, pszFilenameIn); strcat(szAltPath, "\\"); pszFilename = CPLStrdup(szAltPath); } else #endif pszFilename = CPLStrdup(pszFilenameIn); /* -------------------------------------------------------------------- */ /* Initialize. */ /* -------------------------------------------------------------------- */ nHeaderBytes = 0; pabyHeader = NULL; bIsDirectory = FALSE; bStatOK = FALSE; eAccess = eAccessIn; fp = NULL; #ifdef HAVE_READLINK int bHasRetried = FALSE; #endif /* -------------------------------------------------------------------- */ /* Collect information about the file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStat; #ifdef HAVE_READLINK retry: #endif if (VSIStatExL(pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG) == 0) { bStatOK = TRUE; if (VSI_ISREG(sStat.st_mode)) { pabyHeader = (GByte*) CPLCalloc(1025, 1); fp = VSIFOpen(pszFilename, "rb"); if (fp != NULL) { nHeaderBytes = (int) VSIFRead(pabyHeader, 1, 1024, fp); VSIRewind(fp); } /* XXX: ENOENT is used to catch the case of virtual filesystem * when we do not have a real file with such a name. Under some * circumstances EINVAL reported instead of ENOENT in Windows * (for filenames containing colon, e.g. "smth://name"). * See also: #2437 */ else if (errno == 27 /* "File to large" */ || errno == ENOENT || errno == EINVAL #ifdef EOVERFLOW || errno == EOVERFLOW #else || errno == 75 /* Linux EOVERFLOW */ || errno == 79 /* Solaris EOVERFLOW */ #endif ) { VSILFILE *fpL = VSIFOpenL(pszFilename, "rb"); if (fpL != NULL) { nHeaderBytes = (int) VSIFReadL(pabyHeader, 1, 1024, fpL); VSIFCloseL(fpL); } } } else if (VSI_ISDIR(sStat.st_mode)) bIsDirectory = TRUE; } #ifdef HAVE_READLINK else if (!bHasRetried) { /* If someone creates a file with "ln -sf /vsicurl/http://download.osgeo.org/gdal/data/gtiff/utm.tif my_remote_utm.tif" */ /* we will be able to open it by passing my_remote_utm.tif */ /* This helps a lot for GDAL based readers that only provide file explorers to open datasets */ char szPointerFilename[2048]; int nBytes = readlink(pszFilename, szPointerFilename, sizeof(szPointerFilename)); if (nBytes != -1) { szPointerFilename[MIN(nBytes, (int)sizeof(szPointerFilename) - 1)] = 0; CPLFree(pszFilename); pszFilename = CPLStrdup(szPointerFilename); papszSiblingsIn = NULL; bHasRetried = TRUE; goto retry; } } #endif /* -------------------------------------------------------------------- */ /* Capture sibling list either from passed in values, or by */ /* scanning for them. */ /* -------------------------------------------------------------------- */ if (papszSiblingsIn != NULL) { papszSiblingFiles = CSLDuplicate(papszSiblingsIn); } else if (bStatOK && !bIsDirectory) { const char *pszOptionVal = CPLGetConfigOption("GDAL_DISABLE_READDIR_ON_OPEN", "NO"); if (EQUAL(pszOptionVal, "EMPTY_DIR")) { papszSiblingFiles = CSLAddString(NULL, CPLGetFilename(pszFilename)); } else if (CSLTestBoolean(pszOptionVal)) { /* skip reading the directory */ papszSiblingFiles = NULL; } else { CPLString osDir = CPLGetDirname(pszFilename); papszSiblingFiles = VSIReadDir(osDir); } } else papszSiblingFiles = NULL; }
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate, int bTestOpen ) { SHPHandle hSHP; DBFHandle hDBF; const char *pszExtension = CPLGetExtension( pszNewName ); (void) bTestOpen; if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx") && !EQUAL(pszExtension,"dbf") ) return FALSE; /* -------------------------------------------------------------------- */ /* SHPOpen() should include better (CPL based) error reporting, */ /* and we should be trying to distinquish at this point whether */ /* failure is a result of trying to open a non-shapefile, or */ /* whether it was a shapefile and we want to report the error */ /* up. */ /* */ /* Care is taken to suppress the error and only reissue it if */ /* we think it is appropriate. */ /* -------------------------------------------------------------------- */ CPLPushErrorHandler( CPLQuietErrorHandler ); if( bUpdate ) hSHP = DS_SHPOpen( pszNewName, "r+" ); else hSHP = DS_SHPOpen( pszNewName, "r" ); CPLPopErrorHandler(); if( hSHP == NULL && (!EQUAL(CPLGetExtension(pszNewName),"dbf") || strstr(CPLGetLastErrorMsg(),".shp") == NULL) ) { CPLString osMsg = CPLGetLastErrorMsg(); CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() ); return FALSE; } CPLErrorReset(); /* -------------------------------------------------------------------- */ /* Open the .dbf file, if it exists. To open a dbf file, the */ /* filename has to either refer to a successfully opened shp */ /* file or has to refer to the actual .dbf file. */ /* -------------------------------------------------------------------- */ if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") ) { if( bUpdate ) { hDBF = DS_DBFOpen( pszNewName, "r+" ); if( hSHP != NULL && hDBF == NULL ) { for(int i=0;i<2;i++) { VSIStatBufL sStat; const char* pszDBFName = CPLResetExtension(pszNewName, (i == 0 ) ? "dbf" : "DBF"); VSILFILE* fp = NULL; if( VSIStatExL( pszDBFName, &sStat, VSI_STAT_EXISTS_FLAG) == 0 ) { fp = VSIFOpenL(pszDBFName, "r+"); if (fp == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "%s exists, but cannot be opened in update mode", pszDBFName ); SHPClose(hSHP); return FALSE; } VSIFCloseL(fp); break; } } } } else hDBF = DS_DBFOpen( pszNewName, "r" ); } else hDBF = NULL; if( hDBF == NULL && hSHP == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer; poLayer = new OGRShapeLayer( this, pszNewName, hSHP, hDBF, NULL, FALSE, bUpdate, wkbNone ); poLayer->SetModificationDate( CSLFetchNameValue( papszOpenOptions, "DBF_DATE_LAST_UPDATE" ) ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ AddLayer(poLayer); return TRUE; }
CPLErr GTIFFBuildOverviews( const char * pszFilename, int nBands, GDALRasterBand **papoBandList, int nOverviews, int * panOverviewList, const char * pszResampling, GDALProgressFunc pfnProgress, void * pProgressData ) { if( nBands == 0 || nOverviews == 0 ) return CE_None; if( !GTiffOneTimeInit() ) return CE_Failure; TIFF *hOTIFF = nullptr; int nBitsPerPixel = 0; int nCompression = COMPRESSION_NONE; int nPhotometric = 0; int nSampleFormat = 0; int nPlanarConfig = 0; int iOverview = 0; int nXSize = 0; int nYSize = 0; /* -------------------------------------------------------------------- */ /* Verify that the list of bands is suitable for emitting in */ /* TIFF file. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBands; iBand++ ) { int nBandBits = 0; int nBandFormat = 0; GDALRasterBand *hBand = papoBandList[iBand]; switch( hBand->GetRasterDataType() ) { case GDT_Byte: nBandBits = 8; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_UInt16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_UInt32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_Float32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_Float64: nBandBits = 64; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_CInt16: nBandBits = 32; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CInt32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CFloat32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; case GDT_CFloat64: nBandBits = 128; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; default: CPLAssert( false ); return CE_Failure; } if( hBand->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) ) { nBandBits = atoi(hBand->GetMetadataItem("NBITS", "IMAGE_STRUCTURE")); if( nBandBits == 1 && STARTS_WITH_CI(pszResampling, "AVERAGE_BIT2") ) nBandBits = 8; } if( iBand == 0 ) { nBitsPerPixel = nBandBits; nSampleFormat = nBandFormat; nXSize = hBand->GetXSize(); nYSize = hBand->GetYSize(); } else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } else if( hBand->GetColorTable() != nullptr ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of multiple colormapped bands." ); return CE_Failure; } else if( hBand->GetXSize() != nXSize || hBand->GetYSize() != nYSize ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of different sized bands." ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Use specified compression method. */ /* -------------------------------------------------------------------- */ const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", nullptr ); if( pszCompress != nullptr && pszCompress[0] != '\0' ) { nCompression = GTIFFGetCompressionMethod(pszCompress, "COMPRESS_OVERVIEW"); if( nCompression < 0 ) return CE_Failure; } if( nCompression == COMPRESSION_JPEG && nBitsPerPixel > 8 ) { if( nBitsPerPixel > 16 ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " JPEG compressed overviews of nBitsPerPixel > 16." ); return CE_Failure; } nBitsPerPixel = 12; } /* -------------------------------------------------------------------- */ /* Figure out the planar configuration to use. */ /* -------------------------------------------------------------------- */ if( nBands == 1 ) nPlanarConfig = PLANARCONFIG_CONTIG; else nPlanarConfig = PLANARCONFIG_SEPARATE; bool bSourceIsPixelInterleaved = false; bool bSourceIsJPEG2000 = false; if( nBands > 1 ) { GDALDataset* poSrcDS = papoBandList[0]->GetDataset(); if( poSrcDS ) { const char* pszSrcInterleave = poSrcDS->GetMetadataItem("INTERLEAVE", "IMAGE_STRUCTURE"); if( pszSrcInterleave && EQUAL(pszSrcInterleave, "PIXEL") ) { bSourceIsPixelInterleaved = true; } } const char* pszSrcCompression = papoBandList[0]->GetMetadataItem("COMPRESSION", "IMAGE_STRUCTURE"); if( pszSrcCompression ) { bSourceIsJPEG2000 = EQUAL(pszSrcCompression, "JPEG2000"); } if( bSourceIsPixelInterleaved && bSourceIsJPEG2000 ) { nPlanarConfig = PLANARCONFIG_CONTIG; } } const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", nullptr ); if( pszInterleave != nullptr && pszInterleave[0] != '\0' ) { if( EQUAL( pszInterleave, "PIXEL" ) ) nPlanarConfig = PLANARCONFIG_CONTIG; else if( EQUAL( pszInterleave, "BAND" ) ) nPlanarConfig = PLANARCONFIG_SEPARATE; else { CPLError( CE_Failure, CPLE_AppDefined, "INTERLEAVE_OVERVIEW=%s unsupported, " "value must be PIXEL or BAND. ignoring", pszInterleave ); } } /* -------------------------------------------------------------------- */ /* Figure out the photometric interpretation to use. */ /* -------------------------------------------------------------------- */ if( nBands == 3 ) nPhotometric = PHOTOMETRIC_RGB; else if( papoBandList[0]->GetColorTable() != nullptr && !STARTS_WITH_CI(pszResampling, "AVERAGE_BIT2") ) { nPhotometric = PHOTOMETRIC_PALETTE; // Should set the colormap up at this point too! } else if( nBands >= 3 && papoBandList[0]->GetColorInterpretation() == GCI_RedBand && papoBandList[1]->GetColorInterpretation() == GCI_GreenBand && papoBandList[2]->GetColorInterpretation() == GCI_BlueBand ) { nPhotometric = PHOTOMETRIC_RGB; } else nPhotometric = PHOTOMETRIC_MINISBLACK; const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", nullptr ); if( pszPhotometric != nullptr && pszPhotometric[0] != '\0' ) { if( EQUAL( pszPhotometric, "MINISBLACK" ) ) nPhotometric = PHOTOMETRIC_MINISBLACK; else if( EQUAL( pszPhotometric, "MINISWHITE" ) ) nPhotometric = PHOTOMETRIC_MINISWHITE; else if( EQUAL( pszPhotometric, "RGB" )) { nPhotometric = PHOTOMETRIC_RGB; } else if( EQUAL( pszPhotometric, "CMYK" )) { nPhotometric = PHOTOMETRIC_SEPARATED; } else if( EQUAL( pszPhotometric, "YCBCR" )) { nPhotometric = PHOTOMETRIC_YCBCR; // Because of subsampling, setting YCBCR without JPEG compression // leads to a crash currently. Would need to make // GTiffRasterBand::IWriteBlock() aware of subsampling so that it // doesn't overrun buffer size returned by libtiff. if( nCompression != COMPRESSION_JPEG ) { CPLError( CE_Failure, CPLE_NotSupported, "Currently, PHOTOMETRIC_OVERVIEW=YCBCR requires " "COMPRESS_OVERVIEW=JPEG" ); return CE_Failure; } if( pszInterleave != nullptr && pszInterleave[0] != '\0' && nPlanarConfig == PLANARCONFIG_SEPARATE ) { CPLError( CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires " "INTERLEAVE_OVERVIEW=PIXEL" ); return CE_Failure; } else { nPlanarConfig = PLANARCONFIG_CONTIG; } // YCBCR strictly requires 3 bands. Not less, not more // Issue an explicit error message as libtiff one is a bit cryptic: // JPEGLib:Bogus input colorspace. if( nBands != 3 ) { CPLError( CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires a source raster " "with only 3 bands (RGB)" ); return CE_Failure; } } else if( EQUAL( pszPhotometric, "CIELAB" )) { nPhotometric = PHOTOMETRIC_CIELAB; } else if( EQUAL( pszPhotometric, "ICCLAB" )) { nPhotometric = PHOTOMETRIC_ICCLAB; } else if( EQUAL( pszPhotometric, "ITULAB" )) { nPhotometric = PHOTOMETRIC_ITULAB; } else { CPLError( CE_Warning, CPLE_IllegalArg, "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.", pszPhotometric ); } } /* -------------------------------------------------------------------- */ /* Figure out the predictor value to use. */ /* -------------------------------------------------------------------- */ int nPredictor = PREDICTOR_NONE; if( nCompression == COMPRESSION_LZW || nCompression == COMPRESSION_ADOBE_DEFLATE ) { const char* pszPredictor = CPLGetConfigOption( "PREDICTOR_OVERVIEW", nullptr ); if( pszPredictor != nullptr ) { nPredictor = atoi( pszPredictor ); } } /* -------------------------------------------------------------------- */ /* Create the file, if it does not already exist. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; VSILFILE* fpL = nullptr; if( VSIStatExL( pszFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 ) { /* -------------------------------------------------------------------- */ /* Compute the uncompressed size. */ /* -------------------------------------------------------------------- */ double dfUncompressedOverviewSize = 0; int nDataTypeSize = GDALGetDataTypeSizeBytes(papoBandList[0]->GetRasterDataType()); for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { const int nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; const int nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; dfUncompressedOverviewSize += nOXSize * static_cast<double>(nOYSize) * nBands * nDataTypeSize; } if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { #ifndef BIGTIFF_SUPPORT CPLError( CE_Failure, CPLE_NotSupported, "The overview file would be larger than 4GB, " "but this is the largest size a TIFF can be, " "and BigTIFF is unavailable. " "Creation failed." ); return CE_Failure; #endif } /* -------------------------------------------------------------------- */ /* Should the file be created as a bigtiff file? */ /* -------------------------------------------------------------------- */ const char *pszBIGTIFF = CPLGetConfigOption( "BIGTIFF_OVERVIEW", nullptr ); if( pszBIGTIFF == nullptr ) pszBIGTIFF = "IF_SAFER"; bool bCreateBigTIFF = false; if( EQUAL(pszBIGTIFF,"IF_NEEDED") ) { if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) bCreateBigTIFF = true; } else if( EQUAL(pszBIGTIFF,"IF_SAFER") ) { // Look at the size of the base image and suppose that // the added overview levels won't be more than 1/2 of // the size of the base image. The theory says 1/3 of the // base image size if the overview levels are 2, 4, 8, 16. // Thus take 1/2 as the security margin for 1/3. const double dfUncompressedImageSize = nXSize * static_cast<double>(nYSize) * nBands * nDataTypeSize; if( dfUncompressedImageSize * 0.5 > 4200000000.0 ) bCreateBigTIFF = true; } else { bCreateBigTIFF = CPLTestBool( pszBIGTIFF ); if( !bCreateBigTIFF && nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { CPLError( CE_Failure, CPLE_NotSupported, "The overview file will be larger than 4GB, " "so BigTIFF is necessary. " "Creation failed."); return CE_Failure; } } #ifndef BIGTIFF_SUPPORT if( bCreateBigTIFF ) { CPLError( CE_Warning, CPLE_NotSupported, "BigTIFF requested, but GDAL built without BigTIFF " "enabled libtiff, request ignored." ); bCreateBigTIFF = false; } #endif if( bCreateBigTIFF ) CPLDebug( "GTiff", "File being created as a BigTIFF." ); fpL = VSIFOpenL( pszFilename, "w+" ); if( fpL == nullptr ) hOTIFF = nullptr; else hOTIFF = VSI_TIFFOpen( pszFilename, bCreateBigTIFF ? "w+8" : "w+", fpL ); if( hOTIFF == nullptr ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s' " "failed in VSI_TIFFOpen().", pszFilename ); if( fpL != nullptr ) CPL_IGNORE_RET_VAL(VSIFCloseL(fpL)); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Otherwise just open it for update access. */ /* -------------------------------------------------------------------- */ else { fpL = VSIFOpenL( pszFilename, "r+" ); if( fpL == nullptr ) hOTIFF = nullptr; else hOTIFF = VSI_TIFFOpen( pszFilename, "r+", fpL ); if( hOTIFF == nullptr ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s' " "failed in VSI_TIFFOpen().", pszFilename ); if( fpL != nullptr ) CPL_IGNORE_RET_VAL(VSIFCloseL(fpL)); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Do we have a palette? If so, create a TIFF compatible version. */ /* -------------------------------------------------------------------- */ unsigned short *panRed = nullptr; unsigned short *panGreen = nullptr; unsigned short *panBlue = nullptr; if( nPhotometric == PHOTOMETRIC_PALETTE ) { GDALColorTable *poCT = papoBandList[0]->GetColorTable(); int nColorCount = 65536; if( nBitsPerPixel <= 8 ) nColorCount = 256; panRed = static_cast<unsigned short *>( CPLCalloc(nColorCount, sizeof(unsigned short)) ); panGreen = static_cast<unsigned short *>( CPLCalloc(nColorCount, sizeof(unsigned short)) ); panBlue = static_cast<unsigned short *>( CPLCalloc(nColorCount, sizeof(unsigned short)) ); for( int iColor = 0; iColor < nColorCount; iColor++ ) { GDALColorEntry sRGB = { 0, 0, 0, 0 }; if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) ) { // TODO(schwehr): Check for underflow. // Going from signed short to unsigned short. panRed[iColor] = static_cast<unsigned short>(257 * sRGB.c1); panGreen[iColor] = static_cast<unsigned short>(257 * sRGB.c2); panBlue[iColor] = static_cast<unsigned short>(257 * sRGB.c3); } } } /* -------------------------------------------------------------------- */ /* Do we need some metadata for the overviews? */ /* -------------------------------------------------------------------- */ CPLString osMetadata; GDALDataset *poBaseDS = papoBandList[0]->GetDataset(); GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata ); /* -------------------------------------------------------------------- */ /* Loop, creating overviews. */ /* -------------------------------------------------------------------- */ int nOvrBlockXSize = 0; int nOvrBlockYSize = 0; GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize); CPLString osNoData; // don't move this in inner scope const char* pszNoData = nullptr; int bNoDataSet = FALSE; const double dfNoDataValue = papoBandList[0]->GetNoDataValue(&bNoDataSet); if( bNoDataSet ) { osNoData = GTiffFormatGDALNoDataTagValue(dfNoDataValue); pszNoData = osNoData.c_str(); } std::vector<uint16> anExtraSamples; for( int i = GTIFFGetMaxColorChannels(nPhotometric)+1; i <= nBands; i++ ) { if( papoBandList[i-1]->GetColorInterpretation() == GCI_AlphaBand ) { anExtraSamples.push_back( GTiffGetAlphaValue(CPLGetConfigOption("GTIFF_ALPHA", nullptr), DEFAULT_ALPHA_TYPE)); } else { anExtraSamples.push_back(EXTRASAMPLE_UNSPECIFIED); } } for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { const int nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; const int nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; GTIFFWriteDirectory( hOTIFF, FILETYPE_REDUCEDIMAGE, nOXSize, nOYSize, nBitsPerPixel, nPlanarConfig, nBands, nOvrBlockXSize, nOvrBlockYSize, TRUE, nCompression, nPhotometric, nSampleFormat, nPredictor, panRed, panGreen, panBlue, static_cast<int>(anExtraSamples.size()), anExtraSamples.empty() ? nullptr : anExtraSamples.data(), osMetadata, CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", nullptr ), CPLGetConfigOption( "JPEG_TABLESMODE_OVERVIEW", nullptr ), pszNoData, nullptr ); } if( panRed ) { CPLFree(panRed); CPLFree(panGreen); CPLFree(panBlue); panRed = nullptr; panGreen = nullptr; panBlue = nullptr; } XTIFFClose( hOTIFF ); if( VSIFCloseL(fpL) != 0 ) return CE_Failure; fpL = nullptr; /* -------------------------------------------------------------------- */ /* Open the overview dataset so that we can get at the overview */ /* bands. */ /* -------------------------------------------------------------------- */ GDALDataset *hODS = GDALDataset::Open( pszFilename, GDAL_OF_RASTER | GDAL_OF_UPDATE ); if( hODS == nullptr ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Do we need to set the jpeg quality? */ /* -------------------------------------------------------------------- */ TIFF *hTIFF = static_cast<TIFF *>( hODS->GetInternalHandle(nullptr) ); if( nCompression == COMPRESSION_JPEG && CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", nullptr ) != nullptr ) { const int nJpegQuality = atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75")); TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality ); GTIFFSetJpegQuality(GDALDataset::ToHandle(hODS), nJpegQuality); } if( nCompression == COMPRESSION_JPEG && CPLGetConfigOption( "JPEG_TABLESMODE_OVERVIEW", nullptr ) != nullptr ) { const int nJpegTablesMode = atoi(CPLGetConfigOption("JPEG_TABLESMODE_OVERVIEW", CPLSPrintf("%d", knGTIFFJpegTablesModeDefault))); TIFFSetField( hTIFF, TIFFTAG_JPEGTABLESMODE, nJpegTablesMode ); GTIFFSetJpegTablesMode(GDALDataset::ToHandle(hODS), nJpegTablesMode); } /* -------------------------------------------------------------------- */ /* Loop writing overview data. */ /* -------------------------------------------------------------------- */ int *panOverviewListSorted = static_cast<int*>(CPLMalloc(sizeof(int) * nOverviews)); memcpy( panOverviewListSorted, panOverviewList, sizeof(int) * nOverviews); std::sort(panOverviewListSorted, panOverviewListSorted + nOverviews); GTIFFSetInExternalOvr(true); CPLErr eErr = CE_None; if( ((bSourceIsPixelInterleaved && bSourceIsJPEG2000) || (nCompression != COMPRESSION_NONE)) && nPlanarConfig == PLANARCONFIG_CONTIG && !GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) && papoBandList[0]->GetColorTable() == nullptr && (STARTS_WITH_CI(pszResampling, "NEAR") || EQUAL(pszResampling, "AVERAGE") || EQUAL(pszResampling, "GAUSS") || EQUAL(pszResampling, "CUBIC") || EQUAL(pszResampling, "CUBICSPLINE") || EQUAL(pszResampling, "LANCZOS") || EQUAL(pszResampling, "BILINEAR")) ) { // In the case of pixel interleaved compressed overviews, we want to // generate the overviews for all the bands block by block, and not // band after band, in order to write the block once and not loose // space in the TIFF file. GDALRasterBand ***papapoOverviewBands = static_cast<GDALRasterBand ***>( CPLCalloc(sizeof(void *), nBands) ); for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *poSrcBand = papoBandList[iBand]; GDALRasterBand *poDstBand = hODS->GetRasterBand( iBand + 1 ); papapoOverviewBands[iBand] = static_cast<GDALRasterBand **>( CPLCalloc(sizeof(void *), nOverviews) ); int bHasNoData = FALSE; const double noDataValue = poSrcBand->GetNoDataValue(&bHasNoData); if( bHasNoData ) poDstBand->SetNoDataValue(noDataValue); for( int i = 0; i < nOverviews && eErr == CE_None; i++ ) { for( int j = -1; j < poDstBand->GetOverviewCount() && eErr == CE_None; j++ ) { GDALRasterBand * poOverview = (j < 0 ) ? poDstBand : poDstBand->GetOverview( j ); if( poOverview == nullptr ) { eErr = CE_Failure; continue; } const int nOvFactor = GDALComputeOvFactor(poOverview->GetXSize(), poSrcBand->GetXSize(), poOverview->GetYSize(), poSrcBand->GetYSize()); if( nOvFactor == panOverviewListSorted[i] || nOvFactor == GDALOvLevelAdjust2( panOverviewListSorted[i], poSrcBand->GetXSize(), poSrcBand->GetYSize() ) ) { papapoOverviewBands[iBand][i] = poOverview; if( bHasNoData ) poOverview->SetNoDataValue(noDataValue); break; } } CPLAssert( papapoOverviewBands[iBand][i] != nullptr ); } } if( eErr == CE_None ) eErr = GDALRegenerateOverviewsMultiBand( nBands, papoBandList, nOverviews, papapoOverviewBands, pszResampling, pfnProgress, pProgressData ); for( int iBand = 0; iBand < nBands; iBand++ ) { CPLFree(papapoOverviewBands[iBand]); } CPLFree(papapoOverviewBands); } else { GDALRasterBand **papoOverviews = static_cast<GDALRasterBand **>( CPLCalloc( sizeof(void*), knMaxOverviews ) ); for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand = hODS->GetRasterBand( iBand + 1 ); int bHasNoData = FALSE; const double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData); if( bHasNoData ) hDstBand->SetNoDataValue(noDataValue); // FIXME: this logic regenerates all overview bands, not only the // ones requested. papoOverviews[0] = hDstBand; int nDstOverviews = hDstBand->GetOverviewCount() + 1; CPLAssert( nDstOverviews < knMaxOverviews ); nDstOverviews = std::min(knMaxOverviews, nDstOverviews); // TODO(schwehr): Convert to starting with i = 1 and remove +1. for( int i = 0; i < nDstOverviews - 1 && eErr == CE_None; i++ ) { papoOverviews[i+1] = hDstBand->GetOverview(i); if( papoOverviews[i+1] == nullptr ) { eErr = CE_Failure; } else { if( bHasNoData ) papoOverviews[i+1]->SetNoDataValue(noDataValue); } } void *pScaledProgressData = GDALCreateScaledProgress( iBand / static_cast<double>( nBands ), (iBand + 1) / static_cast<double>( nBands ), pfnProgress, pProgressData ); if( eErr == CE_None ) eErr = GDALRegenerateOverviews( hSrcBand, nDstOverviews, reinterpret_cast<GDALRasterBandH *>( papoOverviews ), pszResampling, GDALScaledProgress, pScaledProgressData ); GDALDestroyScaledProgress( pScaledProgressData ); } CPLFree( papoOverviews ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if( eErr == CE_None ) hODS->FlushCache(); delete hODS; GTIFFSetInExternalOvr(false); CPLFree(panOverviewListSorted); pfnProgress( 1.0, nullptr, pProgressData ); return eErr; }
int OGRCSVDataSource::Open( const char * pszFilename, int bUpdateIn, int bForceOpen, char** papszOpenOptions ) { pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; if (bUpdateIn && bForceOpen && EQUAL(pszFilename, "/vsistdout/")) return TRUE; /* For writable /vsizip/, do nothing more */ if (bUpdateIn && bForceOpen && strncmp(pszFilename, "/vsizip/", 8) == 0) return TRUE; CPLString osFilename(pszFilename); CPLString osBaseFilename = CPLGetFilename(pszFilename); CPLString osExt = GetRealExtension(osFilename); pszFilename = NULL; int bIgnoreExtension = EQUALN(osFilename, "CSV:", 4); int bUSGeonamesFile = FALSE; /* int bGeonamesOrgFile = FALSE; */ if (bIgnoreExtension) { osFilename = osFilename + 4; } /* Those are *not* real .XLS files, but text file with tab as column separator */ if (EQUAL(osBaseFilename, "NfdcFacilities.xls") || EQUAL(osBaseFilename, "NfdcRunways.xls") || EQUAL(osBaseFilename, "NfdcRemarks.xls") || EQUAL(osBaseFilename, "NfdcSchedules.xls")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; } else if ((EQUALN(osBaseFilename, "NationalFile_", 13) || EQUALN(osBaseFilename, "POP_PLACES_", 11) || EQUALN(osBaseFilename, "HIST_FEATURES_", 14) || EQUALN(osBaseFilename, "US_CONCISE_", 11) || EQUALN(osBaseFilename, "AllNames_", 9) || EQUALN(osBaseFilename, "Feature_Description_History_", 28) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStates_", 10) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_Features_", 10)) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) && (EQUAL(osExt, "txt") || EQUAL(osExt, "zip")) ) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; bUSGeonamesFile = TRUE; if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } else if (EQUAL(osBaseFilename, "allCountries.txt") || EQUAL(osBaseFilename, "allCountries.zip")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; /* bGeonamesOrgFile = TRUE; */ if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Is this a single CSV file? */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(sStatBuf.st_mode) && (bIgnoreExtension || EQUAL(osExt,"csv") || EQUAL(osExt,"tsv")) ) { if (EQUAL(CPLGetFilename(osFilename), "NfdcFacilities.xls")) { return OpenTable( osFilename, papszOpenOptions, "ARP"); } else if (EQUAL(CPLGetFilename(osFilename), "NfdcRunways.xls")) { OpenTable( osFilename, papszOpenOptions, "BaseEndPhysical"); OpenTable( osFilename, papszOpenOptions, "BaseEndDisplaced"); OpenTable( osFilename, papszOpenOptions, "ReciprocalEndPhysical"); OpenTable( osFilename, papszOpenOptions, "ReciprocalEndDisplaced"); return nLayers != 0; } else if (bUSGeonamesFile) { /* GNIS specific */ if (EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) { OpenTable( osFilename, papszOpenOptions, NULL, "PRIMARY"); } else if (EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "Feature_Description_History_", 28)) { OpenTable( osFilename, papszOpenOptions, NULL, ""); } else { OpenTable( osFilename, papszOpenOptions, NULL, "PRIM"); OpenTable( osFilename, papszOpenOptions, NULL, "SOURCE"); } return nLayers != 0; } return OpenTable( osFilename, papszOpenOptions ); } /* -------------------------------------------------------------------- */ /* Is this a single a ZIP file with only a CSV file inside ? */ /* -------------------------------------------------------------------- */ if( strncmp(osFilename, "/vsizip/", 8) == 0 && EQUAL(osExt, "zip") && VSI_ISREG(sStatBuf.st_mode) ) { char** papszFiles = VSIReadDir(osFilename); if (CSLCount(papszFiles) != 1 || !EQUAL(CPLGetExtension(papszFiles[0]), "CSV")) { CSLDestroy(papszFiles); return FALSE; } osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL); CSLDestroy(papszFiles); return OpenTable( osFilename, papszOpenOptions ); } /* -------------------------------------------------------------------- */ /* Otherwise it has to be a directory. */ /* -------------------------------------------------------------------- */ if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; /* -------------------------------------------------------------------- */ /* Scan through for entries ending in .csv. */ /* -------------------------------------------------------------------- */ int nNotCSVCount = 0, i; char **papszNames = CPLReadDir( osFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if (EQUAL(CPLGetExtension(oSubFilename),"csvt")) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) { nNotCSVCount++; continue; } if (EQUAL(CPLGetExtension(oSubFilename),"csv")) { if( !OpenTable( oSubFilename, papszOpenOptions ) ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_Features_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { int bRet = OpenTable( oSubFilename, papszOpenOptions, NULL, "PRIM"); bRet |= OpenTable( oSubFilename, papszOpenOptions, NULL, "SOURCE"); if ( !bRet ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_FedCodes_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { if ( !OpenTable( oSubFilename, papszOpenOptions, NULL, "PRIMARY") ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } else { nNotCSVCount++; continue; } } CSLDestroy( papszNames ); /* -------------------------------------------------------------------- */ /* We presume that this is indeed intended to be a CSV */ /* datasource if over half the files were .csv files. */ /* -------------------------------------------------------------------- */ return bForceOpen || nNotCSVCount < nLayers; }
GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, int nOpenFlagsIn, char **papszSiblingsIn ) { /* -------------------------------------------------------------------- */ /* Ensure that C: is treated as C:\ so we can stat it on */ /* Windows. Similar to what is done in CPLStat(). */ /* -------------------------------------------------------------------- */ #ifdef WIN32 if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' ) { char szAltPath[10]; strcpy( szAltPath, pszFilenameIn ); strcat( szAltPath, "\\" ); pszFilename = CPLStrdup( szAltPath ); } else #endif pszFilename = CPLStrdup( pszFilenameIn ); /* -------------------------------------------------------------------- */ /* Initialize. */ /* -------------------------------------------------------------------- */ nHeaderBytes = 0; nHeaderBytesTried = 0; pabyHeader = NULL; bIsDirectory = FALSE; bStatOK = FALSE; nOpenFlags = nOpenFlagsIn; eAccess = (nOpenFlags & GDAL_OF_UPDATE) ? GA_Update : GA_ReadOnly; fpL = NULL; papszOpenOptions = NULL; #ifdef HAVE_READLINK bool bHasRetried = false; #endif /* -------------------------------------------------------------------- */ /* Collect information about the file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStat; #ifdef HAVE_READLINK retry: #endif bool bPotentialDirectory = false; /* Check if the filename might be a directory of a special virtual file system */ if( strncmp(pszFilename, "/vsizip/", strlen("/vsizip/")) == 0 || strncmp(pszFilename, "/vsitar/", strlen("/vsitar/")) == 0 ) { const char* pszExt = CPLGetExtension(pszFilename); if( EQUAL(pszExt, "zip") || EQUAL(pszExt, "tar") || EQUAL(pszExt, "gz") ) bPotentialDirectory = true; } else if( strncmp(pszFilename, "/vsicurl/", strlen("/vsicurl/")) == 0 ) { bPotentialDirectory = true; } if( bPotentialDirectory ) { /* For those special files, opening them with VSIFOpenL() might result */ /* in content, even if they should be considered as directories, so */ /* use stat */ if( VSIStatExL( pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) == 0 ) { bStatOK = TRUE; if( VSI_ISDIR( sStat.st_mode ) ) bIsDirectory = TRUE; } } if( !bIsDirectory ) fpL = VSIFOpenL( pszFilename, (eAccess == GA_Update) ? "r+b" : "rb" ); if( fpL != NULL ) { bStatOK = TRUE; pabyHeader = (GByte *) CPLCalloc(1025,1); nHeaderBytesTried = 1024; nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, nHeaderBytesTried, fpL ); VSIRewindL( fpL ); /* If we cannot read anything, check if it is not a directory instead */ if( nHeaderBytes == 0 && VSIStatExL( pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) == 0 && VSI_ISDIR( sStat.st_mode ) ) { VSIFCloseL(fpL); fpL = NULL; CPLFree(pabyHeader); pabyHeader = NULL; bIsDirectory = TRUE; } } else if( !bStatOK ) { if( VSIStatExL( pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) == 0 ) { bStatOK = TRUE; if( VSI_ISDIR( sStat.st_mode ) ) bIsDirectory = TRUE; } #ifdef HAVE_READLINK else if ( !bHasRetried && strncmp(pszFilename, "/vsi", strlen("/vsi")) != 0 ) { /* If someone creates a file with "ln -sf /vsicurl/http://download.osgeo.org/gdal/data/gtiff/utm.tif my_remote_utm.tif" */ /* we will be able to open it by passing my_remote_utm.tif */ /* This helps a lot for GDAL based readers that only provide file explorers to open datasets */ char szPointerFilename[2048]; int nBytes = readlink(pszFilename, szPointerFilename, sizeof(szPointerFilename)); if (nBytes != -1) { szPointerFilename[MIN(nBytes, (int)sizeof(szPointerFilename)-1)] = 0; CPLFree(pszFilename); pszFilename = CPLStrdup(szPointerFilename); papszSiblingsIn = NULL; bHasRetried = true; goto retry; } } #endif } /* -------------------------------------------------------------------- */ /* Capture sibling list either from passed in values, or by */ /* scanning for them only if requested through GetSiblingFiles(). */ /* -------------------------------------------------------------------- */ if( papszSiblingsIn != NULL ) { papszSiblingFiles = CSLDuplicate( papszSiblingsIn ); bHasGotSiblingFiles = TRUE; } else if( bStatOK && !bIsDirectory ) { const char* pszOptionVal = CPLGetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "NO" ); if (EQUAL(pszOptionVal, "EMPTY_DIR")) { papszSiblingFiles = CSLAddString( NULL, CPLGetFilename(pszFilename) ); bHasGotSiblingFiles = TRUE; } else if( CSLTestBoolean(pszOptionVal) ) { /* skip reading the directory */ papszSiblingFiles = NULL; bHasGotSiblingFiles = TRUE; } else { /* will be lazy loaded */ papszSiblingFiles = NULL; bHasGotSiblingFiles = FALSE; } } else { papszSiblingFiles = NULL; bHasGotSiblingFiles = TRUE; } }