xref: /aosp_15_r20/external/sandboxed-api/oss-internship-2020/gdal/raster.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gflags/gflags.h>
16 #include <syscall.h>
17 
18 #include <fstream>
19 #include <iostream>
20 
21 #include "gdal_sapi.sapi.h"  // NOLINT(build/include)
22 #include "absl/log/log.h"
23 #include "sandboxed_api/util/fileops.h"
24 
25 class GdalSapiSandbox : public GDALSandbox {
26  public:
GdalSapiSandbox(std::string path)27   GdalSapiSandbox(std::string path)
28       : GDALSandbox(), file_path_(std::move(path)) {}
29 
ModifyPolicy(sandbox2::PolicyBuilder *)30   std::unique_ptr<sandbox2::Policy> ModifyPolicy(
31       sandbox2::PolicyBuilder*) override {
32     return sandbox2::PolicyBuilder()
33         .AllowDynamicStartup()
34         .AllowRead()
35         .AllowSystemMalloc()
36         .AllowWrite()
37         .AllowExit()
38         .AllowStat()
39         .AllowOpen()
40         .AllowSyscall(__NR_futex)
41         .AllowSyscall(__NR_close)
42         .AllowSyscall(__NR_recvmsg)
43         .AllowSyscall(__NR_getdents64)
44         .AllowSyscall(__NR_lseek)
45         .AllowSyscall(__NR_getpid)
46         .AllowSyscall(__NR_sysinfo)
47         .AllowSyscall(__NR_prlimit64)
48         .AllowSyscall(__NR_ftruncate)
49         .AllowUnlink()
50         .AddFile(file_path_)
51         .BuildOrDie();
52   }
53 
54  private:
55   std::string file_path_;
56 };
57 
GdalMain(std::string filename)58 absl::Status GdalMain(std::string filename) {
59   // Reading GDALDataset from a (local, specific) file.
60   GdalSapiSandbox sandbox(filename);
61 
62   SAPI_RETURN_IF_ERROR(sandbox.Init());
63   GDALApi api(&sandbox);
64 
65   sapi::v::CStr s(filename.data());
66 
67   SAPI_RETURN_IF_ERROR(api.GDALAllRegister());
68   auto open = api.GDALOpen(s.PtrBoth(), GDALAccess::GA_ReadOnly);
69 
70   LOG(INFO) << "Dataset pointer adress: " << open.value() << std::endl;
71   sapi::v::RemotePtr ptr_dataset(open.value());
72 
73   LOG(INFO) << ptr_dataset.ToString() << std::endl;
74   if (!open.value()) {
75     return absl::AbortedError("NULL pointer for Dataset.\n");
76   }
77 
78   // Printing some general information about the dataset.
79   auto driver = api.GDALGetDatasetDriver(&ptr_dataset);
80   sapi::v::RemotePtr ptr_driver(driver.value());
81 
82   auto driver_short_name = api.GDALGetDriverShortName(&ptr_driver);
83   auto driver_long_name = api.GDALGetDriverLongName(&ptr_driver);
84 
85   sapi::v::RemotePtr ptr_driver_short_name(driver_short_name.value());
86   sapi::v::RemotePtr ptr_driver_long_name(driver_long_name.value());
87 
88   LOG(INFO) << "Driver short name: "
89             << sandbox.GetCString(ptr_driver_short_name).value().c_str();
90   LOG(INFO) << "Driver long name: "
91             << sandbox.GetCString(ptr_driver_long_name).value().c_str();
92 
93   // Checking that GetGeoTransform is valid.
94   std::vector<double> adf_geo_transform(6);
95   sapi::v::Array<double> adf_geo_transform_array(&adf_geo_transform[0],
96                                                  adf_geo_transform.size());
97 
98   // For this function that returns CPLErr, the error-handling must be done
99   // analyzing the returning object.
100   // Same for GDALReturnsIO from below.
101   CPLErr err;
102   SAPI_ASSIGN_OR_RETURN(
103       err,
104       api.GDALGetGeoTransform(&ptr_dataset, adf_geo_transform_array.PtrBoth()));
105 
106   // If GDALGetGeoTransform generates an error.
107   if (err != CE_None) {
108     return absl::InternalError("GDAL rasterization failed.");
109   }
110 
111   LOG(INFO) << "Origin = (" << adf_geo_transform[0] << ", "
112             << adf_geo_transform[3] << ")" << std::endl;
113   LOG(INFO) << "Pixel Size = (" << adf_geo_transform[0] << ", "
114             << adf_geo_transform[3] << ")" << std::endl;
115 
116   std::vector<int> n_blockX_size(1);
117   std::vector<int> n_blockY_size(1);
118 
119   sapi::v::Array<int> nBlockXSizeArray(&n_blockX_size[0], n_blockX_size.size());
120   sapi::v::Array<int> nBlockYSizeArray(&n_blockY_size[0], n_blockY_size.size());
121 
122   auto band = api.GDALGetRasterBand(&ptr_dataset, 1);
123   LOG(INFO) << "Band pointer adress: " << band.value() << std::endl;
124   if (!band.value()) {
125     return absl::AbortedError("NULL pointer for Band.\n");
126   }
127 
128   sapi::v::RemotePtr ptr_band(band.value());
129   SAPI_RETURN_IF_ERROR(api.GDALGetBlockSize(
130       &ptr_band, nBlockXSizeArray.PtrBoth(), nBlockYSizeArray.PtrBoth()));
131 
132   LOG(INFO) << "Block = " << n_blockX_size[0] << " x " << n_blockY_size[0]
133             << std::endl;
134 
135   std::vector<int> b_got_min(1);
136   std::vector<int> b_got_max(1);
137 
138   sapi::v::Array<int> b_got_min_array(&b_got_min[0], b_got_min.size());
139   sapi::v::Array<int> b_got_max_array(&b_got_max[0], b_got_max.size());
140 
141   auto nX_size = api.GDALGetRasterBandXSize(&ptr_band);
142   auto nY_size = api.GDALGetRasterBandYSize(&ptr_band);
143 
144   std::vector<int8_t> raster_data(nX_size.value() * nY_size.value(), -1);
145   sapi::v::Array<int8_t> raster_data_array(&raster_data[0], raster_data.size());
146 
147   // We will use CPLErr type of returning value, as before with
148   // GDALGetGeoTransorm.
149   SAPI_ASSIGN_OR_RETURN(
150       err, api.GDALRasterIO(&ptr_band, GF_Read, 0, 0, nX_size.value(),
151                             nY_size.value(), raster_data_array.PtrBoth(),
152                             nX_size.value(), nY_size.value(), GDT_Byte, 0, 0));
153 
154   // If GDALRasterIO generates an error.
155   if (err != CE_None) {
156     return absl::InternalError("GDAL rasterization failed.");
157   }
158 
159   std::cout << "Raster data info: " << raster_data_array.ToString()
160             << std::endl;
161 
162   // To print the data content: `std::cout << raster_data_array.GetData() <<
163   // std::endl;`
164 
165   return absl::OkStatus();
166 }
167 
main(int argc,char * argv[])168 int main(int argc, char* argv[]) {
169   // The file to be converted should be specified in the first argument while
170   // running the program.
171   if (argc < 2) {
172     std::cout << "You need to provide a file name: ./raster "
173                  "your_tiff_file_absolute_path\n"
174                  "Example: ./raster /usr/home/username/file.tiff"
175               << std::endl;
176     return EXIT_FAILURE;
177   }
178 
179   std::ifstream aux_file;
180   aux_file.open(argv[1]);
181   if (!aux_file.is_open()) {
182     std::cout << "Your file name is not valid.\nUnable to open the file."
183               << std::endl;
184     return EXIT_FAILURE;
185   }
186   std::string filename(argv[1]);
187 
188   if (absl::Status status = GdalMain(filename); !status.ok()) {
189     LOG(ERROR) << "Initialization failed: " << status.ToString();
190     return EXIT_FAILURE;
191   }
192 
193   return EXIT_SUCCESS;
194 }
195