17 #include <vtkBMPReader.h>
18 #include <vtkImageData.h>
19 #include <vtkImageImport.h>
20 #include <vtkImageReader2.h>
21 #include <vtkJPEGReader.h>
22 #include <vtkPNGReader.h>
23 #include <vtkTIFFReader.h>
31 #include <geo_tiffp.h>
45 QFileInfo fileInfo(QString::fromStdString(fileName));
47 std::unique_ptr<GeoLib::Raster> raster(
nullptr);
48 if (fileInfo.suffix().toLower() ==
"asc")
53 else if (fileInfo.suffix().toLower() ==
"grd")
63 if ((fileInfo.suffix().toLower() ==
"tif") ||
64 (fileInfo.suffix().toLower() ==
"tiff"))
69 ERR(
"VtkRaster::loadImage(): GeoTiff file format not supported in this "
70 "version! Trying to parse as Tiff-file.");
81 auto* data =
new float[length * 2];
83 static_cast<float>(*std::max_element(data_array, data_array + length));
84 for (
unsigned j = 0; j < length; ++j)
86 data[j * 2] =
static_cast<float>(data_array[j]);
87 if (fabs(data[j * 2] - header.
no_data) <
88 std::numeric_limits<double>::epsilon())
90 data[j * 2] = max_val;
95 data[j * 2 + 1] = max_val;
99 vtkImageImport* image = vtkImageImport::New();
104 image->SetWholeExtent(0, header.
n_cols - 1, 0, header.
n_rows - 1, 0,
106 image->SetDataExtent(0, header.
n_cols - 1, 0, header.
n_rows - 1, 0,
108 image->SetDataExtentToWholeExtent();
109 image->SetDataScalarTypeToFloat();
110 image->SetNumberOfScalarComponents(2);
111 image->SetImportVoidPointer(data, 0);
120 TIFF* tiff = XTIFFOpen(fileName.c_str(),
"r");
124 GTIF* geoTiff = GTIFNew(tiff);
128 GTIFDirectoryInfo(geoTiff, version, &count);
131 WARN(
"VtkRaster::loadImageFromTIFF - file is not georeferenced.");
137 double cellsize = 1.0;
142 double* pnts =
nullptr;
148 }
while (TIFFReadDirectory(tiff));
151 "VtkRaster::loadImageFromTIFF() - File contains {:d} "
152 "images. This method is not tested for this case.",
156 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &imgWidth);
157 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &imgHeight);
162 if (TIFFGetField(tiff, GTIFF_PIXELSCALE, &pntCount, &pnts))
164 if (pnts[0] != pnts[1])
166 "VtkRaster::loadImageFromTIFF(): Original raster data "
167 "has anisotrop pixel size!");
172 if (TIFFGetField(tiff, GTIFF_TIEPOINTS, &pntCount, &pnts))
176 (imgHeight * cellsize);
181 auto* pixVal =
static_cast<uint32*
>(
182 _TIFFmalloc(imgWidth * imgHeight *
sizeof(
uint32)));
183 if ((imgWidth > 0) && (imgHeight > 0))
185 if (!TIFFReadRGBAImage(tiff, imgWidth, imgHeight, pixVal, 0))
187 ERR(
"VtkRaster::loadImageFromTIFF(): reading GeoTIFF "
198 TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
200 uint16 *cmap_red =
nullptr, *cmap_green =
nullptr,
201 *cmap_blue =
nullptr;
202 int colormap_used = TIFFGetField(tiff, TIFFTAG_COLORMAP, &cmap_red,
203 &cmap_green, &cmap_blue);
205 auto* data =
new float[imgWidth * imgHeight * 4];
206 auto* pxl(
new int[4]);
207 for (
int j = 0; j < imgHeight; ++j)
209 int lineindex = j * imgWidth;
210 for (
int i = 0; i < imgWidth; ++i)
213 unsigned pxl_idx(lineindex + i);
214 unsigned pos = 4 * (pxl_idx);
215 if (photometric == 1 && colormap_used == 1)
217 int idx = TIFFGetR(pixVal[pxl_idx]);
218 data[pos] =
static_cast<float>(cmap_red[idx] >> 8);
220 static_cast<float>(cmap_green[idx] >> 8);
221 data[pos + 2] =
static_cast<float>(cmap_blue[idx] >> 8);
227 static_cast<float>(TIFFGetR(pixVal[pxl_idx]));
229 static_cast<float>(TIFFGetG(pixVal[pxl_idx]));
231 static_cast<float>(TIFFGetB(pixVal[pxl_idx]));
233 static_cast<float>(TIFFGetA(pixVal[pxl_idx]));
240 if (photometric == 1)
243 unsigned nPixels = 4 * imgWidth * imgHeight;
244 for (
unsigned j = 0; j < nPixels; ++j)
246 if (data[j] > max_val)
252 for (
unsigned j = 0; j < nPixels; j += 4)
254 data[j + 3] = max_val;
258 vtkImageImport* image = vtkImageImport::New();
259 image->SetDataOrigin(x0, y0, 0);
260 image->SetDataSpacing(cellsize, cellsize, cellsize);
261 image->SetWholeExtent(0, imgWidth - 1, 0, imgHeight - 1, 0, 0);
262 image->SetDataExtent(0, imgWidth - 1, 0, imgHeight - 1, 0, 0);
263 image->SetDataExtentToWholeExtent();
264 image->SetDataScalarTypeToFloat();
265 image->SetNumberOfScalarComponents(4);
266 image->SetImportVoidPointer(data, 0);
276 ERR(
"VtkRaster::loadImageFromTIFF() - File not recognised as "
281 ERR(
"VtkRaster::loadImageFromTIFF() - File not recognised as TIFF-Image.");
288 QString file_name(QString::fromStdString(fileName));
289 QFileInfo fi(file_name);
290 vtkImageReader2* image(
nullptr);
292 if (fi.suffix().toLower() ==
"png")
294 image = vtkPNGReader::New();
296 else if ((fi.suffix().toLower() ==
"tif") ||
297 (fi.suffix().toLower() ==
"tiff"))
299 image = vtkTIFFReader::New();
301 else if ((fi.suffix().toLower() ==
"jpg") ||
302 (fi.suffix().toLower() ==
"jpeg"))
304 image = vtkJPEGReader::New();
306 else if (fi.suffix().toLower() ==
"bmp")
308 image = vtkBMPReader::New();
312 ERR(
"VtkRaster::readImageFromFile(): File format not supported, please "
313 "convert to BMP, JPG, PNG or TIFF.");
317 image->SetFileName(fileName.c_str());
318 image->GetOutput()->AllocateScalars(VTK_FLOAT, 1);
328 constexpr std::array supported_extensions = {
329 ".pgw",
".pngw",
".pgwx",
".jgw",
".jpgw",
".jgwx",
".tfw",
330 ".tifw",
".tfwx",
".bpw",
".bmpw",
".bpwx",
".wld"};
333 std::find_if(supported_extensions.begin(), supported_extensions.end(),
334 [&no_ext](
auto const& ext) ->
bool
335 { return BaseLib::IsFileExisting(no_ext + ext); });
336 if (res != supported_extensions.end())
338 return no_ext + *res;
346 vtkImageReader2* image)
349 if (world_file.empty())
351 WARN(
"No world file found. Image is not georeferenced.");
355 std::ifstream in(world_file.c_str());
358 ERR(
"VtkRaster::readWorldFile(): Could not open file {:s}.", filename);
364 if (!std::getline(in, line))
368 double const delta_x = BaseLib::str2number<double>(line);
370 if (!(std::getline(in, line) && std::getline(in, line)))
375 if (!std::getline(in, line))
379 double const delta_y = BaseLib::str2number<double>(line);
380 if (delta_x != -delta_y)
382 "Anisotropic pixel size detected ({:f} vs {:f}). An isotropic "
383 "spacing of {:f} is assumed, be aware results may be wrong.",
384 delta_x, delta_y, delta_x);
386 if (!std::getline(in, line))
390 double const x0 = BaseLib::str2number<double>(line);
392 if (!std::getline(in, line))
396 double const y0 = BaseLib::str2number<double>(line);
399 image->GetOutput()->GetDimensions(extent);
400 image->SetDataSpacing(delta_x, delta_x, delta_x);
402 double const vtk_y0 = y0 + (extent[1] * delta_y);
403 image->SetDataOrigin(x0, vtk_y0, 0);
Definition of the AsciiRasterInterface class.
void INFO(char const *fmt, Args const &... args)
void ERR(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... args)
Definition of the GeoLib::Raster class.
Definition of the VtkRaster class.
static GeoLib::Raster * getRasterFromSurferFile(std::string const &fname)
Reads a Surfer GRD raster file.
static GeoLib::Raster * getRasterFromASCFile(std::string const &fname)
Reads an ArcGis ASC raster file.
static std::string findWorldFile(const std::string &filename)
static vtkImageAlgorithm * loadImageFromTIFF(const std::string &fileName)
static vtkImageReader2 * loadImageFromFile(const std::string &fileName)
static bool readWorldFile(std::string const &filename, vtkImageReader2 *image)
static vtkImageImport * loadImageFromArray(double const *const data_array, GeoLib::RasterHeader header)
Returns a VtkImageAlgorithm from an array of pixel values and some image meta data.
static vtkImageAlgorithm * loadImage(const std::string &fileName)
Loads an image- or raster-file into an vtkImageAlgorithm-Object.
std::string dropFileExtension(std::string const &filename)