int main(int argc, char* argv[]) { int i; int nThreads = CPLGetNumCPUs(); std::vector<CPLJoinableThread*> apsThreads; Strategy eStrategy = STRATEGY_RANDOM; int bNewDatasetOption = FALSE; int nXSize = 5000; int nYSize = 5000; int nBands = 4; char** papszOptions = NULL; int bOnDisk = FALSE; std::vector<ThreadDescription> asThreadDescription; int bMemDriver = FALSE; GDALDataset* poMEMDS = NULL; int bMigrate = FALSE; int nMaxRequests = -1; argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); GDALAllRegister(); for(i = 1; i < argc; i++) { if( EQUAL(argv[i], "-threads") && i + 1 < argc) { i ++; nThreads = atoi(argv[i]); } else if( EQUAL(argv[i], "-loops") && i + 1 < argc) { i ++; nLoops = atoi(argv[i]); if( nLoops <= 0 ) nLoops = INT_MAX; } else if( EQUAL(argv[i], "-max_requests") && i + 1 < argc) { i ++; nMaxRequests = atoi(argv[i]); } else if( EQUAL(argv[i], "-strategy") && i + 1 < argc) { i ++; if( EQUAL(argv[i], "random") ) eStrategy = STRATEGY_RANDOM; else if( EQUAL(argv[i], "line") ) eStrategy = STRATEGY_LINE; else if( EQUAL(argv[i], "block") ) eStrategy = STRATEGY_BLOCK; else Usage(); } else if( EQUAL(argv[i], "-xsize") && i + 1 < argc) { i ++; nXSize = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-ysize") && i + 1 < argc) { i ++; nYSize = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-bands") && i + 1 < argc) { i ++; nBands = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-co") && i + 1 < argc) { i ++; papszOptions = CSLAddString(papszOptions, argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-ondisk")) { bOnDisk = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-check")) { bCheck = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-memdriver")) { bMemDriver = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-migrate")) bMigrate = TRUE; else if( argv[i][0] == '-' ) Usage(); else if( pszDataset == NULL ) pszDataset = argv[i]; else { Usage(); } } if( pszDataset != NULL && bNewDatasetOption ) Usage(); CPLDebug("TEST", "Using %d threads", nThreads); int bCreatedDataset = FALSE; if( pszDataset == NULL ) { bCreatedDataset = TRUE; if( bOnDisk ) pszDataset = "/tmp/tmp.tif"; else pszDataset = "/vsimem/tmp.tif"; GDALDataset* poDS = ((GDALDriver*)GDALGetDriverByName((bMemDriver) ? "MEM" : "GTiff"))->Create(pszDataset, nXSize, nYSize, nBands, GDT_Byte, papszOptions); if( bCheck ) { GByte* pabyLine = (GByte*) VSIMalloc(nBands * nXSize); for(int iY=0;iY<nYSize;iY++) { for(int iX=0;iX<nXSize;iX++) { for(int iBand=0;iBand<nBands;iBand++) { unsigned long seed = iBand * nXSize * nYSize + iY * nXSize + iX; pabyLine[iBand * nXSize + iX] = (GByte)myrand_r(&seed); } } poDS->RasterIO(GF_Write, 0, iY, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, 0, 0, 0 #ifdef GDAL_COMPILATION , NULL #endif ); } VSIFree(pabyLine); } if( bMemDriver ) poMEMDS = poDS; else GDALClose(poDS); } else { bCheck = FALSE; } CSLDestroy(papszOptions); papszOptions = NULL; Request* psGlobalRequestLast = NULL; for(i = 0; i < nThreads; i++ ) { GDALDataset* poDS; // Since GDAL 2.0, the MEM driver is thread-safe, i.e. does not use the block // cache, but only for operations not involving resampling, which is // the case here if( poMEMDS ) poDS = poMEMDS; else { poDS = (GDALDataset*)GDALOpen(pszDataset, GA_ReadOnly); if( poDS == NULL ) exit(1); } if( bMigrate ) { Resource* psResource = (Resource*)CPLMalloc(sizeof(Resource)); psResource->poDS = poDS; int nBufferSize; if( eStrategy == STRATEGY_RANDOM ) nBufferSize = CreateRandomStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); else if( eStrategy == STRATEGY_LINE ) nBufferSize = CreateLineStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); else nBufferSize = CreateBlockStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); psResource->pBuffer = CPLMalloc(nBufferSize); PutResourceAtEnd(psResource); } else { ThreadDescription sThreadDescription; sThreadDescription.poDS = poDS; sThreadDescription.psRequestList = NULL; Request* psRequestLast = NULL; if( eStrategy == STRATEGY_RANDOM ) sThreadDescription.nBufferSize = CreateRandomStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); else if( eStrategy == STRATEGY_LINE ) sThreadDescription.nBufferSize = CreateLineStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); else sThreadDescription.nBufferSize = CreateBlockStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); asThreadDescription.push_back(sThreadDescription); } } if( bCreatedDataset && poMEMDS == NULL && bOnDisk ) { CPLPushErrorHandler(CPLQuietErrorHandler); VSIUnlink(pszDataset); CPLPopErrorHandler(); } if( bMigrate ) { psLock = CPLCreateLock(LOCK_SPIN); } for(i = 0; i < nThreads; i++ ) { CPLJoinableThread* pThread; if( bMigrate ) pThread = CPLCreateJoinableThread(ThreadFuncWithMigration, NULL); else pThread = CPLCreateJoinableThread(ThreadFuncDedicatedDataset, &(asThreadDescription[i])); apsThreads.push_back(pThread); } for(i = 0; i < nThreads; i++ ) { CPLJoinThread(apsThreads[i]); if( !bMigrate && poMEMDS == NULL ) GDALClose(asThreadDescription[i].poDS); } while( psGlobalResourceList != NULL ) { CPLFree( psGlobalResourceList->pBuffer); if( poMEMDS == NULL ) GDALClose(psGlobalResourceList->poDS); Resource* psNext = psGlobalResourceList->psNext; CPLFree( psGlobalResourceList ); psGlobalResourceList = psNext; } if( psLock ) { CPLDestroyLock( psLock ); } if( bCreatedDataset && poMEMDS == NULL ) { CPLPushErrorHandler(CPLQuietErrorHandler); VSIUnlink(pszDataset); CPLPopErrorHandler(); } if( poMEMDS ) GDALClose(poMEMDS); assert( GDALGetCacheUsed64() == 0 ); GDALDestroyDriverManager(); CSLDestroy( argv ); return 0; }
OGRErr OGRGeometryCollection::exportToWkt( char ** ppszDstText ) const { char **papszGeoms; int iGeom, nCumulativeLength = 0; OGRErr eErr; if( getNumGeometries() == 0 ) { *ppszDstText = CPLStrdup("GEOMETRYCOLLECTION EMPTY"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each Geom. */ /* -------------------------------------------------------------------- */ papszGeoms = (char **) CPLCalloc(sizeof(char *),nGeomCount); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt( &(papszGeoms[iGeom]) ); if( eErr != OGRERR_NONE ) goto error; nCumulativeLength += strlen(papszGeoms[iGeom]); } /* -------------------------------------------------------------------- */ /* Allocate the right amount of space for the aggregated string */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nGeomCount + 23); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); strcat( *ppszDstText, " (" ); nCumulativeLength = strlen(*ppszDstText); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( iGeom > 0 ) (*ppszDstText)[nCumulativeLength++] = ','; int nGeomLength = strlen(papszGeoms[iGeom]); memcpy( *ppszDstText + nCumulativeLength, papszGeoms[iGeom], nGeomLength ); nCumulativeLength += nGeomLength; VSIFree( papszGeoms[iGeom] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszGeoms ); return OGRERR_NONE; error: for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) CPLFree( papszGeoms[iGeom] ); CPLFree( papszGeoms ); return eErr; }
GDALDataset *GSAGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "GSAG driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, Golden Software ASCII Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Golden Software ASCII Grid format only supports one " "raster band, first band will be copied.\n" ); } if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); std::ostringstream ssHeader; ssHeader.precision( nFIELD_PRECISION ); ssHeader.setf( std::ios::uppercase ); ssHeader << "DSAA\x0D\x0A"; ssHeader << nXSize << " " << nYSize << "\x0D\x0A"; ssHeader << adfGeoTransform[0] + adfGeoTransform[1] / 2 << " " << adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0] << "\x0D\x0A"; ssHeader << adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3] << " " << adfGeoTransform[3] + adfGeoTransform[5] / 2 << "\x0D\x0A"; if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(), fp ) != ssHeader.str().length() ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to create copy, writing header failed.\n" ); return NULL; } /* Save the location and write placeholders for the min/max Z value */ vsi_l_offset nRangeStart = VSIFTellL( fp ); const char *szDummyRange = "0.0000000000001 0.0000000000001\x0D\x0A"; size_t nDummyRangeLen = strlen( szDummyRange ); if( VSIFWriteL( (void *)szDummyRange, 1, nDummyRangeLen, fp ) != nDummyRangeLen ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to create copy, writing header failed.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ double *pdfData = (double *)VSIMalloc2( nXSize, sizeof( double ) ); if( pdfData == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create copy, unable to allocate line buffer.\n" ); return NULL; } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1); int bSrcHasNDValue; double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMin = DBL_MAX; double dfMax = -DBL_MAX; for( int iRow=0; iRow<nYSize; iRow++ ) { CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1, nXSize, 1, pdfData, nXSize, 1, GDT_Float64, 0, 0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pdfData ); return NULL; } for( int iCol=0; iCol<nXSize; ) { for( int iCount=0; iCount<10 && iCol<nXSize; iCount++, iCol++ ) { double dfValue = pdfData[iCol]; if( bSrcHasNDValue && AlmostEqual( dfValue, dfSrcNoDataValue ) ) { dfValue = dfNODATA_VALUE; } else { if( dfValue > dfMax ) dfMax = dfValue; if( dfValue < dfMin ) dfMin = dfValue; } std::ostringstream ssOut; ssOut.precision(nFIELD_PRECISION); ssOut.setf( std::ios::uppercase ); ssOut << dfValue << " "; CPLString sOut = ssOut.str(); if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp ) != sOut.length() ) { VSIFCloseL( fp ); VSIFree( pdfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid cell. Disk full?\n" ); return NULL; } } if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 ) { VSIFCloseL( fp ); VSIFree( pdfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to finish write of grid line. Disk full?\n" ); return NULL; } } if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 ) { VSIFCloseL( fp ); VSIFree( pdfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to finish write of grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(iRow + 1)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pdfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pdfData ); /* write out the min and max values */ std::ostringstream ssRange; ssRange.precision( nFIELD_PRECISION ); ssRange.setf( std::ios::uppercase ); ssRange << dfMin << " " << dfMax << "\x0D\x0A"; if( ssRange.str().length() != nDummyRangeLen ) { int nShiftSize = ssRange.str().length() - nDummyRangeLen; if( ShiftFileContents( fp, nRangeStart + nDummyRangeLen, nShiftSize, "\x0D\x0A" ) != CE_None ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to shift file contents.\n" ); return NULL; } } if( VSIFSeekL( fp, nRangeStart, SEEK_SET ) != 0 ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of grid file copy.\n" ); return NULL; } if( VSIFWriteL( (void *)ssRange.str().c_str(), 1, ssRange.str().length(), fp ) != ssRange.str().length() ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write range information.\n" ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); } return poDS; }
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "GSBG driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, Golden Software Binary Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Golden Software Binary Grid format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); if( poSrcBand->GetXSize() > SHRT_MAX || poSrcBand->GetYSize() > SHRT_MAX ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, Golden Software Binary Grid format " "only supports sizes up to %dx%d. %dx%d not supported.\n", SHRT_MAX, SHRT_MAX, poSrcBand->GetXSize(), poSrcBand->GetYSize() ); return NULL; } if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } GInt16 nXSize = (GInt16) poSrcBand->GetXSize(); GInt16 nYSize = (GInt16) poSrcBand->GetYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2; double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]; double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3]; double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2; CPLErr eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) ); if( pfData == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create copy, unable to allocate line buffer.\n" ); return NULL; } int bSrcHasNDValue; float fSrcNoDataValue = (float) poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMinZ = DBL_MAX; double dfMaxZ = -DBL_MAX; for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- ) { eErr = poSrcBand->RasterIO( GF_Read, 0, iRow, nXSize, 1, pfData, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pfData ); return NULL; } for( int iCol=0; iCol<nXSize; iCol++ ) { if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue ) { pfData[iCol] = fNODATA_VALUE; } else { if( pfData[iCol] > dfMaxZ ) dfMaxZ = pfData[iCol]; if( pfData[iCol] < dfMinZ ) dfMinZ = pfData[iCol]; } CPL_LSBPTR32( pfData+iCol ); } if( VSIFWriteL( (void *)pfData, 4, nXSize, fp ) != static_cast<unsigned>(nXSize) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pfData ); /* write out the min and max values */ eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); } return poDS; }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
CPLErr GSAGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { if( eAccess == GA_ReadOnly ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Unable to write block, dataset opened read only.\n" ); return CE_Failure; } if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; GSAGDataset *poGDS = (GSAGDataset *)poDS; assert( poGDS != NULL ); if( padfRowMinZ == NULL || padfRowMaxZ == NULL || nMinZRow < 0 || nMaxZRow < 0 ) { padfRowMinZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) ); if( padfRowMinZ == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row minimums array.\n" ); return CE_Failure; } padfRowMaxZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) ); if( padfRowMaxZ == NULL ) { VSIFree( padfRowMinZ ); padfRowMinZ = NULL; CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row maximums array.\n" ); return CE_Failure; } CPLErr eErr = ScanForMinMaxZ(); if( eErr != CE_None ) return eErr; } if( panLineOffset[nBlockYOff+1] == 0 ) IReadBlock( nBlockXOff, nBlockYOff, NULL ); if( panLineOffset[nBlockYOff+1] == 0 || panLineOffset[nBlockYOff] == 0 ) return CE_Failure; std::ostringstream ssOutBuf; ssOutBuf.precision( GSAGDataset::nFIELD_PRECISION ); ssOutBuf.setf( std::ios::uppercase ); double *pdfImage = (double *)pImage; padfRowMinZ[nBlockYOff] = DBL_MAX; padfRowMaxZ[nBlockYOff] = -DBL_MAX; for( int iCell=0; iCell<nBlockXSize; ) { for( int iCol=0; iCol<10 && iCell<nBlockXSize; iCol++, iCell++ ) { if( AlmostEqual( pdfImage[iCell], GSAGDataset::dfNODATA_VALUE ) ) { if( pdfImage[iCell] < padfRowMinZ[nBlockYOff] ) padfRowMinZ[nBlockYOff] = pdfImage[iCell]; if( pdfImage[iCell] > padfRowMaxZ[nBlockYOff] ) padfRowMaxZ[nBlockYOff] = pdfImage[iCell]; } ssOutBuf << pdfImage[iCell] << " "; } ssOutBuf << poGDS->szEOL; } ssOutBuf << poGDS->szEOL; CPLString sOut = ssOutBuf.str(); if( sOut.length() != panLineOffset[nBlockYOff+1]-panLineOffset[nBlockYOff] ) { int nShiftSize = (int) (sOut.length() - (panLineOffset[nBlockYOff+1] - panLineOffset[nBlockYOff])); if( nBlockYOff != poGDS->nRasterYSize && GSAGDataset::ShiftFileContents( poGDS->fp, panLineOffset[nBlockYOff+1], nShiftSize, poGDS->szEOL ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failure writing block, " "unable to shift file contents.\n" ); return CE_Failure; } for( size_t iLine=nBlockYOff+1; iLine < static_cast<unsigned>(poGDS->nRasterYSize+1) && panLineOffset[iLine] != 0; iLine++ ) panLineOffset[iLine] += nShiftSize; } if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to grid line.\n" ); return CE_Failure; } if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), poGDS->fp ) != sOut.length() ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid block.\n" ); return CE_Failure; } /* Update header as needed */ bool bHeaderNeedsUpdate = false; if( nMinZRow == nBlockYOff && padfRowMinZ[nBlockYOff] > dfMinZ ) { double dfNewMinZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( padfRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = padfRowMinZ[iRow]; nMinZRow = iRow; } } if( dfNewMinZ != dfMinZ ) { dfMinZ = dfNewMinZ; bHeaderNeedsUpdate = true; } } if( nMaxZRow == nBlockYOff && padfRowMaxZ[nBlockYOff] < dfMaxZ ) { double dfNewMaxZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( padfRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = padfRowMaxZ[iRow]; nMaxZRow = iRow; } } if( dfNewMaxZ != dfMaxZ ) { dfMaxZ = dfNewMaxZ; bHeaderNeedsUpdate = true; } } if( padfRowMinZ[nBlockYOff] < dfMinZ || padfRowMaxZ[nBlockYOff] > dfMaxZ ) { if( padfRowMinZ[nBlockYOff] < dfMinZ ) { dfMinZ = padfRowMinZ[nBlockYOff]; nMinZRow = nBlockYOff; } if( padfRowMaxZ[nBlockYOff] > dfMaxZ ) { dfMaxZ = padfRowMaxZ[nBlockYOff]; nMaxZRow = nBlockYOff; } bHeaderNeedsUpdate = true; } if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ ) { CPLErr eErr = poGDS->UpdateHeader(); return eErr; } return CE_None; }
CPLErr GSBGRasterBand::ScanForMinMaxZ() { float *pafRowVals = (float *)VSIMalloc2( nRasterXSize, 4 ); if( pafRowVals == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate row buffer to scan grid file.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, pafRowVals ); if( eErr != CE_None ) { VSIFree( pafRowVals ); return CE_Failure; } pafRowMinZ[iRow] = FLT_MAX; pafRowMaxZ[iRow] = -FLT_MAX; for( int iCol=0; iCol<nRasterXSize; iCol++ ) { if( pafRowVals[iCol] == GSBGDataset::fNODATA_VALUE ) continue; if( pafRowVals[iCol] < pafRowMinZ[iRow] ) pafRowMinZ[iRow] = pafRowVals[iCol]; if( pafRowVals[iCol] > pafRowMinZ[iRow] ) pafRowMaxZ[iRow] = pafRowVals[iCol]; dfSum += pafRowVals[iCol]; dfSum2 += pafRowVals[iCol] * pafRowVals[iCol]; nValuesRead++; } if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nNewMinZRow = iRow; } if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( pafRowVals ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "GSBG driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, Golden Software Binary Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Golden Software Binary Grid format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); if( poSrcBand->GetXSize() > SHRT_MAX || poSrcBand->GetYSize() > SHRT_MAX ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, Golden Software Binary Grid format " "only supports sizes up to %dx%d. %dx%d not supported.\n", SHRT_MAX, SHRT_MAX, poSrcBand->GetXSize(), poSrcBand->GetYSize() ); return NULL; } if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } GInt16 nXSize = poSrcBand->GetXSize(); GInt16 nYSize = poSrcBand->GetYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2; double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]; double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3]; double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2; CPLErr eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) ); if( pfData == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create copy, unable to allocate line buffer.\n" ); return NULL; } int bSrcHasNDValue; float fSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMinZ = DBL_MAX; double dfMaxZ = -DBL_MAX; for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- ) { eErr = poSrcBand->RasterIO( GF_Read, 0, iRow, nXSize, 1, pfData, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pfData ); return NULL; } for( int iCol=0; iCol<nXSize; iCol++ ) { if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue ) { pfData[iCol] = fNODATA_VALUE; } else { if( pfData[iCol] > dfMaxZ ) dfMaxZ = pfData[iCol]; if( pfData[iCol] < dfMinZ ) dfMinZ = pfData[iCol]; } CPL_LSBPTR32( pfData+iCol ); } if( VSIFWriteL( (void *)pfData, 4, nXSize, fp ) != static_cast<unsigned>(nXSize) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(iRow)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pfData ); /* write out the min and max values */ eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDstDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if( poDstDS == NULL ) { VSIUnlink( pszFilename ); CPLError( CE_Failure, CPLE_FileIO, "Unable to open copy of dataset.\n" ); return NULL; } else if( dynamic_cast<GSBGDataset *>(poDstDS) == NULL ) { VSIUnlink( pszFilename ); delete poDstDS; CPLError( CE_Failure, CPLE_FileIO, "Copy dataset not opened as Golden Surfer Binary Grid!?\n" ); return NULL; } GDALRasterBand *poDstBand = poSrcDS->GetRasterBand(1); if( poDstBand == NULL ) { VSIUnlink( pszFilename ); delete poDstDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to open copy of raster band?\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Attempt to copy metadata. */ /* -------------------------------------------------------------------- */ if( !bStrict ) CPLPushErrorHandler( CPLQuietErrorHandler ); /* non-zero transform 2 or 4 or negative 1 or 5 not supported natively */ /*if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 || adfGeoTransform[1] < 0.0 || adfGeoTransform[5] < 0.0 ) poDstDS->GDALPamDataset::SetGeoTransform( adfGeoTransform );*/ const char *szProjectionRef = poSrcDS->GetProjectionRef(); if( *szProjectionRef != '\0' ) poDstDS->SetProjection( szProjectionRef ); char **pszMetadata = poSrcDS->GetMetadata(); if( pszMetadata != NULL ) poDstDS->SetMetadata( pszMetadata ); /* FIXME: Should the dataset description be copied as well, or is it * always the file name? */ poDstBand->SetDescription( poSrcBand->GetDescription() ); int bSuccess; double dfOffset = poSrcBand->GetOffset( &bSuccess ); if( bSuccess && dfOffset != 0.0 ) poDstBand->SetOffset( dfOffset ); double dfScale = poSrcBand->GetScale( &bSuccess ); if( bSuccess && dfScale != 1.0 ) poDstBand->SetScale( dfScale ); GDALColorInterp oColorInterp = poSrcBand->GetColorInterpretation(); if( oColorInterp != GCI_Undefined ) poDstBand->SetColorInterpretation( oColorInterp ); char **pszCatNames = poSrcBand->GetCategoryNames(); if( pszCatNames != NULL) poDstBand->SetCategoryNames( pszCatNames ); GDALColorTable *poColorTable = poSrcBand->GetColorTable(); if( poColorTable != NULL ) poDstBand->SetColorTable( poColorTable ); if( !bStrict ) CPLPopErrorHandler(); return poDstDS; }
JDEMRasterBand::~JDEMRasterBand() { VSIFree(pszRecord); }
int VSIIngestFile( VSILFILE* fp, const char* pszFilename, GByte** ppabyRet, vsi_l_offset* pnSize, GIntBig nMaxSize) { vsi_l_offset nDataLen = 0; int bFreeFP = FALSE; if( fp == NULL && pszFilename == NULL ) return FALSE; if( ppabyRet == NULL ) return FALSE; *ppabyRet = NULL; if( pnSize != NULL ) *pnSize = 0; if( NULL == fp ) { fp = VSIFOpenL( pszFilename, "rb" ); if( NULL == fp ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot open file '%s'", pszFilename ); return FALSE; } bFreeFP = TRUE; } else VSIFSeekL(fp, 0, SEEK_SET); if( pszFilename == NULL || strcmp(pszFilename, "/vsistdin/") == 0 ) { vsi_l_offset nDataAlloc = 0; VSIFSeekL( fp, 0, SEEK_SET ); while(TRUE) { if( nDataLen + 8192 + 1 > nDataAlloc ) { nDataAlloc = (nDataAlloc * 4) / 3 + 8192 + 1; if( nDataAlloc > (vsi_l_offset)(size_t)nDataAlloc ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } GByte* pabyNew = (GByte*)VSIRealloc(*ppabyRet, (size_t)nDataAlloc); if( pabyNew == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocated " CPL_FRMT_GIB " bytes", nDataAlloc ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } *ppabyRet = pabyNew; } int nRead = (int)VSIFReadL( *ppabyRet + nDataLen, 1, 8192, fp ); nDataLen += nRead; if ( nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( pnSize != NULL ) *pnSize = 0; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } if( pnSize != NULL ) *pnSize += nRead; (*ppabyRet)[nDataLen] = '\0'; if( nRead == 0 ) break; } } else { VSIFSeekL( fp, 0, SEEK_END ); nDataLen = VSIFTellL( fp ); // With "large" VSI I/O API we can read data chunks larger than VSIMalloc // could allocate. Catch it here. if ( nDataLen > (vsi_l_offset)(size_t)nDataLen || (nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize) ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } VSIFSeekL( fp, 0, SEEK_SET ); *ppabyRet = (GByte*)VSIMalloc((size_t)(nDataLen + 1)); if( NULL == *ppabyRet ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocated " CPL_FRMT_GIB " bytes", nDataLen + 1 ); if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } (*ppabyRet)[nDataLen] = '\0'; if( ( nDataLen != VSIFReadL( *ppabyRet, 1, (size_t)nDataLen, fp ) ) ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot read " CPL_FRMT_GIB " bytes", nDataLen ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } if( pnSize != NULL ) *pnSize = nDataLen; } if( bFreeFP ) VSIFCloseL( fp ); return TRUE; }
int NASReader::LoadClasses( const char *pszFile ) { // Add logic later to determine reasonable default schema file. if( pszFile == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Load the raw XML file. */ /* -------------------------------------------------------------------- */ FILE *fp; int nLength; char *pszWholeText; fp = VSIFOpen( pszFile, "rb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open file %s.", pszFile ); return FALSE; } VSIFSeek( fp, 0, SEEK_END ); nLength = VSIFTell( fp ); VSIFSeek( fp, 0, SEEK_SET ); pszWholeText = (char *) VSIMalloc(nLength+1); if( pszWholeText == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to allocate %d byte buffer for %s,\n" "is this really a GMLFeatureClassList file?", nLength, pszFile ); VSIFClose( fp ); return FALSE; } if( VSIFRead( pszWholeText, nLength, 1, fp ) != 1 ) { VSIFree( pszWholeText ); VSIFClose( fp ); CPLError( CE_Failure, CPLE_AppDefined, "Read failed on %s.", pszFile ); return FALSE; } pszWholeText[nLength] = '\0'; VSIFClose( fp ); if( strstr( pszWholeText, "<GMLFeatureClassList>" ) == NULL ) { VSIFree( pszWholeText ); CPLError( CE_Failure, CPLE_AppDefined, "File %s does not contain a GMLFeatureClassList tree.", pszFile ); return FALSE; } /* -------------------------------------------------------------------- */ /* Convert to XML parse tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot; psRoot = CPLParseXMLString( pszWholeText ); VSIFree( pszWholeText ); // We assume parser will report errors via CPL. if( psRoot == NULL ) return FALSE; if( psRoot->eType != CXT_Element || !EQUAL(psRoot->pszValue,"GMLFeatureClassList") ) { CPLDestroyXMLNode(psRoot); CPLError( CE_Failure, CPLE_AppDefined, "File %s is not a GMLFeatureClassList document.", pszFile ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract feature classes for all definitions found. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psThis; for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue,"GMLFeatureClass") ) { GMLFeatureClass *poClass; poClass = new GMLFeatureClass(); if( !poClass->InitializeFromXML( psThis ) ) { delete poClass; CPLDestroyXMLNode( psRoot ); return FALSE; } poClass->SetSchemaLocked( TRUE ); AddClass( poClass ); } } CPLDestroyXMLNode( psRoot ); SetClassListLocked( TRUE ); return TRUE; }
OGRFeature *OGRIdrisiLayer::GetNextRawFeature() { while(TRUE) { if (eGeomType == wkbPoint) { double dfId; double dfX, dfY; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfX, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfY, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfX); CPL_LSBPTR64(&dfY); if (m_poFilterGeom != NULL && (dfX < m_sFilterEnvelope.MinX || dfX > m_sFilterEnvelope.MaxX || dfY < m_sFilterEnvelope.MinY || dfY > m_sFilterEnvelope.MaxY)) { nNextFID ++; continue; } OGRPoint* poGeom = new OGRPoint(dfX, dfY); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); return poFeature; } else if (eGeomType == wkbLineString) { double dfId; double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape; unsigned int nNodes; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfMinXShape); CPL_LSBPTR64(&dfMaxXShape); CPL_LSBPTR64(&dfMinYShape); CPL_LSBPTR64(&dfMaxYShape); if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1) { return NULL; } CPL_LSBPTR32(&nNodes); if (nNodes > 100 * 1000 * 1000) return NULL; if (m_poFilterGeom != NULL && (dfMaxXShape < m_sFilterEnvelope.MinX || dfMinXShape > m_sFilterEnvelope.MaxX || dfMaxYShape < m_sFilterEnvelope.MinY || dfMinYShape > m_sFilterEnvelope.MaxY)) { nNextFID ++; VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR); continue; } OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nNodes); if (poRawPoints == NULL) { return NULL; } if ((unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes) { VSIFree(poRawPoints); return NULL; } #if defined(CPL_MSB) for(unsigned int iNode=0; iNode<nNodes; iNode++) { CPL_LSBPTR64(&poRawPoints[iNode].x); CPL_LSBPTR64(&poRawPoints[iNode].y); } #endif OGRLineString* poGeom = new OGRLineString(); poGeom->setPoints(nNodes, poRawPoints, NULL); VSIFree(poRawPoints); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); return poFeature; } else /* if (eGeomType == wkbPolygon) */ { double dfId; double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape; unsigned int nParts; unsigned int nTotalNodes; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfMinXShape); CPL_LSBPTR64(&dfMaxXShape); CPL_LSBPTR64(&dfMinYShape); CPL_LSBPTR64(&dfMaxYShape); if (VSIFReadL(&nParts, sizeof(unsigned int), 1, fp) != 1 || VSIFReadL(&nTotalNodes, sizeof(unsigned int), 1, fp) != 1) { return NULL; } CPL_LSBPTR32(&nParts); CPL_LSBPTR32(&nTotalNodes); if (nParts > 100000 || nTotalNodes > 100 * 1000 * 1000) return NULL; if (m_poFilterGeom != NULL && (dfMaxXShape < m_sFilterEnvelope.MinX || dfMinXShape > m_sFilterEnvelope.MaxX || dfMaxYShape < m_sFilterEnvelope.MinY || dfMinYShape > m_sFilterEnvelope.MaxY)) { unsigned int iPart; for(iPart = 0; iPart < nParts; iPart ++) { unsigned int nNodes; if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1) return NULL; CPL_LSBPTR32(&nNodes); if (nNodes > nTotalNodes) return NULL; VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR); } nNextFID ++; continue; } OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nTotalNodes); if (poRawPoints == NULL) { return NULL; } unsigned int iPart; OGRPolygon* poGeom = new OGRPolygon(); for(iPart = 0; iPart < nParts; iPart ++) { unsigned int nNodes; if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1) { VSIFree(poRawPoints); delete poGeom; return NULL; } CPL_LSBPTR32(&nNodes); if (nNodes > nTotalNodes || (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes) { VSIFree(poRawPoints); delete poGeom; return NULL; } #if defined(CPL_MSB) for(unsigned int iNode=0; iNode<nNodes; iNode++) { CPL_LSBPTR64(&poRawPoints[iNode].x); CPL_LSBPTR64(&poRawPoints[iNode].y); } #endif OGRLinearRing* poLR = new OGRLinearRing(); poGeom->addRingDirectly(poLR); poLR->setPoints(nNodes, poRawPoints, NULL); } VSIFree(poRawPoints); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); return poFeature; } } }
void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle const & extent, int width, int height ) { Q_UNUSED( bandNo ); if ( !mInput || !mShader ) { return 0; } QgsRasterInterface::DataType transparencyType = QgsRasterInterface::UnknownDataType; if ( mAlphaBand > 0 ) { transparencyType = ( QgsRasterInterface::DataType )mInput->dataType( mAlphaBand ); } void* transparencyData = 0; double currentOpacity = mOpacity; QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBand ); void* rasterData = mInput->block( mBand, extent, width, height ); int red, green, blue; QRgb myDefaultColor = qRgba( 255, 255, 255, 0 ); //rendering is faster without considering user-defined transparency bool hasTransparency = usesTransparency(); if ( mAlphaBand > 0 && mAlphaBand != mBand ) { transparencyData = mInput->block( mAlphaBand, extent, width, height ); } else if ( mAlphaBand == mBand ) { transparencyData = rasterData; } //create image QImage img( width, height, QImage::Format_ARGB32_Premultiplied ); QRgb* imageScanLine = 0; double val = 0; int currentRasterPos = 0; for ( int i = 0; i < height; ++i ) { imageScanLine = ( QRgb* )( img.scanLine( i ) ); for ( int j = 0; j < width; ++j ) { val = readValue( rasterData, rasterType, currentRasterPos ); if ( !mShader->shade( val, &red, &green, &blue ) ) { imageScanLine[j] = myDefaultColor; ++currentRasterPos; continue; } if ( !hasTransparency ) { imageScanLine[j] = qRgba( red, green, blue, 255 ); } else { //opacity currentOpacity = mOpacity; if ( mRasterTransparency ) { currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0; } if ( mAlphaBand > 0 ) { currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 ); } imageScanLine[j] = qRgba( currentOpacity * red, currentOpacity * green, currentOpacity * blue, currentOpacity * 255 ); } ++currentRasterPos; } } VSIFree( rasterData ); void * data = VSIMalloc( img.byteCount() ); return memcpy( data, img.bits(), img.byteCount() ); }
GDALRescaledAlphaBand::~GDALRescaledAlphaBand() { VSIFree(pTemp); }
SIGDEMRasterBand::~SIGDEMRasterBand() { SIGDEMRasterBand::FlushCache(); VSIFree(pBlockBuffer); }
CPLErr GDALRasterBlock::Internalize() { CPLAssert( pData == NULL ); void *pNewData = NULL; // This call will initialize the hRBLock mutex. Other call places can // only be called if we have go through there. const GIntBig nCurCacheMax = GDALGetCacheMax64(); // No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo(). const int nSizeInBytes = GetBlockSize(); /* -------------------------------------------------------------------- */ /* Flush old blocks if we are nearing our memory limit. */ /* -------------------------------------------------------------------- */ bool bFirstIter = true; bool bLoopAgain = false; do { bLoopAgain = false; GDALRasterBlock* apoBlocksToFree[64] = { NULL }; int nBlocksToFree = 0; { TAKE_LOCK; if( bFirstIter ) nCacheUsed += nSizeInBytes; GDALRasterBlock *poTarget = poOldest; while( nCacheUsed > nCurCacheMax ) { while( poTarget != NULL ) { if( CPLAtomicCompareAndExchange( &(poTarget->nLockCount), 0, -1) ) break; poTarget = poTarget->poPrevious; } if( poTarget != NULL ) { if( bSleepsForBockCacheDebug ) CPLSleep(CPLAtof( CPLGetConfigOption( "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK", "0"))); GDALRasterBlock* _poPrevious = poTarget->poPrevious; poTarget->Detach_unlocked(); poTarget->GetBand()->UnreferenceBlock(poTarget); apoBlocksToFree[nBlocksToFree++] = poTarget; if( poTarget->GetDirty() ) { // Only free one dirty block at a time so that // other dirty blocks of other bands with the same // coordinates can be found with TryGetLockedBlock() bLoopAgain = nCacheUsed > nCurCacheMax; break; } if( nBlocksToFree == 64 ) { bLoopAgain = ( nCacheUsed > nCurCacheMax ); break; } poTarget = _poPrevious; } else { break; } } /* ------------------------------------------------------------------ */ /* Add this block to the list. */ /* ------------------------------------------------------------------ */ if( !bLoopAgain ) Touch_unlocked(); } bFirstIter = false; // Now free blocks we have detached and removed from their band. for( int i = 0; i < nBlocksToFree; ++i) { GDALRasterBlock * const poBlock = apoBlocksToFree[i]; if( poBlock->GetDirty() ) { CPLErr eErr = poBlock->Write(); if( eErr != CE_None ) { // Save the error for later reporting. poBlock->GetBand()->SetFlushBlockErr(eErr); } } // Try to recycle the data of an existing block. void* pDataBlock = poBlock->pData; if( pNewData == NULL && pDataBlock != NULL && poBlock->GetBlockSize() == nSizeInBytes ) { pNewData = pDataBlock; } else { VSIFree(poBlock->pData); } poBlock->pData = NULL; poBlock->GetBand()->AddBlockToFreeList(poBlock); } } while(bLoopAgain); if( pNewData == NULL ) { pNewData = VSI_MALLOC_VERBOSE( nSizeInBytes ); if( pNewData == NULL ) { return( CE_Failure ); } } pData = pNewData; return CE_None; }
CPLErr GSAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { static size_t nMaxLineSize = 128; double *pdfImage = (double *)pImage; GSAGDataset *poGDS = (GSAGDataset *)poDS; assert( poGDS != NULL ); if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; if( panLineOffset[nBlockYOff] == 0 ) { // Discover the last read block for ( int iFoundLine = nLastReadLine - 1; iFoundLine > nBlockYOff; iFoundLine--) { if( IReadBlock( nBlockXOff, iFoundLine, NULL) != CE_None ) return CE_Failure; } } if( panLineOffset[nBlockYOff] == 0 ) return CE_Failure; if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Can't seek to offset %ld to read grid row %d.", (long) panLineOffset[nBlockYOff], nBlockYOff ); return CE_Failure; } size_t nLineBufSize; char *szLineBuf = NULL; size_t nCharsRead; size_t nCharsExamined = 0; /* If we know the offsets, we can just read line directly */ if( (nBlockYOff > 0) && ( panLineOffset[nBlockYOff-1] != 0 ) ) { assert(panLineOffset[nBlockYOff-1] > panLineOffset[nBlockYOff]); nLineBufSize = (size_t) (panLineOffset[nBlockYOff-1] - panLineOffset[nBlockYOff] + 1); } else { nLineBufSize = nMaxLineSize; } szLineBuf = (char *)VSIMalloc( nLineBufSize ); if( szLineBuf == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to read block, unable to allocate line buffer.\n" ); return CE_Failure; } nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read grid row %d at offset %ld.\n", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } szLineBuf[nCharsRead] = '\0'; char *szStart = szLineBuf; char *szEnd = szStart; for( int iCell=0; iCell<nBlockXSize; szStart = szEnd ) { double dfValue = CPLStrtod( szStart, &szEnd ); if( szStart == szEnd ) { /* No number found */ /* Check if this was an expected failure */ while( isspace( (unsigned char)*szStart ) ) szStart++; /* Found sign at end of input, seek back to re-read it */ if ( (*szStart == '-' || *szStart == '+') && *(szStart+1) == '\0' ) { if( VSIFSeekL( poGDS->fp, VSIFTellL( poGDS->fp)-1, SEEK_SET ) != 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid row %d " "(offset %ld, seek %d).\n", nBlockYOff, (long) VSIFTellL(poGDS->fp), -1 ); return CE_Failure; } } else if( *szStart != '\0' ) { szEnd = szStart; while( !isspace( (unsigned char)*szEnd ) && *szEnd != '\0' ) szEnd++; char cOldEnd = *szEnd; *szEnd = '\0'; CPLError( CE_Warning, CPLE_FileIO, "Unexpected value in grid row %d (expected floating " "point value, found \"%s\").\n", nBlockYOff, szStart ); *szEnd = cOldEnd; szEnd = szStart; while( !isdigit( *szEnd ) && *szEnd != '.' && *szEnd != '\0' ) szEnd++; continue; } else if( static_cast<size_t>(szStart - szLineBuf) != nCharsRead ) { CPLError( CE_Warning, CPLE_FileIO, "Unexpected ASCII null-character in grid row %d at " "offset %ld.\n", nBlockYOff, (long) (szStart - szLineBuf) ); while( *szStart == '\0' && static_cast<size_t>(szStart - szLineBuf) < nCharsRead ) szStart++; szEnd = szStart; continue; } nCharsExamined += szStart - szLineBuf; nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read portion of grid row %d at offset %ld.", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } szLineBuf[nCharsRead] = '\0'; szStart = szEnd = szLineBuf; continue; } else if( *szEnd == '\0' || (*szEnd == '.' && *(szEnd+1) == '\0') || (*szEnd == '-' && *(szEnd+1) == '\0') || (*szEnd == '+' && *(szEnd+1) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') || (*szEnd == 'E' && *(szEnd+1) == '+' && *(szEnd+2) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') || (*szEnd == 'e' && *(szEnd+1) == '+' && *(szEnd+2) == '\0')) { /* Number was interrupted by a nul character */ while( *szEnd != '\0' ) szEnd++; if( static_cast<size_t>(szEnd - szLineBuf) != nCharsRead ) { CPLError( CE_Warning, CPLE_FileIO, "Unexpected ASCII null-character in grid row %d at " "offset %ld.\n", nBlockYOff, (long) (szStart - szLineBuf) ); while( *szEnd == '\0' && static_cast<size_t>(szStart - szLineBuf) < nCharsRead ) szEnd++; continue; } /* End of buffer, could be interrupting a number */ if( VSIFSeekL( poGDS->fp, szStart - szEnd, SEEK_CUR ) != 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid row %d (offset %ld, seek %d)" ".\n", nBlockYOff, (long) VSIFTellL(poGDS->fp), (int) (szStart - szEnd) ); return CE_Failure; } nCharsExamined += szStart - szLineBuf; nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp ); szLineBuf[nCharsRead] = '\0'; if( nCharsRead == 0 ) { VSIFree( szLineBuf ); CPLError( CE_Failure, CPLE_FileIO, "Can't read portion of grid row %d at offset %ld.", nBlockYOff, (long) panLineOffset[nBlockYOff] ); return CE_Failure; } else if( nCharsRead > static_cast<size_t>(szEnd - szStart) ) { /* Read new data, this was not really the end */ szEnd = szStart = szLineBuf; continue; } /* This is really the last value and has no tailing newline */ szStart = szLineBuf; szEnd = szLineBuf + nCharsRead; } if( pdfImage != NULL ) { *(pdfImage+iCell) = dfValue; } iCell++; } while( *szEnd == ' ' ) szEnd++; if( *szEnd != '\0' && *szEnd != poGDS->szEOL[0] ) CPLDebug( "GSAG", "Grid row %d does not end with a newline. " "Possible skew.\n", nBlockYOff ); while( isspace( (unsigned char)*szEnd ) ) szEnd++; nCharsExamined += szEnd - szLineBuf; if( nCharsExamined >= nMaxLineSize ) nMaxLineSize = nCharsExamined + 1; if( nBlockYOff > 0 ) panLineOffset[nBlockYOff - 1] = panLineOffset[nBlockYOff] + nCharsExamined; nLastReadLine = nBlockYOff; VSIFree( szLineBuf ); return CE_None; }
void _TIFFfree(tdata_t p) { VSIFree( p ); }
GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) { /* Check that this actually is a JAXA PALSAR product */ if ( !PALSARJaxaDataset::Identify(poOpenInfo) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The JAXAPALSAR driver does not support update access to existing" " datasets.\n" ); return NULL; } PALSARJaxaDataset *poDS = new PALSARJaxaDataset(); /* Get the suffix of the filename, we'll need this */ char *pszSuffix = VSIStrdup( (char *) (CPLGetFilename( poOpenInfo->pszFilename ) + 3) ); /* Try to read each of the polarizations */ const size_t nImgFileLen = strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + strlen( pszSuffix ) + 8; char *pszImgFile = (char *)CPLMalloc( nImgFileLen ); int nBandNum = 1; /* HH */ VSILFILE *fpHH; snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HH%s", CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix ); fpHH = VSIFOpenL( pszImgFile, "rb" ); if (fpHH != NULL) { poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) ); nBandNum++; } /* HV */ VSILFILE *fpHV; snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HV%s", CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix ); fpHV = VSIFOpenL( pszImgFile, "rb" ); if (fpHV != NULL) { poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) ); nBandNum++; } /* VH */ VSILFILE *fpVH; snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VH%s", CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix ); fpVH = VSIFOpenL( pszImgFile, "rb" ); if (fpVH != NULL) { poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) ); nBandNum++; } /* VV */ VSILFILE *fpVV; snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VV%s", CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix ); fpVV = VSIFOpenL( pszImgFile, "rb" ); if (fpVV != NULL) { poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) ); nBandNum++; } VSIFree( pszImgFile ); /* did we get at least one band? */ if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find any image data. Aborting opening as PALSAR image."); delete poDS; VSIFree( pszSuffix ); return NULL; } /* Level 1.0 products are not supported */ if (poDS->nFileType == level_10) { CPLError( CE_Failure, CPLE_AppDefined, "ALOS PALSAR Level 1.0 products are not supported. Aborting opening as PALSAR image."); delete poDS; VSIFree( pszSuffix ); return NULL; } /* read metadata from Leader file. */ const size_t nLeaderFilenameLen = strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) + strlen(pszSuffix) + 5; char *pszLeaderFilename = (char *)CPLMalloc( nLeaderFilenameLen ); snprintf( pszLeaderFilename, nLeaderFilenameLen, "%s%sLED%s", CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix ); VSILFILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" ); /* check if the leader is actually present */ if (fpLeader != NULL) { ReadMetadata(poDS, fpLeader); VSIFCloseL(fpLeader); } VSIFree(pszLeaderFilename); VSIFree( pszSuffix ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
CPLErr JP2LuraRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg* psExtraArg) { JP2LuraDataset *poGDS = reinterpret_cast<JP2LuraDataset *>(poDS); const int nBufTypeSize = GDALGetDataTypeSizeBytes(eBufType); if (eRWFlag != GF_Read) return CE_Failure; #ifdef DEBUG_VERBOSE CPLDebug("JP2Lura", "RasterIO(nBand=%d,nLevel=%d %d,%d,%dx%d -> %dx%d)", nBand, poGDS->iLevel, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize); #endif if( eBufType != eDataType || nPixelSpace != nBufTypeSize || nLineSpace != nPixelSpace * nBufXSize ) { return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); } // Use cached data if( poGDS->sOutputData.nXOff == nXOff && poGDS->sOutputData.nYOff == nYOff && poGDS->sOutputData.nXSize == nXSize && poGDS->sOutputData.nYSize == nYSize && poGDS->sOutputData.nBufXSize == nBufXSize && poGDS->sOutputData.nBufYSize == nBufYSize && poGDS->sOutputData.eBufType == eBufType ) { if (poGDS->sOutputData.pDatacache[nBand - 1] != nullptr) { #ifdef DEBUG_VERBOSE CPLDebug("JP2Lura", "Using cached data"); #endif memcpy(pData, poGDS->sOutputData.pDatacache[nBand - 1], static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize); return CE_None; } } /* ==================================================================== */ /* Do we have overviews that would be appropriate to satisfy */ /* this request? */ /* ==================================================================== */ if ((nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0 && eRWFlag == GF_Read) { int nOverview; GDALRasterIOExtraArg sExtraArg; GDALCopyRasterIOExtraArg(&sExtraArg, psExtraArg); nOverview = GDALBandGetBestOverviewLevel2( this, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, &sExtraArg); if (nOverview >= 0) { GDALRasterBand* poOverviewBand = GetOverview(nOverview); if (poOverviewBand == nullptr) return CE_Failure; return poOverviewBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, &sExtraArg); } } if( nBufXSize != nXSize || nBufYSize != nYSize ) { return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); } JP2_Error error = 0; const short factor = 1 << poGDS->iLevel; JP2_Rect comp_region; comp_region.ulLeft = nXOff; comp_region.ulRight = nXOff + nXSize; comp_region.ulTop = nYOff; comp_region.ulBottom = nYOff + nYSize; error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Scale_Down, factor); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } poGDS->sOutputData.pimage = reinterpret_cast<unsigned char*>(pData); poGDS->sOutputData.nXOff = nXOff; poGDS->sOutputData.nYOff = nYOff; poGDS->sOutputData.nXSize = nXSize; poGDS->sOutputData.nYSize = nYSize; poGDS->sOutputData.nBufXSize = nBufXSize; poGDS->sOutputData.nBufYSize = nBufYSize; poGDS->sOutputData.eBufType = eBufType; poGDS->sOutputData.nBand = nBand; poGDS->sOutputData.nBands = poGDS->nBands; if( poGDS->sOutputData.pDatacache == nullptr ) { poGDS->sOutputData.pDatacache = reinterpret_cast<unsigned char**> (CPLCalloc( poGDS->nBands, sizeof(unsigned char*))); } for (int i = 0; i < poGDS->nBands; i++) { if (poGDS->sOutputData.pDatacache[i] != nullptr) { VSIFree(poGDS->sOutputData.pDatacache[i]); poGDS->sOutputData.pDatacache[i] = nullptr; } if (i == nBand-1) continue; poGDS->sOutputData.pDatacache[i] = reinterpret_cast<unsigned char*>(VSIMalloc( static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize)); } /*++++++++++++++++++++++++++++++++++++++++++++++*/ /* Set the callback function and parameter */ /*++++++++++++++++++++++++++++++++++++++++++++++*/ error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Output_Parameter, reinterpret_cast<JP2_Property_Value>(&(poGDS->sOutputData))); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } error = JP2_Decompress_SetProp(poGDS->sOutputData.handle, cJP2_Prop_Output_Function, reinterpret_cast<JP2_Property_Value>( GDALJP2Lura_Callback_Decompress_Write)); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } error = JP2_Decompress_Region(poGDS->sOutputData.handle, comp_region); if( error ) { CPLError(CE_Failure, CPLE_AppDefined, "Internal library error during decompress region (%s).", JP2LuraDataset::GetErrorMessage(error)); return CE_Failure; } return CE_None; }
CPLErr GSBGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { if( eAccess == GA_ReadOnly ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Unable to write block, dataset opened read only.\n" ); return CE_Failure; } if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) return CE_Failure; GSBGDataset *poGDS = dynamic_cast<GSBGDataset *>(poDS); assert( poGDS != NULL ); if( pafRowMinZ == NULL || pafRowMaxZ == NULL || nMinZRow < 0 || nMaxZRow < 0 ) { pafRowMinZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) ); if( pafRowMinZ == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row minimums array.\n" ); return CE_Failure; } pafRowMaxZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) ); if( pafRowMaxZ == NULL ) { VSIFree( pafRowMinZ ); pafRowMinZ = NULL; CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for row maximums array.\n" ); return CE_Failure; } CPLErr eErr = ScanForMinMaxZ(); if( eErr != CE_None ) return eErr; } if( VSIFSeekL( poGDS->fp, GSBGDataset::nHEADER_SIZE + 4 * nRasterXSize * (nRasterYSize - nBlockYOff - 1), SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to beginning of grid row.\n" ); return CE_Failure; } float *pfImage = (float *)pImage; pafRowMinZ[nBlockYOff] = FLT_MAX; pafRowMaxZ[nBlockYOff] = -FLT_MAX; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { if( pfImage[iPixel] != GSBGDataset::fNODATA_VALUE ) { if( pfImage[iPixel] < pafRowMinZ[nBlockYOff] ) pafRowMinZ[nBlockYOff] = pfImage[iPixel]; if( pfImage[iPixel] > pafRowMaxZ[nBlockYOff] ) pafRowMaxZ[nBlockYOff] = pfImage[iPixel]; } CPL_LSBPTR32( pfImage+iPixel ); } if( VSIFWriteL( pImage, sizeof(float), nBlockXSize, poGDS->fp ) != static_cast<unsigned>(nBlockXSize) ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write block to grid file.\n" ); return CE_Failure; } /* Update min/max Z values as appropriate */ bool bHeaderNeedsUpdate = false; if( nMinZRow == nBlockYOff && pafRowMinZ[nBlockYOff] > dfMinZ ) { double dfNewMinZ = DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nMinZRow = iRow; } } if( dfNewMinZ != dfMinZ ) { dfMinZ = dfNewMinZ; bHeaderNeedsUpdate = true; } } if( nMaxZRow == nBlockYOff && pafRowMaxZ[nBlockYOff] < dfMaxZ ) { double dfNewMaxZ = -DBL_MAX; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nMaxZRow = iRow; } } if( dfNewMaxZ != dfMaxZ ) { dfMaxZ = dfNewMaxZ; bHeaderNeedsUpdate = true; } } if( pafRowMinZ[nBlockYOff] < dfMinZ || pafRowMaxZ[nBlockYOff] > dfMaxZ ) { if( pafRowMinZ[nBlockYOff] < dfMinZ ) { dfMinZ = pafRowMinZ[nBlockYOff]; nMinZRow = nBlockYOff; } if( pafRowMaxZ[nBlockYOff] > dfMaxZ ) { dfMaxZ = pafRowMaxZ[nBlockYOff]; nMaxZRow = nBlockYOff; } bHeaderNeedsUpdate = true; } if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ ) { CPLErr eErr = poGDS->WriteHeader( poGDS->fp, (GInt16) nRasterXSize, (GInt16) nRasterYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); return eErr; } return CE_None; }
void CPLDebug( const char * pszCategory, const char * pszFormat, ... ) { CPLErrorContext *psCtx = CPLGetErrorContext(); char *pszMessage; va_list args; const char *pszDebug = CPLGetConfigOption("CPL_DEBUG",NULL); #define ERROR_MAX 25000 /* -------------------------------------------------------------------- */ /* Does this message pass our current criteria? */ /* -------------------------------------------------------------------- */ if( pszDebug == NULL ) return; if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") ) { size_t i, nLen = strlen(pszCategory); for( i = 0; pszDebug[i] != '\0'; i++ ) { if( EQUALN(pszCategory,pszDebug+i,nLen) ) break; } if( pszDebug[i] == '\0' ) return; } /* -------------------------------------------------------------------- */ /* Allocate a block for the error. */ /* -------------------------------------------------------------------- */ pszMessage = (char *) VSIMalloc( ERROR_MAX ); if( pszMessage == NULL ) return; /* -------------------------------------------------------------------- */ /* Dal -- always log a timestamp as the first part of the line */ /* to ensure one is looking at what one should be looking at! */ /* -------------------------------------------------------------------- */ pszMessage[0] = '\0'; #ifdef TIMESTAMP_DEBUG if( CPLGetConfigOption( "CPL_TIMESTAMP", NULL ) != NULL ) { strcpy( pszMessage, VSICTime( VSITime(NULL) ) ); // On windows anyway, ctime puts a \n at the end, but I'm not // convinced this is standard behaviour, so we'll get rid of it // carefully if (pszMessage[strlen(pszMessage) -1 ] == '\n') { pszMessage[strlen(pszMessage) - 1] = 0; // blow it out } strcat( pszMessage, ": " ); } #endif /* -------------------------------------------------------------------- */ /* Add the category. */ /* -------------------------------------------------------------------- */ strcat( pszMessage, pszCategory ); strcat( pszMessage, ": " ); /* -------------------------------------------------------------------- */ /* Format the application provided portion of the debug message. */ /* -------------------------------------------------------------------- */ va_start(args, pszFormat); #if defined(HAVE_VSNPRINTF) vsnprintf(pszMessage+strlen(pszMessage), ERROR_MAX - strlen(pszMessage), pszFormat, args); #else vsprintf(pszMessage+strlen(pszMessage), pszFormat, args); #endif va_end(args); /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None, pszMessage ); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler( CE_Debug, CPLE_None, pszMessage ); } VSIFree( pszMessage ); }
GDALDataset * EpsilonDatasetCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if ((nBands != 1 && nBands != 3) || (nBands > 0 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)) { CPLError(CE_Failure, CPLE_NotSupported, "The EPSILON driver only supports 1 band (grayscale) " "or 3 band (RGB) data"); return NULL; } /* -------------------------------------------------------------------- */ /* Fetch and check creation options */ /* -------------------------------------------------------------------- */ int nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); int nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if ((nBlockXSize != 32 && nBlockXSize != 64 && nBlockXSize != 128 && nBlockXSize != 256 && nBlockXSize != 512 && nBlockXSize != 1024) || (nBlockYSize != 32 && nBlockYSize != 64 && nBlockYSize != 128 && nBlockYSize != 256 && nBlockYSize != 512 && nBlockYSize != 1024)) { CPLError(CE_Failure, CPLE_NotSupported, "Block size must be a power of 2 between 32 et 1024"); return NULL; } const char* pszFilter = CSLFetchNameValueDef(papszOptions, "FILTER", "daub97lift"); char** papszFBID = eps_get_fb_info(EPS_FB_ID); char** papszFBIDIter = papszFBID; int bFound = FALSE; int nIndexFB = 0; while(papszFBIDIter && *papszFBIDIter && !bFound) { if (strcmp(*papszFBIDIter, pszFilter) == 0) bFound = TRUE; else nIndexFB ++; papszFBIDIter ++; } eps_free_fb_info(papszFBID); if (!bFound) { CPLError(CE_Failure, CPLE_NotSupported, "FILTER='%s' not supported", pszFilter); return NULL; } int eMode = EPS_MODE_OTLPF; const char* pszMode = CSLFetchNameValueDef(papszOptions, "MODE", "OTLPF"); if (EQUAL(pszMode, "NORMAL")) eMode = EPS_MODE_NORMAL; else if (EQUAL(pszMode, "OTLPF")) eMode = EPS_MODE_OTLPF; else { CPLError(CE_Failure, CPLE_NotSupported, "MODE='%s' not supported", pszMode); return NULL; } char** papszFBType = eps_get_fb_info(EPS_FB_TYPE); int bIsBiOrthogonal = EQUAL(papszFBType[nIndexFB], "biorthogonal"); eps_free_fb_info(papszFBType); if (eMode == EPS_MODE_OTLPF && !bIsBiOrthogonal) { CPLError(CE_Failure, CPLE_NotSupported, "MODE=OTLPF can only be used with biorthogonal filters. " "Use MODE=NORMAL instead"); return NULL; } int bRasterliteOutput = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "RASTERLITE_OUTPUT", "NO")); int nYRatio = EPS_Y_RT; int nCbRatio = EPS_Cb_RT; int nCrRatio = EPS_Cr_RT; int eResample; if (CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "RGB_RESAMPLE", "YES"))) eResample = EPS_RESAMPLE_420; else eResample = EPS_RESAMPLE_444; const char* pszTarget = CSLFetchNameValueDef(papszOptions, "TARGET", "96"); double dfReductionFactor = 1 - atof(pszTarget) / 100; if (dfReductionFactor > 1) dfReductionFactor = 1; else if (dfReductionFactor < 0) dfReductionFactor = 0; /* -------------------------------------------------------------------- */ /* Open file */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) return NULL; /* -------------------------------------------------------------------- */ /* Compute number of blocks, block size, etc... */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); if (eMode == EPS_MODE_OTLPF) { nBlockXSize ++; nBlockYSize ++; } int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; int nBlocks = nXBlocks * nYBlocks; int nUncompressedFileSize = nXSize * nYSize * nBands; int nUncompressedBlockSize = nUncompressedFileSize / nBlocks; int nTargetBlockSize = (int) (dfReductionFactor * nUncompressedBlockSize); if (nBands == 1) nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_GRAYSCALE_BUF + 1); else nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_TRUECOLOR_BUF + 1); /* -------------------------------------------------------------------- */ /* Allocate work buffers */ /* -------------------------------------------------------------------- */ GByte* pabyBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands); if (pabyBuffer == NULL) { VSIFCloseL(fp); return NULL; } GByte* pabyOutBuf = (GByte*)VSIMalloc(nTargetBlockSize); if (pabyOutBuf == NULL) { VSIFree(pabyBuffer); VSIFCloseL(fp); return NULL; } GByte** apapbyRawBuffer[3]; int i, j; for(i=0;i<nBands;i++) { apapbyRawBuffer[i] = (GByte**) VSIMalloc(sizeof(GByte*) * nBlockYSize); for(j=0;j<nBlockYSize;j++) { apapbyRawBuffer[i][j] = pabyBuffer + (i * nBlockXSize + j) * nBlockYSize; } } if (bRasterliteOutput) { const char* pszHeader = RASTERLITE_WAVELET_HEADER; VSIFWriteL(pszHeader, 1, strlen(pszHeader) + 1, fp); } /* -------------------------------------------------------------------- */ /* Iterate over blocks */ /* -------------------------------------------------------------------- */ int nBlockXOff, nBlockYOff; CPLErr eErr = CE_None; for(nBlockYOff = 0; eErr == CE_None && nBlockYOff < nYBlocks; nBlockYOff ++) { for(nBlockXOff = 0; eErr == CE_None && nBlockXOff < nXBlocks; nBlockXOff ++) { int bMustMemset = FALSE; int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) { bMustMemset = TRUE; nReqXSize = nXSize - nBlockXOff * nBlockXSize; } if ((nBlockYOff+1) * nBlockYSize > nYSize) { bMustMemset = TRUE; nReqYSize = nYSize - nBlockYOff * nBlockYSize; } if (bMustMemset) memset(pabyBuffer, 0, nBands * nBlockXSize * nBlockYSize); eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyBuffer, nReqXSize, nReqYSize, GDT_Byte, nBands, NULL, 1, nBlockXSize, nBlockXSize * nBlockYSize); int nOutBufSize = nTargetBlockSize; if (eErr == CE_None && nBands == 1) { if (EPS_OK != eps_encode_grayscale_block(apapbyRawBuffer[0], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, pabyOutBuf, &nOutBufSize, (char*) pszFilter, eMode)) { CPLError(CE_Failure, CPLE_AppDefined, "Error occured when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } else if (eErr == CE_None) { if (EPS_OK != eps_encode_truecolor_block( apapbyRawBuffer[0], apapbyRawBuffer[1], apapbyRawBuffer[2], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, eResample, pabyOutBuf, &nOutBufSize, nYRatio, nCbRatio, nCrRatio, (char*) pszFilter, eMode)) { CPLError(CE_Failure, CPLE_AppDefined, "Error occured when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } if (eErr == CE_None) { if ((int)VSIFWriteL(pabyOutBuf, 1, nOutBufSize, fp) != nOutBufSize) eErr = CE_Failure; char chEPSMarker = EPS_MARKER; VSIFWriteL(&chEPSMarker, 1, 1, fp); if (pfnProgress && !pfnProgress( 1.0 * (nBlockYOff * nXBlocks + nBlockXOff + 1) / nBlocks, NULL, pProgressData)) { eErr = CE_Failure; } } } } if (bRasterliteOutput) { const char* pszFooter = RASTERLITE_WAVELET_FOOTER; VSIFWriteL(pszFooter, 1, strlen(pszFooter) + 1, fp); } /* -------------------------------------------------------------------- */ /* Cleanup work buffers */ /* -------------------------------------------------------------------- */ for(i=0;i<nBands;i++) { VSIFree(apapbyRawBuffer[i]); } VSIFree(pabyOutBuf); VSIFree(pabyBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; /* -------------------------------------------------------------------- */ /* Reopen the dataset, unless asked for not (Rasterlite optim) */ /* -------------------------------------------------------------------- */ return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly); }
static CPLString GIFCollectXMPMetadata(VSILFILE* fp) { CPLString osXMP; /* Save current position to avoid disturbing GIF stream decoding */ vsi_l_offset nCurOffset = VSIFTellL(fp); char abyBuffer[2048+1]; VSIFSeekL( fp, 0, SEEK_SET ); /* Loop over file */ int iStartSearchOffset = 1024; while(TRUE) { int nRead = VSIFReadL( abyBuffer + 1024, 1, 1024, fp ); if (nRead <= 0) break; abyBuffer[1024 + nRead] = 0; int i; int iFoundOffset = -1; for(i=iStartSearchOffset;i<1024+nRead - 14;i++) { if (memcmp(abyBuffer + i, "\x21\xff\x0bXMP DataXMP", 14) == 0) { iFoundOffset = i + 14; break; } } iStartSearchOffset = 0; if (iFoundOffset >= 0) { int nSize = 1024 + nRead - iFoundOffset; char* pszXMP = (char*)VSIMalloc(nSize + 1); if (pszXMP == NULL) break; pszXMP[nSize] = 0; memcpy(pszXMP, abyBuffer + iFoundOffset, nSize); /* Read from file until we find a NUL character */ int nLen = (int)strlen(pszXMP); while(nLen == nSize) { char* pszNewXMP = (char*)VSIRealloc(pszXMP, nSize + 1024 + 1); if (pszNewXMP == NULL) break; pszXMP = pszNewXMP; nRead = VSIFReadL( pszXMP + nSize, 1, 1024, fp ); if (nRead <= 0) break; pszXMP[nSize + nRead] = 0; nLen += (int)strlen(pszXMP + nSize); nSize += nRead; } if (nLen > 256 && pszXMP[nLen - 1] == '\x01' && pszXMP[nLen - 2] == '\x02' && pszXMP[nLen - 255] == '\xff' && pszXMP[nLen - 256] == '\x01') { pszXMP[nLen - 256] = 0; osXMP = pszXMP; } VSIFree(pszXMP); break; } if (nRead != 1024) break; memcpy(abyBuffer, abyBuffer + 1024, 1024); } VSIFSeekL( fp, nCurOffset, SEEK_SET ); return osXMP; }
GDALDataset *MEMDataset::Create( const char * /* pszFilename */, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions ) { /* -------------------------------------------------------------------- */ /* Do we want a pixel interleaved buffer? I mostly care about */ /* this to test pixel interleaved IO in other contexts, but it */ /* could be useful to create a directly accessible buffer for */ /* some apps. */ /* -------------------------------------------------------------------- */ bool bPixelInterleaved = false; const char *pszOption = CSLFetchNameValue( papszOptions, "INTERLEAVE" ); if( pszOption && EQUAL(pszOption,"PIXEL") ) bPixelInterleaved = true; /* -------------------------------------------------------------------- */ /* First allocate band data, verifying that we can get enough */ /* memory. */ /* -------------------------------------------------------------------- */ const int nWordSize = GDALGetDataTypeSize(eType) / 8; if( nBands > 0 && nWordSize > 0 && (nBands > INT_MAX / nWordSize || (GIntBig)nXSize * nYSize > GINTBIG_MAX / (nWordSize * nBands)) ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Multiplication overflow"); return NULL; } const GUIntBig nGlobalBigSize = static_cast<GUIntBig>(nWordSize) * nBands * nXSize * nYSize; const size_t nGlobalSize = static_cast<size_t>(nGlobalBigSize); #if SIZEOF_VOIDP == 4 if( static_cast<GUIntBig>(nGlobalSize) != nGlobalBigSize ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocate " CPL_FRMT_GUIB " bytes on this platform.", nGlobalBigSize ); return NULL; } #endif std::vector<GByte*> apbyBandData; bool bAllocOK = true; if( bPixelInterleaved ) { apbyBandData.push_back( reinterpret_cast<GByte *>( VSI_CALLOC_VERBOSE( 1, nGlobalSize ) ) ); if( apbyBandData[0] == NULL ) bAllocOK = FALSE; else { for( int iBand = 1; iBand < nBands; iBand++ ) apbyBandData.push_back( apbyBandData[0] + iBand * nWordSize ); } } else { for( int iBand = 0; iBand < nBands; iBand++ ) { apbyBandData.push_back( reinterpret_cast<GByte *>( VSI_CALLOC_VERBOSE( 1, static_cast<size_t>(nWordSize) * nXSize * nYSize ) ) ); if( apbyBandData[iBand] == NULL ) { bAllocOK = FALSE; break; } } } if( !bAllocOK ) { for( int iBand = 0; iBand < static_cast<int>( apbyBandData.size() ); iBand++ ) { if( apbyBandData[iBand] ) VSIFree( apbyBandData[iBand] ); } return NULL; } /* -------------------------------------------------------------------- */ /* Create the new GTiffDataset object. */ /* -------------------------------------------------------------------- */ MEMDataset *poDS = new MEMDataset(); poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->eAccess = GA_Update; const char *pszPixelType = CSLFetchNameValue( papszOptions, "PIXELTYPE" ); if( pszPixelType && EQUAL(pszPixelType, "SIGNEDBYTE") ) poDS->SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" ); if( bPixelInterleaved ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBands; iBand++ ) { MEMRasterBand *poNewBand = NULL; if( bPixelInterleaved ) poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand], eType, nWordSize * nBands, 0, iBand == 0 ); else poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand], eType, 0, 0, TRUE ); poDS->SetBand( iBand+1, poNewBand ); } /* -------------------------------------------------------------------- */ /* Try to return a regular handle on the file. */ /* -------------------------------------------------------------------- */ return poDS; }
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { OGRErr eErr; bool bMustWriteComma = false; /* -------------------------------------------------------------------- */ /* If we have no valid exterior ring, return POLYGON EMPTY. */ /* -------------------------------------------------------------------- */ if (getExteriorRing() == NULL || getExteriorRing()->IsEmpty() ) { if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) *ppszDstText = CPLStrdup("POLYGON ZM EMPTY"); else if( flags & OGR_G_MEASURED ) *ppszDstText = CPLStrdup("POLYGON M EMPTY"); else if( flags & OGR_G_3D ) *ppszDstText = CPLStrdup("POLYGON Z EMPTY"); else *ppszDstText = CPLStrdup("POLYGON EMPTY"); } else *ppszDstText = CPLStrdup("POLYGON EMPTY"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each ring. */ /* -------------------------------------------------------------------- */ char **papszRings = (char **) CPLCalloc(sizeof(char *),oCC.nCurveCount); size_t nCumulativeLength = 0; size_t nNonEmptyRings = 0; size_t *pnRingBeginning = (size_t *) CPLCalloc(sizeof(size_t),oCC.nCurveCount); for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing]; //poLR->setFlags( getFlags() ); poLR->set3D(Is3D()); poLR->setMeasured(IsMeasured()); if( poLR->getNumPoints() == 0 ) { papszRings[iRing] = NULL; continue; } eErr = poLR->exportToWkt( &(papszRings[iRing]), eWkbVariant ); if( eErr != OGRERR_NONE ) goto error; if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING ZM (") ) pnRingBeginning[iRing] = 14; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING M (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING Z (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING (") ) pnRingBeginning[iRing] = 11; else { CPLAssert( 0 ); } nCumulativeLength += strlen(papszRings[iRing] + pnRingBeginning[iRing]); nNonEmptyRings++; } /* -------------------------------------------------------------------- */ /* Allocate exactly the right amount of space for the */ /* aggregated string. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSI_MALLOC_VERBOSE(nCumulativeLength + nNonEmptyRings + 16); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) strcpy( *ppszDstText, "POLYGON ZM (" ); else if( flags & OGR_G_MEASURED ) strcpy( *ppszDstText, "POLYGON M (" ); else if( flags & OGR_G_3D ) strcpy( *ppszDstText, "POLYGON Z (" ); else strcpy( *ppszDstText, "POLYGON (" ); } else strcpy( *ppszDstText, "POLYGON (" ); nCumulativeLength = strlen(*ppszDstText); for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { if( papszRings[iRing] == NULL ) { CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring."); continue; } if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = true; size_t nRingLen = strlen(papszRings[iRing] + pnRingBeginning[iRing]); memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + pnRingBeginning[iRing], nRingLen ); nCumulativeLength += nRingLen; VSIFree( papszRings[iRing] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszRings ); CPLFree( pnRingBeginning ); return OGRERR_NONE; error: for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) CPLFree(papszRings[iRing]); CPLFree(papszRings); return eErr; }
CPLErr GSAGDataset::ShiftFileContents( VSILFILE *fp, vsi_l_offset nShiftStart, int nShiftSize, const char *pszEOL ) { /* nothing to do for zero-shift */ if( nShiftSize == 0 ) return CE_None; /* make sure start location is sane */ if( nShiftStart < 0 || (nShiftSize < 0 && nShiftStart < static_cast<vsi_l_offset>(-nShiftSize)) ) nShiftStart = (nShiftSize > 0) ? 0 : -nShiftSize; /* get offset at end of file */ if( VSIFSeekL( fp, 0, SEEK_END ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to end of grid file.\n" ); return CE_Failure; } vsi_l_offset nOldEnd = VSIFTellL( fp ); /* If shifting past end, just zero-pad as necessary */ if( nShiftStart >= nOldEnd ) { if( nShiftSize < 0 ) { if( nShiftStart + nShiftSize >= nOldEnd ) return CE_None; if( VSIFSeekL( fp, nShiftStart + nShiftSize, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek near end of file.\n" ); return CE_Failure; } /* ftruncate()? */ for( vsi_l_offset nPos = nShiftStart + nShiftSize; nPos > nOldEnd; nPos++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } return CE_None; } else { for( vsi_l_offset nPos = nOldEnd; nPos < nShiftStart + nShiftSize; nPos++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } return CE_None; } } /* prepare buffer for real shifting */ size_t nBufferSize = (1024 >= abs(nShiftSize)*2) ? 1024 : abs(nShiftSize)*2; char *pabyBuffer = (char *)VSIMalloc( nBufferSize ); if( pabyBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for shift buffer.\n" ); return CE_Failure; } if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of shift in grid file.\n" ); return CE_Failure; } size_t nRead; size_t nOverlap = (nShiftSize > 0) ? nShiftSize : 0; /* If there is overlap, fill buffer with the overlap to start */ if( nOverlap > 0) { nRead = VSIFReadL( (void *)pabyBuffer, 1, nOverlap, fp ); if( nRead < nOverlap && !VSIFEofL( fp ) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Error reading grid file.\n" ); return CE_Failure; } /* overwrite the new space with ' ' */ if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of shift in grid file.\n" ); return CE_Failure; } for( int iFill=0; iFill<nShiftSize; iFill++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } /* if we have already read the entire file, finish it off */ if( VSIFTellL( fp ) >= nOldEnd ) { if( VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ) != nRead ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (Out of space?).\n" ); return CE_Failure; } VSIFree( pabyBuffer ); return CE_None; } } /* iterate over the remainder of the file and shift as requested */ bool bEOF = false; while( !bEOF ) { nRead = VSIFReadL( (void *)(pabyBuffer+nOverlap), 1, nBufferSize - nOverlap, fp ); if( VSIFEofL( fp ) ) bEOF = true; else bEOF = false; if( nRead == 0 && !bEOF ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to read from grid file (possible corruption).\n"); return CE_Failure; } /* FIXME: Should use SEEK_CUR, review integer promotions... */ if( VSIFSeekL( fp, VSIFTellL(fp)-nRead+nShiftSize-nOverlap, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid file (possible corruption).\n" ); return CE_Failure; } size_t nWritten = VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ); if( nWritten != nRead ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } /* shift overlapped contents to the front of the buffer if necessary */ if( nOverlap > 0) memmove(pabyBuffer, pabyBuffer+nRead, nOverlap); } /* write the remainder of the buffer or overwrite leftovers and finish */ if( nShiftSize > 0 ) { size_t nTailSize = nOverlap; while( nTailSize > 0 && isspace( (unsigned char)pabyBuffer[nTailSize-1] ) ) nTailSize--; if( VSIFWriteL( (void *)pabyBuffer, 1, nTailSize, fp ) != nTailSize ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp ) != strlen(pszEOL) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } } else { /* FIXME: ftruncate()? */ /* FIXME: Should use SEEK_CUR, review integer promotions... */ if( VSIFSeekL( fp, VSIFTellL(fp)-strlen(pszEOL), SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid file.\n" ); return CE_Failure; } for( int iPadding=0; iPadding<-nShiftSize; iPadding++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Error writing to grid file.\n" ); return CE_Failure; } } if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp ) != strlen(pszEOL) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } } VSIFree( pabyBuffer ); return CE_None; }
GDALDataset* SIGDEMDataset::CreateCopy( const char * pszFilename, GDALDataset * poSrcDS, int /*bStrict*/, char ** /*papszOptions*/, GDALProgressFunc pfnProgress, void * pProgressData) { const int nBands = poSrcDS->GetRasterCount(); double adfGeoTransform[6] = { }; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver requires a valid GeoTransform."); return nullptr; } if (nBands != 1) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver doesn't support %d bands. Must be 1 band.", nBands); return nullptr; } VSILFILE *fp = VSIFOpenL(pszFilename, "wb"); if (fp == nullptr) { CPLError(CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.", pszFilename); return nullptr; } GDALRasterBand* band = poSrcDS->GetRasterBand(1); const char* pszProjection = poSrcDS->GetProjectionRef(); int32_t nCols = poSrcDS->GetRasterXSize(); int32_t nRows = poSrcDS->GetRasterYSize(); int32_t nCoordinateSystemId = GetCoordinateSystemId(pszProjection); SIGDEMHeader sHeader; sHeader.nCoordinateSystemId = nCoordinateSystemId; sHeader.dfMinX = adfGeoTransform[0]; const char* pszMin = band->GetMetadataItem("STATISTICS_MINIMUM"); if (pszMin == nullptr) { sHeader.dfMinZ = -10000; } else { sHeader.dfMinZ = CPLAtof(pszMin); } sHeader.dfMaxY = adfGeoTransform[3]; const char* pszMax = band->GetMetadataItem("STATISTICS_MAXIMUM"); if (pszMax == nullptr) { sHeader.dfMaxZ = 10000; } else { sHeader.dfMaxZ = CPLAtof(pszMax); } sHeader.nCols = poSrcDS->GetRasterXSize(); sHeader.nRows = poSrcDS->GetRasterYSize(); sHeader.dfXDim = adfGeoTransform[1]; sHeader.dfYDim = -adfGeoTransform[5]; sHeader.dfMaxX = sHeader.dfMinX + sHeader.nCols * sHeader.dfXDim; sHeader.dfMinY = sHeader.dfMaxY - sHeader.nRows * sHeader.dfYDim; sHeader.dfOffsetX = sHeader.dfMinX; sHeader.dfOffsetY = sHeader.dfMinY; if( !sHeader.Write(fp) ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } // Write fill with all NO_DATA values int32_t* row = static_cast<int32_t*>(VSI_MALLOC2_VERBOSE(nCols, sizeof(int32_t))); if( !row ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } std::fill(row, row + nCols, CPL_MSBWORD32(NO_DATA)); for (int i = 0; i < nRows; i++) { if( VSIFWriteL(row, CELL_SIZE_FILE, nCols, fp) != static_cast<size_t>(nCols) ) { VSIFree(row); VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } } VSIFree(row); if (VSIFCloseL(fp) != 0) { return nullptr; } if (nCoordinateSystemId <= 0) { if (!EQUAL(pszProjection, "")) { CPLString osPrjFilename = CPLResetExtension(pszFilename, "prj"); VSILFILE *fpProj = VSIFOpenL(osPrjFilename, "wt"); if (fpProj != nullptr) { OGRSpatialReference oSRS; oSRS.importFromWkt(pszProjection); oSRS.morphToESRI(); char *pszESRIProjection = nullptr; oSRS.exportToWkt(&pszESRIProjection); CPL_IGNORE_RET_VAL( VSIFWriteL(pszESRIProjection, 1, strlen(pszESRIProjection), fpProj)); CPL_IGNORE_RET_VAL(VSIFCloseL(fpProj)); CPLFree(pszESRIProjection); } else { CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.", osPrjFilename.c_str()); } } } GDALOpenInfo oOpenInfo(pszFilename, GA_Update); GDALDataset * poDstDS = Open(&oOpenInfo); if (poDstDS != nullptr && GDALDatasetCopyWholeRaster(poSrcDS, poDstDS, nullptr, pfnProgress, pProgressData) == OGRERR_NONE) { return poDstDS; } else { VSIUnlink(pszFilename); return nullptr; } }
CPLErr GSAGRasterBand::ScanForMinMaxZ() { double *padfRowValues = (double *)VSIMalloc2( nBlockXSize, sizeof(double) ); if( padfRowValues == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate memory for grid row values.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, padfRowValues ); if( eErr != CE_None ) { VSIFree( padfRowValues ); return eErr; } padfRowMinZ[iRow] = DBL_MAX; padfRowMaxZ[iRow] = -DBL_MAX; for( int iCell=0; iCell<nRasterXSize; iCell++ ) { if( AlmostEqual(padfRowValues[iCell], GSAGDataset::dfNODATA_VALUE) ) continue; if( padfRowValues[iCell] < padfRowMinZ[iRow] ) padfRowMinZ[iRow] = padfRowValues[iCell]; if( padfRowValues[iCell] > padfRowMaxZ[iRow] ) padfRowMaxZ[iRow] = padfRowValues[iCell]; dfSum += padfRowValues[iCell]; dfSum2 += padfRowValues[iCell] * padfRowValues[iCell]; nValuesRead++; } if( padfRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = padfRowMinZ[iRow]; nNewMinZRow = iRow; } if( padfRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = padfRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( padfRowValues ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
OGRErr OGRLineString::exportToWkt( char ** ppszDstText ) const { int nMaxString = nPointCount * 20 * 3 + 20; int nRetLen = 0; /* -------------------------------------------------------------------- */ /* Handle special empty case. */ /* -------------------------------------------------------------------- */ if( nPointCount == 0 ) { *ppszDstText = CPLStrdup("LINESTRING(EMPTY)"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* General case. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc( nMaxString ); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; sprintf( *ppszDstText, "%s (", getGeometryName() ); for( int i = 0; i < nPointCount; i++ ) { if( nMaxString <= (int) strlen(*ppszDstText+nRetLen) + 32 + nRetLen ) { CPLDebug( "OGR", "OGRLineString::exportToWkt() ... buffer overflow.\n" "nMaxString=%d, strlen(*ppszDstText) = %d, i=%d\n" "*ppszDstText = %s", nMaxString, strlen(*ppszDstText), i, *ppszDstText ); VSIFree( *ppszDstText ); *ppszDstText = NULL; return OGRERR_NOT_ENOUGH_MEMORY; } if( i > 0 ) strcat( *ppszDstText + nRetLen, "," ); nRetLen += strlen(*ppszDstText + nRetLen); if( getCoordinateDimension() == 3 ) OGRMakeWktCoordinate( *ppszDstText + nRetLen, paoPoints[i].x, paoPoints[i].y, padfZ[i] ); else OGRMakeWktCoordinate( *ppszDstText + nRetLen, paoPoints[i].x, paoPoints[i].y, 0.0 ); nRetLen += strlen(*ppszDstText + nRetLen); } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }