44
56
#include <assert.h>
46
static int byte_order_test = 1;
47
#define IS_LSB (((unsigned char *) (&byte_order_test))[0] == 1)
49
/************************************************************************/
52
/* Convert the given words into local order in place. */
53
/************************************************************************/
55
static void local_order( unsigned char *data, int word_size, int word_count )
58
/* We only need to do work on LSB machines. Perhaps we should
59
convert the data files into LSB order to cut workload! */
65
for( word = 0; word < word_count; word++ )
69
for( i = 0; i < word_size/2; i++ )
74
data[i] = data[word_size-i-1];
75
data[word_size-i-1] = t;
83
/************************************************************************/
86
/* Load an NTv1 style Canadian grid shift file. */
87
/************************************************************************/
89
static struct CTABLE *nad_load_ntv1( FILE * fid )
98
assert( sizeof(int) == 4 );
99
assert( sizeof(double) == 8 );
100
if( sizeof(int) != 4 || sizeof(double) != 8 )
103
"basic types of inappropraiate size in nad_load_ntv1()\n" );
108
/* -------------------------------------------------------------------- */
109
/* Read the header. */
110
/* -------------------------------------------------------------------- */
111
if( fread( header, sizeof(header), 1, fid ) != 1 )
59
/************************************************************************/
60
/* nad_ctable_load() */
62
/* Load the data portion of a ctable formatted grid. */
63
/************************************************************************/
65
int nad_ctable_load( struct CTABLE *ct, FILE *fid )
70
fseek( fid, sizeof(struct CTABLE), SEEK_SET );
72
/* read all the actual shift values */
73
a_size = ct->lim.lam * ct->lim.phi;
74
ct->cvs = (FLP *) pj_malloc(sizeof(FLP) * a_size);
76
|| fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size )
118
/* -------------------------------------------------------------------- */
119
/* Regularize fields of interest. */
120
/* -------------------------------------------------------------------- */
121
local_order( header+8, 4, 1 );
122
local_order( header+24, 8, 1 );
123
local_order( header+40, 8, 1 );
124
local_order( header+56, 8, 1 );
125
local_order( header+72, 8, 1 );
126
local_order( header+88, 8, 1 );
127
local_order( header+104, 8, 1 );
129
if( *((int *) (header+8)) != 12 )
132
printf("NTv1 grid shift file has wrong record count, corrupt?\n");
136
/* -------------------------------------------------------------------- */
137
/* Fill in CTABLE structure. */
138
/* -------------------------------------------------------------------- */
139
ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
140
strcpy( ct->id, "NTv1 Grid Shift File" );
142
ct->ll.lam = - *((double *) (header+72));
143
ct->ll.phi = *((double *) (header+24));
144
ur.lam = - *((double *) (header+56));
145
ur.phi = *((double *) (header+40));
146
ct->del.lam = *((double *) (header+104));
147
ct->del.phi = *((double *) (header+88));
148
ct->lim.lam = (int) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
149
ct->lim.phi = (int) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;
151
ct->ll.lam *= DEG_TO_RAD;
152
ct->ll.phi *= DEG_TO_RAD;
153
ct->del.lam *= DEG_TO_RAD;
154
ct->del.phi *= DEG_TO_RAD;
156
/* -------------------------------------------------------------------- */
157
/* Fill the data array. */
159
/* We process one line at a time. Note that the array storage */
160
/* direction (e-w) is different in the NTv1 file and what */
161
/* the CTABLE is supposed to have. The phi/lam are also */
162
/* reversed, and we have to be aware of byte swapping. */
163
/* -------------------------------------------------------------------- */
164
row_buf = (double *) pj_malloc(ct->lim.lam * sizeof(double) * 2);
165
ct->cvs = (FLP *) pj_malloc(ct->lim.lam*ct->lim.phi*sizeof(FLP));
166
if( row_buf == NULL || ct->cvs == NULL )
169
for( row = 0; row < ct->lim.phi; row++ )
173
double *diff_seconds;
175
if( fread( row_buf, sizeof(double), ct->lim.lam * 2, fid )
178
pj_dalloc( row_buf );
179
pj_dalloc( ct->cvs );
184
local_order( (unsigned char *) row_buf, 8, ct->lim.lam * 2 );
186
/* convert seconds to radians */
187
diff_seconds = row_buf;
189
for( i = 0; i < ct->lim.lam; i++ )
191
cvs = ct->cvs + (row) * ct->lim.lam
192
+ (ct->lim.lam - i - 1);
194
cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0);
195
cvs->lam = *(diff_seconds++) * ((PI/180.0) / 3600.0);
199
pj_dalloc( row_buf );
204
/************************************************************************/
205
/* nad_load_ctable() */
207
/* Load a datum shift file already in "CTABLE" format. */
208
/************************************************************************/
210
static struct CTABLE *nad_load_ctable( FILE * fid )
85
/************************************************************************/
86
/* nad_ctable_init() */
88
/* Read the header portion of a "ctable" format grid. */
89
/************************************************************************/
91
struct CTABLE *nad_ctable_init( FILE * fid )
212
93
struct CTABLE *ct;
96
/* read the table header */
215
97
ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
217
99
|| fread( ct, sizeof(struct CTABLE), 1, fid ) != 1 )
267
/* -------------------------------------------------------------------- */
268
/* Load a header, to determine the file type. */
269
/* -------------------------------------------------------------------- */
270
if( fread( header, sizeof(header), 1, fid ) != 1 )
277
fseek( fid, SEEK_SET, 0 );
279
/* -------------------------------------------------------------------- */
280
/* Determine file type. */
281
/* -------------------------------------------------------------------- */
282
if( strncmp(header + 0, "HEADER", 6) == 0
283
&& strncmp(header + 96, "W GRID", 6) == 0
284
&& strncmp(header + 144, "TO NAD83 ", 16) == 0 )
286
ct = nad_load_ntv1( fid );
291
ct = nad_load_ctable( fid );
151
ct = nad_ctable_init( fid );
154
if( !nad_ctable_load( ct, fid ) )