diff --git a/oss-internship-2020/gdal/CANYrelief1-geo.tif b/oss-internship-2020/gdal/CANYrelief1-geo.tif new file mode 100644 index 0000000..f9d2ef0 Binary files /dev/null and b/oss-internship-2020/gdal/CANYrelief1-geo.tif differ diff --git a/oss-internship-2020/gdal/CMakeLists.txt b/oss-internship-2020/gdal/CMakeLists.txt new file mode 100644 index 0000000..bfe0256 --- /dev/null +++ b/oss-internship-2020/gdal/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.10) + +project(test CXX C) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(SAPI_ROOT "/usr/local/google/home/inach/work/sandboxed-api" CACHE PATH "Path to the Sandboxed API source tree") +# cmake .. -G Ninja -DSAPI_ROOT=$HOME/sapi_root + +set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "") +set(SAPI_ENABLE_TESTS OFF CACHE BOOL "") +add_subdirectory("${SAPI_ROOT}" + "${CMAKE_BINARY_DIR}/sandboxed-api-build" + # Omit this to have the full Sandboxed API in IDE + EXCLUDE_FROM_ALL) + +add_library(libgdal STATIC IMPORTED) +set_property(TARGET libgdal PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libgdal.a") + +find_package(PNG REQUIRED) + +target_link_libraries(libgdal INTERFACE + crypto expat jpeg + /usr/lib/x86_64-linux-gnu/libproj.so + /usr/lib/x86_64-linux-gnu/libpcre.so + sqlite3 tiff z pthread m rt dl curl + PNG::PNG) + +add_sapi_library(gdal_sapi + FUNCTIONS GDALOpen GDALAllRegister GDALGetDatasetDriver + GDALGetDriverShortName GDALGetDriverLongName GDALGetRasterXSize + GDALGetRasterYSize GDALGetRasterCount GDALGetProjectionRef + GDALOpenEx GDALGetGeoTransform GDALGetRasterBand GDALGetBlockSize + GDALGetRasterMinimum GDALGetRasterMaximum GDALGetRasterBandXSize + GDALGetRasterBandYSize GDALRasterIO + + INPUTS "/usr/include/gdal/gdal.h" + LIBRARY libgdal + LIBRARY_NAME gdal + + NAMESPACE "" +) + +target_include_directories(gdal_sapi INTERFACE + "${PROJECT_BINARY_DIR}" +) + +add_executable(raster + raster.cc +) + +target_link_libraries(raster + gdal_sapi + sapi::sapi +) diff --git a/oss-internship-2020/gdal/README.md b/oss-internship-2020/gdal/README.md new file mode 100644 index 0000000..c4e1999 --- /dev/null +++ b/oss-internship-2020/gdal/README.md @@ -0,0 +1,53 @@ +# GDAL Raster GeoTIFF Workflow + +``` +Build Tools: CMake/Ninja +OS: Linux +``` + +### For testing: +`mkdir build && cd build` + +`cmake .. -G Ninja` + +`ninja` + +`./raster` + +## About the project + GDAL is a translator library for raster and vector + geospatial data format. + The project consist in rastering a GeoTIFF file format + using GDAL functionalities and sandboxed methods. + +## Implementation + +*Sandboxing...* + + The purpose of sandboxing is to limit the permissions + and capabilities of library’s methods, in order to + secure the usage of them. After obtaining the sandbox, + the functions will be called through an Sandbox API + (being called api in the current test) and so, the + operations, system calls or namspaces access may be + controlled. + +*Raster process...* + + From gdal.h header useful methods are added to sapi + library builded with CMake. + + One .tiff file is manipulated with GDALOpen + functionality, which extracts a pointer to the data set + containg a list of raster bands, all pertaining to the + same area. + Metadata, a coordinate system, a georeferencing + transform, size of raster and various other information + are kept into the data set that corresponds to the image. + + To create an array containing the image information, the + dimentions needed are extracted using some specific + GDAL(X/Y)Size functions applied to the block. + GDALRasterBand function takes care of data type conversion, one more step following: placing the + converted data (with RasterIO method) into the created + and well allocated structure. diff --git a/oss-internship-2020/gdal/raster.cc b/oss-internship-2020/gdal/raster.cc new file mode 100644 index 0000000..0e1f7b6 --- /dev/null +++ b/oss-internship-2020/gdal/raster.cc @@ -0,0 +1,115 @@ +#include +#include + +#include + +#include "gdal_sapi.sapi.h" +#include "sandboxed_api/sandbox2/util/fileops.h" + +class GdalSapiSandbox : public gdalSandbox { + public: + std::unique_ptr ModifyPolicy( + sandbox2::PolicyBuilder*) override { + return sandbox2::PolicyBuilder() + .DangerDefaultAllowAll() + .DisableNamespaces() + .BuildOrDie(); + } +}; + +int main() { + GdalSapiSandbox sandbox; + sandbox.Init().IgnoreError(); + gdalApi api(&sandbox); + + // Reading GDALDataset from a (local, specific) file. + std::string filename = "CANYrelief1-geo.tif"; + sapi::v::CStr s(filename.data()); + + api.GDALAllRegister().IgnoreError(); + auto open = api.GDALOpen(s.PtrBefore(), GDALAccess::GA_ReadOnly); + sapi::v::RemotePtr ptrDataset(open.value()); + + LOG(INFO) << "Dataset pointer adress: " << open.value() << std::endl; + LOG(INFO) << ptrDataset.ToString() << std::endl; + if (!open.value()) { + printf("NULL pointer for Dataset.\n"); + return 1; + } + + // Printing some general information about the dataset. + auto driver = api.GDALGetDatasetDriver(&ptrDataset); + sapi::v::RemotePtr ptrDriver(driver.value()); + + auto driverShortName = api.GDALGetDriverShortName(&ptrDriver); + auto driverLongName = api.GDALGetDriverLongName(&ptrDriver); + + sapi::v::RemotePtr ptrDriverShortName(driverShortName.value()); + sapi::v::RemotePtr ptrDriverLongName(driverLongName.value()); + + LOG(INFO) << "Driver short name: " + << sandbox.GetCString(ptrDriverShortName).value().c_str(); + LOG(INFO) << "Driver long name: " + << sandbox.GetCString(ptrDriverLongName).value().c_str(); + + // Checking that GetGeoTransform is valid. + std::vector adfGeoTransform(6); + sapi::v::Array adfGeoTransformArray(&adfGeoTransform[0], + adfGeoTransform.size()); + + api.GDALGetGeoTransform(&ptrDataset, adfGeoTransformArray.PtrBoth()) + .IgnoreError(); + + LOG(INFO) << "Origin = (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] + << ")" << std::endl; + LOG(INFO) << "Pixel Size = (" << adfGeoTransform[0] << ", " + << adfGeoTransform[3] << ")" << std::endl; + + std::vector nBlockXSize(1); + std::vector nBlockYSize(1); + + sapi::v::Array nBlockXSizeArray(&nBlockXSize[0], nBlockXSize.size()); + sapi::v::Array nBlockYSizeArray(&nBlockYSize[0], nBlockYSize.size()); + + auto band = api.GDALGetRasterBand(&ptrDataset, 1); + LOG(INFO) << "Band pointer adress: " << band.value() << std::endl; + if (!band.value()) { + printf("NULL pointer for Band.\n"); + return 1; + } + + sapi::v::RemotePtr ptrBand(band.value()); + api.GDALGetBlockSize(&ptrBand, nBlockXSizeArray.PtrBoth(), + nBlockYSizeArray.PtrBoth()) + .IgnoreError(); + + LOG(INFO) << "Block = " << nBlockXSize[0] << " x " << nBlockYSize[0] + << std::endl; + + std::vector bGotMin(1); + std::vector bGotMax(1); + + sapi::v::Array bGotMinArray(&bGotMin[0], bGotMin.size()); + sapi::v::Array bGotMaxArray(&bGotMax[0], bGotMax.size()); + + auto adfMin = api.GDALGetRasterMinimum(&ptrBand, bGotMinArray.PtrBoth()); + auto adfMax = api.GDALGetRasterMaximum(&ptrBand, bGotMaxArray.PtrBoth()); + + auto nXSize = api.GDALGetRasterBandXSize(&ptrBand); + auto nYSize = api.GDALGetRasterBandYSize(&ptrBand); + + std::vector rasterData(nXSize.value() * nYSize.value(), -1); + sapi::v::Array rasterDataArray(&rasterData[0], rasterData.size()); + + api.GDALRasterIO(&ptrBand, GF_Read, 0, 0, nXSize.value(), nYSize.value(), + rasterDataArray.PtrBoth(), nXSize.value(), nYSize.value(), + GDT_Byte, 0, 0) + .IgnoreError(); + + std::cout << "Raster data info: " << rasterDataArray.ToString() << std::endl; + + // To print the data content: `std::cout << rasterDataArray.GetData() << + // std::endl;` + + return 0; +} \ No newline at end of file