~ubuntu-branches/ubuntu/breezy/proj/breezy

« back to all changes in this revision

Viewing changes to src/nad_init.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter S Galbraith
  • Date: 2004-11-06 19:44:53 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041106194453-axnsmkh1zplal8mz
Tags: upstream-4.4.9
ImportĀ upstreamĀ versionĀ 4.4.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: nad_init.c,v 1.4 2001/08/17 17:28:37 warmerda Exp $
 
2
 * $Id: nad_init.c,v 1.8 2003/03/17 18:56:01 warmerda Exp $
3
3
 *
4
4
 * Project:  PROJ.4
5
5
 * Purpose:  Load datum shift files into memory.
28
28
 ******************************************************************************
29
29
 *
30
30
 * $Log: nad_init.c,v $
 
31
 * Revision 1.8  2003/03/17 18:56:01  warmerda
 
32
 * implement delayed loading of ctable format files
 
33
 *
 
34
 * Revision 1.7  2003/03/15 06:02:02  warmerda
 
35
 * preliminary NTv2 support, major restructure of datum shifting
 
36
 *
 
37
 * Revision 1.6  2002/07/08 02:32:05  warmerda
 
38
 * ensure clean C++ builds
 
39
 *
 
40
 * Revision 1.5  2002/04/30 16:26:07  warmerda
 
41
 * trip newlines of ctable id field
 
42
 *
31
43
 * Revision 1.4  2001/08/17 17:28:37  warmerda
32
44
 * removed use of emess()
33
45
 *
42
54
#include <stdio.h>
43
55
#include <errno.h>
44
56
#include <assert.h>
45
 
 
46
 
static int  byte_order_test = 1;
47
 
#define IS_LSB  (((unsigned char *) (&byte_order_test))[0] == 1)
48
 
 
49
 
/************************************************************************/
50
 
/*                            local_order()                             */
51
 
/*                                                                      */
52
 
/*      Convert the given words into local order in place.              */
53
 
/************************************************************************/
54
 
 
55
 
static void local_order( unsigned char *data, int word_size, int word_count )
56
 
 
57
 
{
58
 
    /* We only need to do work on LSB machines.  Perhaps we should 
59
 
       convert the data files into LSB order to cut workload! */
60
 
 
61
 
    if( IS_LSB )
62
 
    {
63
 
        int     word;
64
 
 
65
 
        for( word = 0; word < word_count; word++ )
66
 
        {
67
 
            int i;
68
 
 
69
 
            for( i = 0; i < word_size/2; i++ )
70
 
            {
71
 
                int     t;
72
 
 
73
 
                t = data[i];
74
 
                data[i] = data[word_size-i-1];
75
 
                data[word_size-i-1] = t;
76
 
            }
77
 
 
78
 
            data += word_size;
79
 
        }
80
 
    }
81
 
}
82
 
 
83
 
/************************************************************************/
84
 
/*                           nad_load_ntv1()                            */
85
 
/*                                                                      */
86
 
/*      Load an NTv1 style Canadian grid shift file.                    */
87
 
/************************************************************************/
88
 
 
89
 
static struct CTABLE *nad_load_ntv1( FILE * fid )
90
 
 
91
 
{
92
 
    char        header[176];
93
 
    struct CTABLE *ct;
94
 
    LP          ur;
95
 
    double      *row_buf;
96
 
    int         row;
97
 
    
98
 
    assert( sizeof(int) == 4 );
99
 
    assert( sizeof(double) == 8 );
100
 
    if( sizeof(int) != 4 || sizeof(double) != 8 )
101
 
    {
102
 
        fprintf( stderr, 
103
 
                 "basic types of inappropraiate size in nad_load_ntv1()\n" );
104
 
        pj_errno = -38;
105
 
        return NULL;
106
 
    }
107
 
 
108
 
/* -------------------------------------------------------------------- */
109
 
/*      Read the header.                                                */
110
 
/* -------------------------------------------------------------------- */
111
 
    if( fread( header, sizeof(header), 1, fid ) != 1 )
112
 
    {
113
 
        fclose( fid );
 
57
#include <string.h>
 
58
 
 
59
/************************************************************************/
 
60
/*                          nad_ctable_load()                           */
 
61
/*                                                                      */
 
62
/*      Load the data portion of a ctable formatted grid.               */
 
63
/************************************************************************/
 
64
 
 
65
int nad_ctable_load( struct CTABLE *ct, FILE *fid )
 
66
 
 
67
{
 
68
    int  a_size;
 
69
 
 
70
    fseek( fid, sizeof(struct CTABLE), SEEK_SET );
 
71
 
 
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);
 
75
    if( ct->cvs == NULL 
 
76
        || fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size )
 
77
    {
114
78
        pj_errno = -38;
115
79
        return 0;
116
80
    }
117
81
 
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 );
128
 
 
129
 
    if( *((int *) (header+8)) != 12 )
130
 
    {
131
 
        pj_errno = -38;
132
 
        printf("NTv1 grid shift file has wrong record count, corrupt?\n");
133
 
        return NULL;
134
 
    }
135
 
 
136
 
/* -------------------------------------------------------------------- */
137
 
/*      Fill in CTABLE structure.                                       */
138
 
/* -------------------------------------------------------------------- */
139
 
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
140
 
    strcpy( ct->id, "NTv1 Grid Shift File" );
141
 
 
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;
150
 
 
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;
155
 
 
156
 
/* -------------------------------------------------------------------- */
157
 
/*      Fill the data array.                                            */
158
 
/*                                                                      */
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 )
167
 
        return NULL;
168
 
 
169
 
    for( row = 0; row < ct->lim.phi; row++ )
170
 
    {
171
 
        int     i;
172
 
        FLP     *cvs;
173
 
        double  *diff_seconds;
174
 
 
175
 
        if( fread( row_buf, sizeof(double), ct->lim.lam * 2, fid ) 
176
 
            != 2 * ct->lim.lam )
177
 
        {
178
 
            pj_dalloc( row_buf );
179
 
            pj_dalloc( ct->cvs );
180
 
            pj_errno = -38;
181
 
            return NULL;
182
 
        }
183
 
 
184
 
        local_order( (unsigned char *) row_buf, 8, ct->lim.lam * 2 );
185
 
 
186
 
        /* convert seconds to radians */
187
 
        diff_seconds = row_buf;
188
 
 
189
 
        for( i = 0; i < ct->lim.lam; i++ )
190
 
        {
191
 
            cvs = ct->cvs + (row) * ct->lim.lam
192
 
                + (ct->lim.lam - i - 1);
193
 
 
194
 
            cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0);
195
 
            cvs->lam = *(diff_seconds++) * ((PI/180.0) / 3600.0);
196
 
        }
197
 
    }
198
 
 
199
 
    pj_dalloc( row_buf );
200
 
 
201
 
    return ct;
202
 
}
203
 
 
204
 
/************************************************************************/
205
 
/*                          nad_load_ctable()                           */
206
 
/*                                                                      */
207
 
/*      Load a datum shift file already in "CTABLE" format.             */
208
 
/************************************************************************/
209
 
 
210
 
static struct CTABLE *nad_load_ctable( FILE * fid )
 
82
    return 1;
 
83
 
84
 
 
85
/************************************************************************/
 
86
/*                          nad_ctable_init()                           */
 
87
/*                                                                      */
 
88
/*      Read the header portion of a "ctable" format grid.              */
 
89
/************************************************************************/
 
90
 
 
91
struct CTABLE *nad_ctable_init( FILE * fid )
211
92
{
212
93
    struct CTABLE *ct;
213
 
    int         a_size;
 
94
    int         id_end;
214
95
 
 
96
    /* read the table header */
215
97
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
216
98
    if( ct == NULL 
217
99
        || fread( ct, sizeof(struct CTABLE), 1, fid ) != 1 )
220
102
        return NULL;
221
103
    }
222
104
 
 
105
    /* do some minimal validation to ensure the structure isn't corrupt */
223
106
    if( ct->lim.lam < 1 || ct->lim.lam > 100000 
224
107
        || ct->lim.phi < 1 || ct->lim.phi > 100000 )
225
108
    {
227
110
        return NULL;
228
111
    }
229
112
    
230
 
    a_size = ct->lim.lam * ct->lim.phi;
231
 
    ct->cvs = (FLP *) pj_malloc(sizeof(FLP) * a_size);
232
 
    if( ct->cvs == NULL 
233
 
        || fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size )
 
113
    /* trim white space and newlines off id */
 
114
    for( id_end = strlen(ct->id)-1; id_end > 0; id_end-- )
234
115
    {
235
 
        nad_free( ct );
236
 
        pj_errno = -38;
237
 
        return NULL;
 
116
        if( ct->id[id_end] == '\n' || ct->id[id_end] == ' ' )
 
117
            ct->id[id_end] = '\0';
 
118
        else
 
119
            break;
238
120
    }
239
121
 
 
122
    ct->cvs = NULL;
 
123
 
240
124
    return ct;
241
125
}
242
126
 
264
148
        return 0;
265
149
    }
266
150
    
267
 
/* -------------------------------------------------------------------- */
268
 
/*      Load a header, to determine the file type.                      */
269
 
/* -------------------------------------------------------------------- */
270
 
    if( fread( header, sizeof(header), 1, fid ) != 1 )
271
 
    {
272
 
        fclose( fid );
273
 
        pj_errno = -38;
274
 
        return 0;
275
 
    }
276
 
 
277
 
    fseek( fid, SEEK_SET, 0 );
278
 
 
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 )
285
 
    {
286
 
        ct = nad_load_ntv1( fid );
287
 
    }
288
 
    
289
 
    else
290
 
    {
291
 
        ct = nad_load_ctable( fid );
 
151
    ct = nad_ctable_init( fid );
 
152
    if( ct != NULL )
 
153
    {
 
154
        if( !nad_ctable_load( ct, fid ) )
 
155
        {
 
156
            nad_free( ct );
 
157
            ct = NULL;
 
158
        }
292
159
    }
293
160
 
294
161
    fclose(fid);
304
171
void nad_free(struct CTABLE *ct) 
305
172
{
306
173
    if (ct) {
307
 
        pj_dalloc(ct->cvs);
 
174
        if( ct->cvs != NULL )
 
175
            pj_dalloc(ct->cvs);
 
176
 
308
177
        pj_dalloc(ct);
309
178
    }
310
179
}