<commit_before>//
// vtElevationGridIO.cpp
//
// This modules contains the implementations of the file I/O methods of
// the class vtElevationGrid.
//
// Copyright (c) 2001-2003 Virtual Terrain Project.
// Free for all uses, see license.txt for details.
//

#include <stdlib.h>
#include <string.h>
#include <fstream>
using namespace std;

#include "config_vtdata.h"
#include "vtLog.h"
#include "vtDIB.h"
#include "ElevationGrid.h"
#include "ByteOrder.h"
#include "vtString.h"
#include "FilePath.h"

#if SUPPORT_NETCDF
extern "C" {
#include "netcdf.h"
}
#endif

// GDAL
#include "gdal_priv.h"

// OGR
#include <ogrsf_frmts.h>

//	Header structure for a GTOPO30 DEM header file
typedef struct
{
	char			ByteOrder[30];		//	Byte order in which image pixel values are stored
										//		M = Motorola byte order (MSB first)
										//		I = Intel byte order (LSB first)
	char			Layout[30];			//	Organization of the bands in the file
										//		BIL = Band interleaved by line (DEM = single band image)
	unsigned long	NumRows;			//	Number of rows in the image
	unsigned long	NumCols;			//	Number of columns in the image
	char			Bands[30];			//	Number of spectral bands in the image (1 for DEM)
	char			Bits[30];			//	Number of bits per pixel (16 for DEM)
	char			BandRowBytes[30];	//	Number of bytes per band per row
										//		(twice the number of columns for 16 bit DEM)
	char			TotalRowBytes[30];	//	Total number of bytes of data per row
										//		(twice the number of columns for 16 bit DEM)
	char			BandGapBytes[30];	//	Number of bytes between bands in a BSQ format
										//		(0 for DEM)
	short			NoData;				//	Value used for no data or masking purposes
	double			ULXMap;				//	Longitude of the center of the upper left pixel in decimal degrees.
	double			ULYMap;				//	Latitude of the center of the upper left pixel in decimal degrees.
	double			XDim;				//	x dimension of a pixel in geographic units (decimal degrees).
	double			YDim;				//	y dimension of a pixel in geographic units (decimal degrees).
} GTOPOHeader;


/**
 * Load from a file whose type is not known a priori.  This will end up
 * calling one of the Load* member functions.
 *
 * \return true if successful.
 */
bool vtElevationGrid::LoadFromFile(const char *szFileName,
								   void progress_callback(int))
{
	vtString FileName(szFileName);
	vtString FileExt = FileName.Right(3);
	vtString FileExtGZ = FileName.Right(6);

	if (FileExt == "")
		return false;

	// The first character in the file is useful for telling which format
	// the file really is.
	FILE *fp = fopen(szFileName, "rb");
	if (!fp)
		return false;
	char FirstChar = fgetc(fp);
	fclose(fp);

	bool Success = false;

	if ((!FileExt.CompareNoCase(".bt")) || (!FileExtGZ.CompareNoCase(".bt.gz")))
	{
		Success = LoadFromBT(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("dem"))
	{
		if (FirstChar == '*')
			Success = LoadFromMicroDEM(szFileName, progress_callback);
		else
			Success = LoadFromDEM(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("asc"))
	{
		Success = LoadWithGDAL(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("bil"))
	{
		Success = LoadWithGDAL(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("ter"))
	{
		Success = LoadFromTerragen(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("cdf"))
	{
		Success = LoadFromCDF(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("hdr"))
	{
		Success = LoadFromGTOPO30(szFileName, progress_callback);
		if (!Success)
		{
			// might be NOAA GLOBE header
			Success = LoadFromGLOBE(szFileName, progress_callback);
		}
	}
	else if (!FileExt.CompareNoCase("dte") ||
			 !FileExt.CompareNoCase("dt0") ||
			 !FileExt.CompareNoCase("dt1") ||
			 !FileExt.CompareNoCase("dt2"))
	{
		Success = LoadFromDTED(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("pgm"))
	{
		Success = LoadFromPGM(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("grd"))
	{
		// might by CDF, might be GRD
		if (FirstChar == 'D')
			Success = LoadFromGRD(szFileName, progress_callback);
		else
			Success = LoadFromCDF(szFileName, progress_callback);

		if (!Success)
		{
			// Might be 'Arc Binary Grid', try GDAL
			Success = LoadWithGDAL(szFileName, progress_callback);
		}
	}
	else if (!FileName.Right(8).CompareNoCase("catd.ddf") ||
			 !FileExt.CompareNoCase("tif") ||
			 !FileExt.CompareNoCase("png") ||
			 !FileExt.CompareNoCase("adf"))
	{
		Success = LoadWithGDAL(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase("hgt"))
	{
		Success = LoadFromHGT(szFileName, progress_callback);
	}
	return Success;
}


// ************** DConvert - DEM Helper function ****************

double DConvert(FILE *fp, int length)
{
	char szCharString[64];

	fread(szCharString, length, 1, fp);
	szCharString[length] = 0;

	return atof(szCharString);
}

int IConvert(FILE *fp, int length)
{
	char szCharString[64];

	fread(szCharString, length, 1, fp);
	szCharString[length] = 0;

	return atoi(szCharString);
}

/**
 * Loads elevation from a USGS DEM file.<commit_msg>chg to use GetExtension, chg to use LoadFromASC<commit_after>//
// vtElevationGridIO.cpp
//
// This modules contains the implementations of the file I/O methods of
// the class vtElevationGrid.
//
// Copyright (c) 2001-2003 Virtual Terrain Project.
// Free for all uses, see license.txt for details.
//

#include <stdlib.h>
#include <string.h>
#include <fstream>
using namespace std;

#include "config_vtdata.h"
#include "vtLog.h"
#include "vtDIB.h"
#include "ElevationGrid.h"
#include "ByteOrder.h"
#include "vtString.h"
#include "FilePath.h"

#if SUPPORT_NETCDF
extern "C" {
#include "netcdf.h"
}
#endif

// GDAL
#include "gdal_priv.h"

// OGR
#include <ogrsf_frmts.h>

//	Header structure for a GTOPO30 DEM header file
typedef struct
{
	char			ByteOrder[30];		//	Byte order in which image pixel values are stored
										//		M = Motorola byte order (MSB first)
										//		I = Intel byte order (LSB first)
	char			Layout[30];			//	Organization of the bands in the file
										//		BIL = Band interleaved by line (DEM = single band image)
	unsigned long	NumRows;			//	Number of rows in the image
	unsigned long	NumCols;			//	Number of columns in the image
	char			Bands[30];			//	Number of spectral bands in the image (1 for DEM)
	char			Bits[30];			//	Number of bits per pixel (16 for DEM)
	char			BandRowBytes[30];	//	Number of bytes per band per row
										//		(twice the number of columns for 16 bit DEM)
	char			TotalRowBytes[30];	//	Total number of bytes of data per row
										//		(twice the number of columns for 16 bit DEM)
	char			BandGapBytes[30];	//	Number of bytes between bands in a BSQ format
										//		(0 for DEM)
	short			NoData;				//	Value used for no data or masking purposes
	double			ULXMap;				//	Longitude of the center of the upper left pixel in decimal degrees.
	double			ULYMap;				//	Latitude of the center of the upper left pixel in decimal degrees.
	double			XDim;				//	x dimension of a pixel in geographic units (decimal degrees).
	double			YDim;				//	y dimension of a pixel in geographic units (decimal degrees).
} GTOPOHeader;


/**
 * Load from a file whose type is not known a priori.  This will end up
 * calling one of the Load* member functions.
 *
 * \return true if successful.
 */
bool vtElevationGrid::LoadFromFile(const char *szFileName,
								   void progress_callback(int))
{
	vtString FileExt = GetExtension(szFileName);

	if (FileExt == "")
		return false;

	// The first character in the file is useful for telling which format
	// the file really is.
	FILE *fp = fopen(szFileName, "rb");
	if (!fp)
		return false;
	char FirstChar = fgetc(fp);
	fclose(fp);

	bool Success = false;

	if ((!FileExt.CompareNoCase(".bt")) || (!FileExt.CompareNoCase(".bt.gz")))
	{
		Success = LoadFromBT(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".dem"))
	{
		if (FirstChar == '*')
			Success = LoadFromMicroDEM(szFileName, progress_callback);
		else
			Success = LoadFromDEM(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".asc"))
	{
		// GDAL's ASC reader has trouble on some machines
//		Success = LoadWithGDAL(szFileName, progress_callback);

		Success = LoadFromASC(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".bil"))
	{
		Success = LoadWithGDAL(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".ter"))
	{
		Success = LoadFromTerragen(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".cdf"))
	{
		Success = LoadFromCDF(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".hdr"))
	{
		Success = LoadFromGTOPO30(szFileName, progress_callback);
		if (!Success)
		{
			// might be NOAA GLOBE header
			Success = LoadFromGLOBE(szFileName, progress_callback);
		}
	}
	else if (!FileExt.CompareNoCase(".dte") ||
			 !FileExt.CompareNoCase(".dt0") ||
			 !FileExt.CompareNoCase(".dt1") ||
			 !FileExt.CompareNoCase(".dt2"))
	{
		Success = LoadFromDTED(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".pgm"))
	{
		Success = LoadFromPGM(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".grd"))
	{
		// might by CDF, might be GRD
		if (FirstChar == 'D')
			Success = LoadFromGRD(szFileName, progress_callback);
		else
			Success = LoadFromCDF(szFileName, progress_callback);

		if (!Success)
		{
			// Might be 'Arc Binary Grid', try GDAL
			Success = LoadWithGDAL(szFileName, progress_callback);
		}
	}
	else if (!FileExt.CompareNoCase(".catd.ddf") ||
			 !FileExt.CompareNoCase(".tif") ||
			 !FileExt.CompareNoCase(".tiff") ||
			 !FileExt.CompareNoCase(".png") ||
			 !FileExt.CompareNoCase(".adf"))
	{
		Success = LoadWithGDAL(szFileName, progress_callback);
	}
	else if (!FileExt.CompareNoCase(".hgt"))
	{
		Success = LoadFromHGT(szFileName, progress_callback);
	}
	return Success;
}


// ************** DConvert - DEM Helper function ****************

double DConvert(FILE *fp, int length)
{
	char szCharString[64];

	fread(szCharString, length, 1, fp);
	szCharString[length] = 0;

	return atof(szCharString);
}

int IConvert(FILE *fp, int length)
{
	char szCharString[64];

	fread(szCharString, length, 1, fp);
	szCharString[length] = 0;

	return atoi(szCharString);
}

/**
 * Loads elevation from a USGS DEM file.
{'fraction_non_alphanumeric': 0.1274273017099797, 'fraction_numerical': 0.008984639165298038, 'mean_word_length': 3.66726780883679, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2348573', 'n_tokens_mistral': 3924, 'n_tokens_neox': 3497, 'n_words': 1029}