// Read from a RAM Tiff. This is rather generic CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img) { CPLString fname = uniq_memfname("mrf_tif_read"); VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false); // Comes back opened, but we can't use it if (fp) VSIFCloseL(fp); else { CPLError(CE_Failure,CPLE_AppDefined, CPLString().Printf("MRF: TIFF, can't open %s as a temp file", fname.c_str())); return CE_Failure; } GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly)); if (!fp) { CPLError(CE_Failure,CPLE_AppDefined, CPLString().Printf("MRF: TIFF, can't open page as a Tiff")); return CE_Failure; } CPLErr ret; // Bypass the GDAL caching if (img.pagesize.c == 1) { ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer); } else { ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y, dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, NULL, 0,0,0); } GDALClose(poTiff); if (CE_None != ret) return ret; VSIUnlink(fname); return CE_None; }
CPLString BufferToVSIFile(GByte *buffer, size_t size) { CPLString file_name; file_name.Printf("/vsimem/wms/%p/wmsresult.dat", buffer); VSILFILE *f = VSIFileFromMemBuffer(file_name.c_str(), buffer, size, false); if (f == nullptr) return CPLString(); VSIFCloseL(f); return file_name; }
GDALDataset* geGdalVSI::VsiGdalOpenInternalWrap( std::string* const vsifile, const std::string& image_alpha) { GDALDatasetH hvsi_ds; khMutex &mutex = GetMutex(); khLockGuard lock(mutex); *vsifile = UniqueVSIFilename(); VSIFCloseL(VSIFileFromMemBuffer((*vsifile).c_str(), reinterpret_cast<GByte*> (const_cast<char*>(&(image_alpha[0]))), image_alpha.size(), FALSE)); hvsi_ds = GDALOpenEx((*vsifile).c_str(), GA_ReadOnly, kGdalAllowedDrivers, NULL, NULL); return static_cast<GDALDataset*>(hvsi_ds); }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr ); if ( !hDS ) { VSIUnlink( TO8( randomFileName ) ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 ); if ( !ogrLayer ) { OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; } OGRFeatureH oFeat; while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) ) { QgsFeature feat = readOgrFeature( oFeat, fields, encoding ); if ( feat.isValid() ) features << feat; OGR_F_Destroy( oFeat ); } OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; }
// Read from a RAM Tiff. This is rather generic static CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img) { CPLString fname = uniq_memfname("mrf_tif_read"); VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false); // Comes back opened, but we can't use it if (fp) VSIFCloseL(fp); else { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't open %s as a temp file", fname.c_str()); return CE_Failure; } #if GDAL_VERSION_MAJOR >= 2 const char* const apszAllowedDrivers[] = { "GTiff", NULL }; GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpenEx(fname, GDAL_OF_RASTER, apszAllowedDrivers, NULL, NULL)); #else GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly)); #endif if (poTiff == NULL) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't open page as a Tiff"); VSIUnlink(fname); return CE_Failure; } CPLErr ret; // Bypass the GDAL caching if (img.pagesize.c == 1) { ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer); } else { ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y, dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, NULL, 0,0,0 #if GDAL_VERSION_MAJOR >= 2 ,NULL #endif ); } GDALClose(poTiff); VSIUnlink(fname); return ret; }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString &string, const QgsFields &fields, QTextCodec *encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QStringLiteral( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(), reinterpret_cast< GByte * >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); gdal::ogr_datasource_unique_ptr hDS( OGROpen( randomFileName.toUtf8().constData(), false, nullptr ) ); if ( !hDS ) { VSIUnlink( randomFileName.toUtf8().constData() ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 ); if ( !ogrLayer ) { hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; } gdal::ogr_feature_unique_ptr oFeat; while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat ) { QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding ); if ( feat.isValid() ) features << feat; } hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; }
bool OsmAnd::HeightmapTileProvider_P::obtainData( const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapTiledData>& outTiledData, const IQueryController* const queryController) { // Obtain raw data from DB QByteArray data; bool ok = _tileDb.obtainTileData(tileId, zoom, data); if (!ok || data.length() == 0) { // There was no data at all, to avoid further requests, mark this tile as empty outTiledData.reset(); return true; } // We have the data, use GDAL to decode this GeoTIFF const auto tileSize = getTileSize(); bool success = false; QString vmemFilename; vmemFilename.sprintf("/vsimem/heightmapTile@%p", data.data()); VSIFileFromMemBuffer(qPrintable(vmemFilename), reinterpret_cast<GByte*>(data.data()), data.length(), FALSE); auto dataset = reinterpret_cast<GDALDataset*>(GDALOpen(qPrintable(vmemFilename), GA_ReadOnly)); if (dataset != nullptr) { bool bad = false; bad = bad || dataset->GetRasterCount() != 1; bad = bad || dataset->GetRasterXSize() != tileSize; bad = bad || dataset->GetRasterYSize() != tileSize; if (bad) { if (dataset->GetRasterCount() != 1) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %d bands instead of 1", tileId.x, tileId.y, zoom, dataset->GetRasterCount()); if (dataset->GetRasterXSize() != tileSize || dataset->GetRasterYSize() != tileSize) { LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %dx%x size instead of %d", tileId.x, tileId.y, zoom, dataset->GetRasterXSize(), dataset->GetRasterYSize(), tileSize); } } else { auto band = dataset->GetRasterBand(1); bad = bad || band->GetColorTable() != nullptr; bad = bad || band->GetRasterDataType() != GDT_Int16; if (bad) { if (band->GetColorTable() != nullptr) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has color table", tileId.x, tileId.y, zoom); if (band->GetRasterDataType() != GDT_Int16) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %s data type in band 1", tileId.x, tileId.y, zoom, GDALGetDataTypeName(band->GetRasterDataType())); } else { auto buffer = new float[tileSize*tileSize]; auto res = dataset->RasterIO(GF_Read, 0, 0, tileSize, tileSize, buffer, tileSize, tileSize, GDT_Float32, 1, nullptr, 0, 0, 0); if (res != CE_None) { delete[] buffer; LogPrintf(LogSeverityLevel::Error, "Failed to decode height tile %dx%d@%d: %s", tileId.x, tileId.y, zoom, CPLGetLastErrorMsg()); } else { outTiledData.reset(new ElevationDataTile(buffer, sizeof(float)*tileSize, tileSize, tileId, zoom)); success = true; } } } GDALClose(dataset); } VSIUnlink(qPrintable(vmemFilename)); return success; }
CPL_C_END int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { #ifndef HAVE_JASPER // J2K_SUBFILE method // create "memory file" from buffer int fileNumber = 0; VSIStatBufL sStatBuf; CPLString osFileName = "/vsimem/work.jpc"; // ensure we don't overwrite an existing file accidentally while ( VSIStatL( osFileName, &sStatBuf ) == 0 ) { osFileName.Printf( "/vsimem/work%d.jpc", ++fileNumber ); } VSIFCloseL( VSIFileFromMemBuffer( osFileName, (unsigned char*)injpc, bufsize, FALSE ) ); // TRUE to let vsi delete the buffer when done // Open memory buffer for reading GDALDataset* poJ2KDataset = (GDALDataset *) GDALOpen( osFileName, GA_ReadOnly ); if( poJ2KDataset == NULL ) { printf("dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n" "Is the JPEG2000 driver available?" ); return -3; } if( poJ2KDataset->GetRasterCount() != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // Fulfill administration: initialize parameters required for RasterIO int nXSize = poJ2KDataset->GetRasterXSize(); int nYSize = poJ2KDataset->GetRasterYSize(); int nXOff = 0; int nYOff = 0; int nBufXSize = nXSize; int nBufYSize = nYSize; GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int* int nBandCount = 1; int* panBandMap = NULL; int nPixelSpace = 0; int nLineSpace = 0; int nBandSpace = 0; // Decompress the JPEG2000 into the output integer array. poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize, outfld, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace, NULL ); // close source file, and "unlink" it. GDALClose( poJ2KDataset ); VSIUnlink( osFileName ); return 0; #else // JasPer method int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return = %d \n",ier); return -3; } pcmpt=image->cmpts_[0]; // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; for (i=0; i<pcmpt->height_; i++) for (j=0; j<pcmpt->width_; j++) outfld[k++]=data->rows_[i][j]; // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; #endif }
void GDALJP2AbstractDataset::LoadVectorLayers(int bOpenRemoteResources) { char** papszGMLJP2 = GetMetadata("xml:gml.root-instance"); if( papszGMLJP2 == NULL ) return; GDALDriver* poMemDriver = (GDALDriver*)GDALGetDriverByName("Memory"); if( poMemDriver == NULL ) return; CPLXMLNode* psRoot = CPLParseXMLString(papszGMLJP2[0]); if( psRoot == NULL ) return; CPLXMLNode* psCC = CPLGetXMLNode(psRoot, "=gmljp2:GMLJP2CoverageCollection"); if( psCC == NULL ) { CPLDestroyXMLNode(psRoot); return; } // Find feature collections CPLXMLNode* psCCChildIter = psCC->psChild; int nLayersAtCC = 0; int nLayersAtGC = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:feature") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL ) continue; CPLXMLNode* psFC = NULL; int bFreeFC = FALSE; CPLString osGMLTmpFile; CPLXMLNode* psChild = psGCorGMLJP2FeaturesChildIter->psChild; if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && strncmp(psChild->psChild->pszValue, "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = psChild->psChild->pszValue + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { psFC = CPLParseXMLString(papszBoxData[0]); bFreeFC = TRUE; } else { CPLDebug("GMLJP2", "gmljp2:feature references %s, but no corresponding box found", psChild->psChild->pszValue); } } if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && (strncmp(psChild->psChild->pszValue, "http://", strlen("http://")) == 0 || strncmp(psChild->psChild->pszValue, "https://", strlen("https://")) == 0) ) { if( !bOpenRemoteResources ) CPLDebug("GMLJP2", "Remote feature collection %s mentionned in GMLJP2 box", psChild->psChild->pszValue); else osGMLTmpFile = "/vsicurl/" + CPLString(psChild->psChild->pszValue); } else if( psChild->eType == CXT_Element && strstr(psChild->pszValue, "FeatureCollection") != NULL ) { psFC = psChild; } if( psFC == NULL && osGMLTmpFile.size() == 0 ) continue; if( psFC != NULL ) { osGMLTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.gml", this); // Create temporary .gml file CPLSerializeXMLTreeToFile(psFC, osGMLTmpFile); } CPLDebug("GMLJP2", "Found a FeatureCollection at %s level", (bIsGC) ? "GridCoverage" : "CoverageCollection"); CPLString osXSDTmpFile; if( psFC ) { // Try to localize its .xsd schema in a GMLJP2 auxiliary box const char* pszSchemaLocation = CPLGetXMLValue(psFC, "xsi:schemaLocation", NULL); if( pszSchemaLocation ) { char **papszTokens = CSLTokenizeString2( pszSchemaLocation, " \t\n", CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if( (CSLCount(papszTokens) % 2) == 0 ) { for(char** papszIter = papszTokens; *papszIter; papszIter += 2 ) { if( strncmp(papszIter[1], "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = papszIter[1] + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { osXSDTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.xsd", this); VSIFCloseL(VSIFileFromMemBuffer(osXSDTmpFile, (GByte*)papszBoxData[0], strlen(papszBoxData[0]), FALSE)); } else { CPLDebug("GMLJP2", "Feature collection references %s, but no corresponding box found", papszIter[1]); } break; } } } CSLDestroy(papszTokens); } if( bFreeFC ) { CPLDestroyXMLNode(psFC); psFC = NULL; } } GDALDriverH hDrv = GDALIdentifyDriver(osGMLTmpFile, NULL); GDALDriverH hGMLDrv = GDALGetDriverByName("GML"); if( hDrv != NULL && hDrv == hGMLDrv ) { char* apszOpenOptions[2]; apszOpenOptions[0] = (char*) "FORCE_SRS_DETECTION=YES"; apszOpenOptions[1] = NULL; GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osGMLTmpFile, GDAL_OF_VECTOR, NULL, apszOpenOptions, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; if( bIsGC ) pszLayerName = CPLSPrintf("FC_GridCoverage_%d_%s", ++nLayersAtGC, poSrcLyr->GetName()); else pszLayerName = CPLSPrintf("FC_CoverageCollection_%d_%s", ++nLayersAtCC, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); // In case we don't have a schema, a .gfs might have been generated VSIUnlink(CPLSPrintf("/vsimem/gmljp2/%p/my.gfs", this)); } } else { CPLDebug("GMLJP2", "No GML driver found to read feature collection"); } if( strncmp(osGMLTmpFile, "/vsicurl/", strlen("/vsicurl/")) != 0 ) VSIUnlink(osGMLTmpFile); if( osXSDTmpFile.size() ) VSIUnlink(osXSDTmpFile); } } // Find annotations psCCChildIter = psCC->psChild; int nAnnotations = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); if( !bIsGC ) continue; CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:annotation") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL || psGCorGMLJP2FeaturesChildIter->psChild->eType != CXT_Element || strstr(psGCorGMLJP2FeaturesChildIter->psChild->pszValue, "kml") == NULL ) continue; CPLDebug("GMLJP2", "Found a KML annotation"); // Create temporary .kml file CPLXMLNode* psKML = psGCorGMLJP2FeaturesChildIter->psChild; CPLString osKMLTmpFile(CPLSPrintf("/vsimem/gmljp2/%p/my.kml", this)); CPLSerializeXMLTreeToFile(psKML, osKMLTmpFile); GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osKMLTmpFile, GDAL_OF_VECTOR, NULL, NULL, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; pszLayerName = CPLSPrintf("Annotation_%d_%s", ++nAnnotations, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); } else { CPLDebug("GMLJP2", "No KML/LIBKML driver found to read annotation"); } VSIUnlink(osKMLTmpFile); } } CPLDestroyXMLNode(psRoot); }
bool OGRGeoJSONSeqDataSource::Open( GDALOpenInfo* poOpenInfo, GeoJSONSourceType nSrcType) { VSILFILE* fp = nullptr; CPLString osLayerName("GeoJSONSeq"); const char* pszUnprefixedFilename = poOpenInfo->pszFilename; if (STARTS_WITH_CI(poOpenInfo->pszFilename, "GeoJSONSeq:") ) { pszUnprefixedFilename = poOpenInfo->pszFilename + strlen("GeoJSONSeq:"); } if( nSrcType == eGeoJSONSourceFile ) { if (pszUnprefixedFilename != poOpenInfo->pszFilename) { osLayerName = CPLGetBasename(pszUnprefixedFilename); fp = VSIFOpenL( pszUnprefixedFilename, "rb"); } else { osLayerName = CPLGetBasename(poOpenInfo->pszFilename); fp = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; } } else if( nSrcType == eGeoJSONSourceText ) { m_osTmpFile = CPLSPrintf("/vsimem/geojsonseq/%p", this); fp = VSIFileFromMemBuffer( m_osTmpFile.c_str(), reinterpret_cast<GByte*>(CPLStrdup(poOpenInfo->pszFilename)), strlen(poOpenInfo->pszFilename), true ); } else if( nSrcType == eGeoJSONSourceService ) { char* pszStoredContent = OGRGeoJSONDriverStealStoredContent(pszUnprefixedFilename); if( pszStoredContent ) { if( !GeoJSONSeqIsObject( pszStoredContent) ) { OGRGeoJSONDriverStoreContent( poOpenInfo->pszFilename, pszStoredContent ); return false; } else { m_osTmpFile = CPLSPrintf("/vsimem/geojsonseq/%p", this); fp = VSIFileFromMemBuffer( m_osTmpFile.c_str(), reinterpret_cast<GByte*>(pszStoredContent), strlen(pszStoredContent), true ); } } else { const char* const papsOptions[] = { "HEADERS=Accept: text/plain, application/json", nullptr }; CPLHTTPResult* pResult = CPLHTTPFetch( pszUnprefixedFilename, papsOptions ); if( nullptr == pResult || 0 == pResult->nDataLen || 0 != CPLGetLastErrorNo() ) { CPLHTTPDestroyResult( pResult ); return false; } if( 0 != pResult->nStatus ) { CPLError( CE_Failure, CPLE_AppDefined, "Curl reports error: %d: %s", pResult->nStatus, pResult->pszErrBuf ); CPLHTTPDestroyResult( pResult ); return false; } m_osTmpFile = CPLSPrintf("/vsimem/geojsonseq/%p", this); fp = VSIFileFromMemBuffer( m_osTmpFile.c_str(), pResult->pabyData, pResult->nDataLen, true ); pResult->pabyData = nullptr; pResult->nDataLen = 0; CPLHTTPDestroyResult( pResult ); } } if( fp == nullptr ) { return false; } SetDescription( poOpenInfo->pszFilename ); m_poLayer.reset(new OGRGeoJSONSeqLayer(this, osLayerName.c_str(), fp)); return true; }
OGRLayer * OGRSQLiteExecuteSQL( GDALDataset* poDS, const char *pszStatement, OGRGeometry *poSpatialFilter, CPL_UNUSED const char *pszDialect ) { char* pszTmpDBName = (char*) CPLMalloc(256); snprintf(pszTmpDBName, 256, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName); OGRSQLiteDataSource* poSQLiteDS = NULL; int nRet; int bSpatialiteDB = FALSE; CPLString osOldVal; const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL); if( pszOldVal != NULL ) { osOldVal = pszOldVal; pszOldVal = osOldVal.c_str(); } /* -------------------------------------------------------------------- */ /* Create in-memory sqlite/spatialite DB */ /* -------------------------------------------------------------------- */ #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Creating an empty SpatiaLite DB (with spatial_ref_sys populated */ /* has a significant cost. So at the first attempt, let's make */ /* one and cache it for later use. */ /* -------------------------------------------------------------------- */ #if 1 static size_t nEmptyDBSize = 0; static GByte* pabyEmptyDB = NULL; { static CPLMutex* hMutex = NULL; CPLMutexHolder oMutexHolder(&hMutex); static int bTried = FALSE; if( !bTried && CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { bTried = TRUE; char* pszCachedFilename = (char*) CPLMalloc(256); snprintf(pszCachedFilename, 256, "/vsimem/ogr2sqlite/reference_%p.db", pszCachedFilename); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource(); nRet = poCachedDS->Create( pszCachedFilename, papszOptions ); CSLDestroy(papszOptions); papszOptions = NULL; delete poCachedDS; if( nRet ) { /* Note: the reference file keeps the ownership of the data, so that */ /* it gets released with VSICleanupFileManager() */ vsi_l_offset nEmptyDBSizeLarge = 0; pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSizeLarge, FALSE ); nEmptyDBSize = static_cast<size_t>(nEmptyDBSizeLarge); } CPLFree( pszCachedFilename ); } } /* The following configuration option is useful mostly for debugging/testing */ if( pabyEmptyDB != NULL && CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { GByte* pabyEmptyDBClone = (GByte*)VSI_MALLOC_VERBOSE(nEmptyDBSize); if( pabyEmptyDBClone == NULL ) { CPLFree(pszTmpDBName); return NULL; } memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize); VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE )); poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Open( pszTmpDBName, TRUE, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { /* should not happen really ! */ delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bSpatialiteDB = TRUE; } #else /* No caching version */ poSQLiteDS = new OGRSQLiteDataSource(); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); CSLDestroy(papszOptions); papszOptions = NULL; if( nRet ) { bSpatialiteDB = TRUE; } #endif else { delete poSQLiteDS; poSQLiteDS = NULL; #else // HAVE_SPATIALITE if( true ) { #endif // HAVE_SPATIALITE poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } } /* -------------------------------------------------------------------- */ /* Attach the Virtual Table OGR2SQLITE module to it. */ /* -------------------------------------------------------------------- */ OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS); sqlite3* hDB = poSQLiteDS->GetDB(); /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); std::set<LayerDesc>::iterator oIter = oSetLayers.begin(); if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 ) CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str()); pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */ int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos ); /* -------------------------------------------------------------------- */ /* For each of those tables, create a Virtual Table. */ /* -------------------------------------------------------------------- */ OGRLayer* poSingleSrcLayer = NULL; for(; oIter != oSetLayers.end(); ++oIter) { const LayerDesc& oLayerDesc = *oIter; /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s", oLayerDesc.osOriginalStr.c_str(), oLayerDesc.osSubstitutedName.c_str(), oLayerDesc.osDSName.c_str(), oLayerDesc.osLayerName.c_str());*/ CPLString osSQL; OGRLayer* poLayer = NULL; CPLString osTableName; int nExtraDS; if( oLayerDesc.osDSName.size() == 0 ) { poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName); /* Might be a false positive (unlikely) */ if( poLayer == NULL ) continue; osTableName = oLayerDesc.osLayerName; nExtraDS = -1; } else { OGRDataSource* poOtherDS = (OGRDataSource* ) OGROpen(oLayerDesc.osDSName, FALSE, NULL); if( poOtherDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open datasource '%s'", oLayerDesc.osDSName.c_str() ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName); if( poLayer == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find layer '%s' in '%s'", oLayerDesc.osLayerName.c_str(), oLayerDesc.osDSName.c_str() ); delete poOtherDS; delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } osTableName = oLayerDesc.osSubstitutedName; nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS); } if( oSetLayers.size() == 1 ) poSingleSrcLayer = poLayer; osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d,%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(), bFoundOGRStyle, TRUE/*bExposeOGRNativeData*/); char* pszErrMsg = NULL; int rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create virtual table for layer '%s' : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); continue; } for(int i=0; i<poLayer->GetLayerDefn()->GetGeomFieldCount(); i++) { OGR2SQLITEDealWithSpatialColumn(poLayer, i, oLayerDesc, osTableName, poSQLiteDS, hDB, bSpatialiteDB, oSetLayers, oSetSpatialIndex); } } /* -------------------------------------------------------------------- */ /* Reload, so that virtual tables are recognized */ /* -------------------------------------------------------------------- */ poSQLiteDS->ReloadLayers(); /* -------------------------------------------------------------------- */ /* Prepare the statement. */ /* -------------------------------------------------------------------- */ /* This will speed-up layer creation */ /* ORDER BY are costly to evaluate and are not necessary to establish */ /* the layer definition. */ int bUseStatementForGetNextFeature = TRUE; int bEmptyLayer = FALSE; sqlite3_stmt *hSQLStmt = NULL; int rc = sqlite3_prepare( hDB, pszStatement, -1, &hSQLStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_prepare(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); if( hSQLStmt != NULL ) { sqlite3_finalize( hSQLStmt ); } delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } /* -------------------------------------------------------------------- */ /* Do we get a resultset? */ /* -------------------------------------------------------------------- */ rc = sqlite3_step( hSQLStmt ); if( rc != SQLITE_ROW ) { if ( rc != SQLITE_DONE ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_step(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } if( !STARTS_WITH_CI(pszStatement, "SELECT ") ) { sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bUseStatementForGetNextFeature = FALSE; bEmptyLayer = TRUE; } /* -------------------------------------------------------------------- */ /* Create layer. */ /* -------------------------------------------------------------------- */ OGRSQLiteSelectLayer *poLayer = NULL; poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName, poSQLiteDS, pszStatement, hSQLStmt, bUseStatementForGetNextFeature, bEmptyLayer ); if( poSpatialFilter != NULL ) poLayer->SetSpatialFilter( 0, poSpatialFilter ); if( poSingleSrcLayer != NULL ) poLayer->SetMetadata( poSingleSrcLayer->GetMetadata( "NATIVE_DATA" ), "NATIVE_DATA" ); return poLayer; } /************************************************************************/ /* OGRSQLiteGetReferencedLayers() */ /************************************************************************/ std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement) { /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); return oSetLayers; }
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { VSILFILE* fp = VSIFileFromMemBuffer( "/vsimem/test.tar", reinterpret_cast<GByte*>(const_cast<uint8_t*>(buf)), len, FALSE ); VSIFCloseL(fp); CPLPushErrorHandler(CPLQuietErrorHandler); char** papszArgv = nullptr; // Prevent generating too big output raster. Make sure they are set at // the beginning to avoid being accidentally eaten by invalid arguments // afterwards. papszArgv = CSLAddString(papszArgv, "-limit_outsize"); papszArgv = CSLAddString(papszArgv, "1000000"); fp = VSIFOpenL("/vsitar//vsimem/test.tar/cmd.txt", "rb"); if( fp != nullptr ) { const char* pszLine = nullptr; while( (pszLine = CPLReadLineL(fp)) != nullptr ) { if( !EQUAL(pszLine, "-limit_outsize") ) papszArgv = CSLAddString(papszArgv, pszLine); } VSIFCloseL(fp); } int nXDim = -1; int nYDim = -1; bool bXDimPct = false; bool bYDimPct = false; bool bNonNearestResampling = false; int nBlockXSize = 0; int nBlockYSize = 0; bool bStatsEnabled = false; bool bHFA = false; if( papszArgv != nullptr ) { int nCount = CSLCount(papszArgv); for( int i = 0; i < nCount; i++ ) { if( EQUAL(papszArgv[i], "-outsize") && i + 2 < nCount ) { nXDim = atoi(papszArgv[i+1]); bXDimPct = (papszArgv[i+1][0] != '\0' && papszArgv[i+1][strlen(papszArgv[i+1])-1] == '%'); nYDim = atoi(papszArgv[i+2]); bYDimPct = (papszArgv[i+2][0] != '\0' && papszArgv[i+2][strlen(papszArgv[i+2])-1] == '%'); } else if( EQUAL(papszArgv[i], "-r") && i + 1 < nCount ) { bNonNearestResampling = !STARTS_WITH_CI(papszArgv[i+1], "NEAR"); } else if( EQUAL(papszArgv[i], "-co") && i + 1 < nCount ) { if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKSIZE=") ) { nBlockXSize = std::max(nBlockXSize, atoi(papszArgv[i+1]+strlen("BLOCKSIZE="))); nBlockYSize = std::max(nBlockYSize, atoi(papszArgv[i+1]+strlen("BLOCKSIZE="))); } else if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKXSIZE=") ) { nBlockXSize = std::max(nBlockXSize, atoi(papszArgv[i+1]+strlen("BLOCKXSIZE="))); } else if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKYSIZE=") ) { nBlockYSize = std::max(nBlockYSize, atoi(papszArgv[i+1]+strlen("BLOCKYSIZE="))); } } else if( EQUAL(papszArgv[i], "-stats") ) { bStatsEnabled = true; } else if( EQUAL(papszArgv[i], "-of") && i + 1 < nCount ) { bHFA = EQUAL( papszArgv[i+1], "HFA" ); } } if( bHFA ) { // Disable statistics computation for HFA, as it can be time // consuming. // See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10067 papszArgv = CSLInsertString(papszArgv, 0, "-co"); papszArgv = CSLInsertString(papszArgv, 1, "STATISTICS=NO"); } } if( papszArgv != nullptr ) { GDALTranslateOptions* psOptions = GDALTranslateOptionsNew(papszArgv, nullptr); if( psOptions ) { GDALDatasetH hSrcDS = GDALOpen( "/vsitar//vsimem/test.tar/in", GA_ReadOnly ); if( hSrcDS != nullptr ) { // Also check that reading the source doesn't involve too // much memory GDALDataset* poSrcDS = reinterpret_cast<GDALDataset*>(hSrcDS); int nBands = poSrcDS->GetRasterCount(); if( nBands < 10 ) { // Prevent excessive downsampling which might require huge // memory allocation bool bOKForResampling = true; if( bNonNearestResampling && nXDim >= 0 && nYDim >= 0 ) { if( bXDimPct && nXDim > 0 ) { nXDim = static_cast<int>( poSrcDS->GetRasterXSize() / 100.0 * nXDim); } if( bYDimPct && nYDim > 0 ) { nYDim = static_cast<int>( poSrcDS->GetRasterYSize() / 100.0 * nYDim); } if( nXDim > 0 && poSrcDS->GetRasterXSize() / nXDim > 100 ) bOKForResampling = false; if( nYDim > 0 && poSrcDS->GetRasterYSize() / nYDim > 100 ) bOKForResampling = false; } bool bOKForSrc = true; if( nBands ) { const int nDTSize = GDALGetDataTypeSizeBytes( poSrcDS->GetRasterBand(1)->GetRasterDataType() ); vsi_l_offset nSize = static_cast<vsi_l_offset>(nBands) * poSrcDS->GetRasterXSize() * poSrcDS->GetRasterYSize() * nDTSize; if( nSize > 10 * 1024 * 1024 ) { bOKForSrc = false; } int nBXSize = 0, nBYSize = 0; GDALGetBlockSize( GDALGetRasterBand(hSrcDS, 1), &nBXSize, &nBYSize ); const char* pszInterleave = GDALGetMetadataItem( hSrcDS, "INTERLEAVE", "IMAGE_STRUCTURE" ); int nSimultaneousBands = (pszInterleave && EQUAL(pszInterleave, "PIXEL")) ? nBands : 1; if( static_cast<GIntBig>(nSimultaneousBands)* nBXSize * nBYSize * nDTSize > 10 * 1024 * 1024 ) { bOKForSrc = false; } if( static_cast<GIntBig>(nBlockXSize) * nBlockYSize > 10 * 1024 * 1024 / (nBands * nDTSize) ) { bOKForSrc = false; } } bool bOKForStats = true; if( nBands && bStatsEnabled ) { // Other types might be too slow with sanitization enabled // See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10029 bOKForStats = poSrcDS->GetRasterBand(1)->GetRasterDataType() == GDT_Byte; } if( bOKForSrc && bOKForResampling && bOKForStats ) { GDALDatasetH hOutDS = GDALTranslate("/vsimem/out", hSrcDS, psOptions, nullptr); if( hOutDS ) GDALClose(hOutDS); } } GDALClose(hSrcDS); } GDALTranslateOptionsFree(psOptions); } } CSLDestroy(papszArgv); VSIRmdirRecursive("/vsimem/"); CPLPopErrorHandler(); return 0; }
static CPLXMLNode* GDALWMSDatasetGetConfigFromArcGISJSON(const char* pszURL, const char* pszContent) { /* TODO : use JSONC library to parse. But we don't really need it */ CPLString osTmpFilename(CPLSPrintf("/vsimem/WMSArcGISJSON%p", pszURL)); VSILFILE* fp = VSIFileFromMemBuffer( osTmpFilename, (GByte*)pszContent, strlen(pszContent), FALSE); const char* pszLine; int nTileWidth = -1, nTileHeight = -1; int nWKID = -1; double dfMinX = 0, dfMaxY = 0; int bHasMinX = FALSE, bHasMaxY = FALSE; int nExpectedLevel = 0; double dfBaseResolution = 0; while((pszLine = CPLReadLine2L(fp, 4096, NULL)) != NULL) { const char* pszPtr; if ((pszPtr = strstr(pszLine, "\"rows\" : ")) != NULL) nTileHeight = atoi(pszPtr + strlen("\"rows\" : ")); else if ((pszPtr = strstr(pszLine, "\"cols\" : ")) != NULL) nTileWidth = atoi(pszPtr + strlen("\"cols\" : ")); else if ((pszPtr = strstr(pszLine, "\"wkid\" : ")) != NULL) { int nVal = atoi(pszPtr + strlen("\"wkid\" : ")); if (nWKID < 0) nWKID = nVal; else if (nWKID != nVal) { CPLDebug("WMS", "Inconsisant WKID values : %d, %d", nVal, nWKID); VSIFCloseL(fp); return NULL; } } else if ((pszPtr = strstr(pszLine, "\"x\" : ")) != NULL) { bHasMinX = TRUE; dfMinX = CPLAtofM(pszPtr + strlen("\"x\" : ")); } else if ((pszPtr = strstr(pszLine, "\"y\" : ")) != NULL) { bHasMaxY = TRUE; dfMaxY = CPLAtofM(pszPtr + strlen("\"y\" : ")); } else if ((pszPtr = strstr(pszLine, "\"level\" : ")) != NULL) { int nLevel = atoi(pszPtr + strlen("\"level\" : ")); if (nLevel != nExpectedLevel) { CPLDebug("WMS", "Expected level : %d, got : %d", nExpectedLevel, nLevel); VSIFCloseL(fp); return NULL; } if ((pszPtr = strstr(pszLine, "\"resolution\" : ")) != NULL) { double dfResolution = CPLAtofM(pszPtr + strlen("\"resolution\" : ")); if (nLevel == 0) dfBaseResolution = dfResolution; } else { CPLDebug("WMS", "Did not get resolution"); VSIFCloseL(fp); return NULL; } nExpectedLevel ++; } } VSIFCloseL(fp); int nLevelCount = nExpectedLevel - 1; if (nLevelCount < 1) { CPLDebug("WMS", "Did not get levels"); return NULL; } if (nTileWidth <= 0) { CPLDebug("WMS", "Did not get tile width"); return NULL; } if (nTileHeight <= 0) { CPLDebug("WMS", "Did not get tile height"); return NULL; } if (nWKID <= 0) { CPLDebug("WMS", "Did not get WKID"); return NULL; } if (!bHasMinX) { CPLDebug("WMS", "Did not get min x"); return NULL; } if (!bHasMaxY) { CPLDebug("WMS", "Did not get max y"); return NULL; } if (nWKID == 102100) nWKID = 3857; const char* pszEndURL = strstr(pszURL, "/MapServer?f=json"); CPLAssert(pszEndURL); CPLString osURL(pszURL); osURL.resize(pszEndURL - pszURL); double dfMaxX = dfMinX + dfBaseResolution * nTileWidth; double dfMinY = dfMaxY - dfBaseResolution * nTileHeight; int nTileCountX = 1; if (fabs(dfMinX - -180) < 1e-4 && fabs(dfMaxY - 90) < 1e-4 && fabs(dfMinY - -90) < 1e-4) { nTileCountX = 2; dfMaxX = 180; } CPLString osXML = CPLSPrintf( "<GDAL_WMS>\n" " <Service name=\"TMS\">\n" " <ServerUrl>%s/MapServer/tile/${z}/${y}/${x}</ServerUrl>\n" " </Service>\n" " <DataWindow>\n" " <UpperLeftX>%.8f</UpperLeftX>\n" " <UpperLeftY>%.8f</UpperLeftY>\n" " <LowerRightX>%.8f</LowerRightX>\n" " <LowerRightY>%.8f</LowerRightY>\n" " <TileLevel>%d</TileLevel>\n" " <TileCountX>%d</TileCountX>\n" " <YOrigin>top</YOrigin>\n" " </DataWindow>\n" " <Projection>EPSG:%d</Projection>\n" " <BlockSizeX>%d</BlockSizeX>\n" " <BlockSizeY>%d</BlockSizeY>\n" " <Cache/>\n" "</GDAL_WMS>\n", osURL.c_str(), dfMinX, dfMaxY, dfMaxX, dfMinY, nLevelCount, nTileCountX, nWKID, nTileWidth, nTileHeight); CPLDebug("WMS", "Opening TMS :\n%s", osXML.c_str()); return CPLParseXMLString(osXML); }
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { VSILFILE* fp = VSIFileFromMemBuffer( "/vsimem/test.tar", reinterpret_cast<GByte*>(const_cast<uint8_t*>(buf)), len, FALSE ); VSIFCloseL(fp); CPLPushErrorHandler(CPLQuietErrorHandler); char** papszArgv = nullptr; CPLString osOutFilename("out"); fp = VSIFOpenL("/vsitar//vsimem/test.tar/cmd.txt", "rb"); if( fp != nullptr ) { const char* pszLine = nullptr; if( (pszLine = CPLReadLineL(fp)) != nullptr ) { osOutFilename = pszLine; osOutFilename = osOutFilename.replaceAll('/', '_'); } int nCandidateLayerNames = 0; while( (pszLine = CPLReadLineL(fp)) != nullptr ) { if( pszLine[0] != '-' ) { nCandidateLayerNames ++; if( nCandidateLayerNames == 10 ) break; } papszArgv = CSLAddString(papszArgv, pszLine); } VSIFCloseL(fp); } char** papszDrivers = CSLAddString(nullptr, "CSV"); GDALDatasetH hSrcDS = GDALOpenEx( "/vsitar//vsimem/test.tar/in", GDAL_OF_VECTOR, papszDrivers, nullptr, nullptr ); CSLDestroy(papszDrivers); if( papszArgv != nullptr && hSrcDS != nullptr ) { OGRLayerH hLayer = GDALDatasetGetLayer(hSrcDS, 0); if( hLayer ) { int nFieldCount = OGR_FD_GetFieldCount( OGR_L_GetLayerDefn(hLayer)); if( nFieldCount > 100 ) { papszArgv = CSLAddString(papszArgv, "-limit"); papszArgv = CSLAddString(papszArgv, "100"); } } GDALVectorTranslateOptions* psOptions = GDALVectorTranslateOptionsNew(papszArgv, nullptr); if( psOptions ) { CPLString osFullOutFilename("/vsimem/" + osOutFilename); GDALDatasetH hOutDS = GDALVectorTranslate( osFullOutFilename.c_str(), nullptr, 1, &hSrcDS, psOptions, nullptr); if( hOutDS ) { GDALDriverH hOutDrv = GDALGetDatasetDriver(hOutDS); GDALClose(hOutDS); // Try re-opening generated file GDALClose( GDALOpenEx(osFullOutFilename, GDAL_OF_VECTOR, nullptr, nullptr, nullptr)); if( hOutDrv ) GDALDeleteDataset(hOutDrv, osFullOutFilename); } GDALVectorTranslateOptionsFree(psOptions); } } CSLDestroy(papszArgv); GDALClose(hSrcDS); VSIRmdirRecursive("/vsimem/"); CPLPopErrorHandler(); return 0; }
OGRLayer * OGRSQLiteExecuteSQL( OGRDataSource* poDS, const char *pszStatement, OGRGeometry *poSpatialFilter, const char *pszDialect ) { char* pszTmpDBName = (char*) CPLMalloc(256); sprintf(pszTmpDBName, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName); OGRSQLiteDataSource* poSQLiteDS = NULL; int nRet; int bSpatialiteDB = FALSE; CPLString osOldVal; const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL); if( pszOldVal != NULL ) { osOldVal = pszOldVal; pszOldVal = osOldVal.c_str(); } /* -------------------------------------------------------------------- */ /* Create in-memory sqlite/spatialite DB */ /* -------------------------------------------------------------------- */ #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Creating an empty spatialite DB (with spatial_ref_sys populated */ /* has a non-neglectable cost. So at the first attempt, let's make */ /* one and cache it for later use. */ /* -------------------------------------------------------------------- */ #if 1 static vsi_l_offset nEmptyDBSize = 0; static GByte* pabyEmptyDB = NULL; { static void* hMutex = NULL; CPLMutexHolder oMutexHolder(&hMutex); static int bTried = FALSE; if( !bTried && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { bTried = TRUE; char* pszCachedFilename = (char*) CPLMalloc(256); sprintf(pszCachedFilename, "/vsimem/ogr2sqlite/reference_%p.db",pszCachedFilename); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource(); nRet = poCachedDS->Create( pszCachedFilename, papszOptions ); CSLDestroy(papszOptions); papszOptions = NULL; delete poCachedDS; if( nRet ) /* Note: the reference file keeps the ownership of the data, so that */ /* it gets released with VSICleanupFileManager() */ pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSize, FALSE ); CPLFree( pszCachedFilename ); } } /* The following configuration option is usefull mostly for debugging/testing */ if( pabyEmptyDB != NULL && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { GByte* pabyEmptyDBClone = (GByte*)VSIMalloc(nEmptyDBSize); if( pabyEmptyDBClone == NULL ) { CPLFree(pszTmpDBName); return NULL; } memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize); VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE )); poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Open( pszTmpDBName, TRUE ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { /* should not happen really ! */ delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bSpatialiteDB = TRUE; } #else /* No caching version */ poSQLiteDS = new OGRSQLiteDataSource(); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); CSLDestroy(papszOptions); papszOptions = NULL; if( nRet ) { bSpatialiteDB = TRUE; } #endif else { delete poSQLiteDS; poSQLiteDS = NULL; #else // HAVE_SPATIALITE if( TRUE ) { #endif // HAVE_SPATIALITE poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } } /* -------------------------------------------------------------------- */ /* Attach the Virtual Table OGR2SQLITE module to it. */ /* -------------------------------------------------------------------- */ OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS); sqlite3* hDB = poSQLiteDS->GetDB(); /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); std::set<LayerDesc>::iterator oIter = oSetLayers.begin(); if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 ) CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str()); pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */ int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos ); /* -------------------------------------------------------------------- */ /* For each of those tables, create a Virtual Table. */ /* -------------------------------------------------------------------- */ for(; oIter != oSetLayers.end(); ++oIter) { const LayerDesc& oLayerDesc = *oIter; /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s", oLayerDesc.osOriginalStr.c_str(), oLayerDesc.osSubstitutedName.c_str(), oLayerDesc.osDSName.c_str(), oLayerDesc.osLayerName.c_str());*/ CPLString osSQL; OGRLayer* poLayer = NULL; CPLString osTableName; int nExtraDS; if( oLayerDesc.osDSName.size() == 0 ) { poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName); /* Might be a false positive (unlikely) */ if( poLayer == NULL ) continue; osTableName = oLayerDesc.osLayerName; nExtraDS = -1; osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(osTableName).c_str(), bFoundOGRStyle); } else { OGRDataSource* poOtherDS = (OGRDataSource* ) OGROpen(oLayerDesc.osDSName, FALSE, NULL); if( poOtherDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open datasource '%s'", oLayerDesc.osDSName.c_str() ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName); if( poLayer == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find layer '%s' in '%s'", oLayerDesc.osLayerName.c_str(), oLayerDesc.osDSName.c_str() ); delete poOtherDS; delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } osTableName = oLayerDesc.osSubstitutedName; nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS); osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(), bFoundOGRStyle); } char* pszErrMsg = NULL; int rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create virtual table for layer '%s' : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); continue; } if( poLayer->GetGeomType() == wkbNone ) continue; CPLString osGeomColRaw(OGR2SQLITE_GetNameForGeometryColumn(poLayer)); const char* pszGeomColRaw = osGeomColRaw.c_str(); CPLString osGeomColEscaped(OGRSQLiteEscape(pszGeomColRaw)); const char* pszGeomColEscaped = osGeomColEscaped.c_str(); CPLString osLayerNameEscaped(OGRSQLiteEscape(osTableName)); const char* pszLayerNameEscaped = osLayerNameEscaped.c_str(); CPLString osIdxNameRaw(CPLSPrintf("idx_%s_%s", oLayerDesc.osLayerName.c_str(), pszGeomColRaw)); CPLString osIdxNameEscaped(OGRSQLiteEscapeName(osIdxNameRaw)); /* Make sure that the SRS is injected in spatial_ref_sys */ OGRSpatialReference* poSRS = poLayer->GetSpatialRef(); int nSRSId = poSQLiteDS->GetUndefinedSRID(); if( poSRS != NULL ) nSRSId = poSQLiteDS->FetchSRSId(poSRS); int bCreateSpatialIndex = FALSE; if( !bSpatialiteDB ) { osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_format, geometry_type, " "coord_dimension, srid) " "VALUES ('%s','%s','SpatiaLite',%d,%d,%d)", pszLayerNameEscaped, pszGeomColEscaped, (int) wkbFlatten(poLayer->GetGeomType()), ( poLayer->GetGeomType() & wkb25DBit ) ? 3 : 2, nSRSId); } #ifdef HAVE_SPATIALITE else { /* We detect the need for creating a spatial index by 2 means : */ /* 1) if there's an explicit reference to a 'idx_layername_geometrycolumn' */ /* table in the SQL --> old/traditionnal way of requesting spatial indices */ /* with spatialite. */ std::set<LayerDesc>::iterator oIter2 = oSetLayers.begin(); for(; oIter2 != oSetLayers.end(); ++oIter2) { const LayerDesc& oLayerDescIter = *oIter2; if( EQUAL(oLayerDescIter.osLayerName, osIdxNameRaw) ) { bCreateSpatialIndex = TRUE; break; } } /* 2) or if there's a SELECT FROM SpatialIndex WHERE f_table_name = 'layername' */ if( !bCreateSpatialIndex ) { std::set<CPLString>::iterator oIter3 = oSetSpatialIndex.begin(); for(; oIter3 != oSetSpatialIndex.end(); ++oIter3) { const CPLString& osNameIter = *oIter3; if( EQUAL(osNameIter, oLayerDesc.osLayerName) ) { bCreateSpatialIndex = TRUE; break; } } } if( poSQLiteDS->HasSpatialite4Layout() ) { int nGeomType = poLayer->GetGeomType(); int nCoordDimension = 2; if( nGeomType & wkb25DBit ) { nGeomType += 1000; nCoordDimension = 3; } osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES ('%s',Lower('%s'),%d ,%d ,%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, nGeomType, nCoordDimension, nSRSId, bCreateSpatialIndex ); } else { const char *pszGeometryType = OGRToOGCGeomType(poLayer->GetGeomType()); if (pszGeometryType[0] == '\0') pszGeometryType = "GEOMETRY"; osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES ('%s','%s','%s','%s',%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, pszGeometryType, ( poLayer->GetGeomType() & wkb25DBit ) ? "XYZ" : "XY", nSRSId, bCreateSpatialIndex ); } } #endif // HAVE_SPATIALITE sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Should we create a spatial index ?. */ /* -------------------------------------------------------------------- */ if( !bSpatialiteDB || !bCreateSpatialIndex ) continue; CPLDebug("SQLITE", "Create spatial index %s", osIdxNameRaw.c_str()); /* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */ #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING " "VirtualOGRSpatialIndex(%d, '%s', pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str()); rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); if( rc != SQLITE_OK ) { CPLDebug("SQLITE", "Error occured during spatial index creation : %s", sqlite3_errmsg(hDB)); } #else // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, NULL ); osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" " "USING rtree(pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str()); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); sqlite3_stmt *hStmt = NULL; if( rc == SQLITE_OK ) { const char* pszInsertInto = CPLSPrintf( "INSERT INTO \"%s\" (pkid, xmin, xmax, ymin, ymax) " "VALUES (?,?,?,?,?)", osIdxNameEscaped.c_str()); rc = sqlite3_prepare(hDB, pszInsertInto, -1, &hStmt, NULL); } OGRFeature* poFeature; OGREnvelope sEnvelope; OGR2SQLITE_IgnoreAllFieldsExceptGeometry(poLayer); poLayer->ResetReading(); while( rc == SQLITE_OK && (poFeature = poLayer->GetNextFeature()) != NULL ) { OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && !poGeom->IsEmpty() ) { poGeom->getEnvelope(&sEnvelope); sqlite3_bind_int64(hStmt, 1, (sqlite3_int64) poFeature->GetFID() ); sqlite3_bind_double(hStmt, 2, sEnvelope.MinX); sqlite3_bind_double(hStmt, 3, sEnvelope.MaxX); sqlite3_bind_double(hStmt, 4, sEnvelope.MinY); sqlite3_bind_double(hStmt, 5, sEnvelope.MaxY); rc = sqlite3_step(hStmt); if( rc == SQLITE_OK || rc == SQLITE_DONE ) rc = sqlite3_reset(hStmt); } delete poFeature; } poLayer->SetIgnoredFields(NULL); sqlite3_finalize(hStmt); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, NULL ); else { CPLDebug("SQLITE", "Error occured during spatial index creation : %s", sqlite3_errmsg(hDB)); rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, NULL ); } #endif // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX #endif // HAVE_SPATIALITE } /* -------------------------------------------------------------------- */ /* Reload, so that virtual tables are recognized */ /* -------------------------------------------------------------------- */ poSQLiteDS->ReloadLayers(); /* -------------------------------------------------------------------- */ /* Prepare the statement. */ /* -------------------------------------------------------------------- */ /* This will speed-up layer creation */ /* ORDER BY are costly to evaluate and are not necessary to establish */ /* the layer definition. */ int bUseStatementForGetNextFeature = TRUE; int bEmptyLayer = FALSE; sqlite3_stmt *hSQLStmt = NULL; int rc = sqlite3_prepare( hDB, pszStatement, strlen(pszStatement), &hSQLStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_prepare(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); if( hSQLStmt != NULL ) { sqlite3_finalize( hSQLStmt ); } delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } /* -------------------------------------------------------------------- */ /* Do we get a resultset? */ /* -------------------------------------------------------------------- */ rc = sqlite3_step( hSQLStmt ); if( rc != SQLITE_ROW ) { if ( rc != SQLITE_DONE ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_step(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } if( !EQUALN(pszStatement, "SELECT ", 7) ) { sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bUseStatementForGetNextFeature = FALSE; bEmptyLayer = TRUE; } /* -------------------------------------------------------------------- */ /* Create layer. */ /* -------------------------------------------------------------------- */ OGRSQLiteSelectLayer *poLayer = NULL; poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName, poSQLiteDS, pszStatement, hSQLStmt, bUseStatementForGetNextFeature, bEmptyLayer ); if( poSpatialFilter != NULL ) poLayer->SetSpatialFilter( poSpatialFilter ); return poLayer; } /************************************************************************/ /* OGRSQLiteGetReferencedLayers() */ /************************************************************************/ std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement) { /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); return oSetLayers; }
void Decode_Raster( char* input_buffer, const uint64_t& input_buffer_size, char*& output_buffer, int& output_rows, int& output_cols, int& output_channels ) { // Initialize Outputs output_buffer = nullptr; output_rows = 0; output_cols = 0; output_channels = 0; // Create memory file system object VSIFCloseL( VSIFileFromMemBuffer( "/vsimem/work.png", (unsigned char*)input_buffer, input_buffer_size, false )); // Open memory buffer for read. GDALDataset* dataset = (GDALDataset*)GDALOpen( "/vsimem/work.png", GA_ReadOnly ); // Get output format driver. GDALDriver* driver = (GDALDriver*)GDALGetDriverByName( "PNG" );//GTiff" ); // Set the parameters if( driver == NULL ){ BOOST_LOG_TRIVIAL(error) << "Unable to parse GDAL raster"; return; } // Update outputs output_cols = dataset->GetRasterXSize(); output_rows = dataset->GetRasterYSize(); output_channels = dataset->GetRasterCount(); output_buffer = new char[output_cols * output_rows * output_channels]; int osize = output_cols * output_rows * output_channels; int output_pos = 0; // Log Current BOOST_LOG_TRIVIAL(debug) << "Raster Rows: " << output_rows << ", Raster Cols: " << output_cols << ", Channels: " << output_channels; // Iterate over the bands uint8_t* scanline = new uint8_t[output_cols]; int idx, channel; for( int bid=1; bid <= output_channels; bid++ ) { // Get the band GDALRasterBand* band = dataset->GetRasterBand(bid); channel = bid-1; // Iterate over each row for( int r=0; r<output_rows; r++ ) { // Fetch the buffer band->RasterIO( GF_Read, 0, r, output_cols, 1, scanline, output_cols, 1, GDT_Byte, 0, 0); // Copy for( int c=0; c<output_cols; c++ ) { // Compute the Index idx = (output_cols * output_channels * r) + (c * output_channels) + channel; if( idx >= osize ){ BOOST_LOG_TRIVIAL(error) << __func__ << "::" << __LINE__ << ", About to go out of bounds. IDX: " << idx << ", Length: " << osize; } // Update the buffer output_buffer[idx] = scanline[c]; } } } // Clean up delete [] scanline; // close source file, and "unlink" it. GDALClose( dataset ); VSIUnlink( "/vsimem/work.png" ); }