diff options
| author | Frank Warmerdam <warmerdam@pobox.com> | 2011-11-22 22:51:47 +0000 |
|---|---|---|
| committer | Frank Warmerdam <warmerdam@pobox.com> | 2011-11-22 22:51:47 +0000 |
| commit | cf37b02b5540ddf8fb1d9fcf4658a55e3fcaeb33 (patch) | |
| tree | 111b38c0a3d5a0b7b54c790130aebd107c8a2781 /src | |
| parent | d2d560d04c4a1cf78ba3cedb8be9993e3037870c (diff) | |
| download | PROJ-cf37b02b5540ddf8fb1d9fcf4658a55e3fcaeb33.tar.gz PROJ-cf37b02b5540ddf8fb1d9fcf4658a55e3fcaeb33.zip | |
implement support for ctable2 format (read/write)
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@2121 4e78687f-474d-0410-85f9-8d5e500ac6b2
Diffstat (limited to 'src')
| -rw-r--r-- | src/nad2bin.c | 105 | ||||
| -rw-r--r-- | src/nad_init.c | 149 | ||||
| -rw-r--r-- | src/pj_gridinfo.c | 42 | ||||
| -rw-r--r-- | src/projects.h | 2 |
4 files changed, 278 insertions, 20 deletions
diff --git a/src/nad2bin.c b/src/nad2bin.c index 6db9fe67..807859ba 100644 --- a/src/nad2bin.c +++ b/src/nad2bin.c @@ -6,8 +6,6 @@ #define PJ_LIB__ #include <projects.h> #define U_SEC_TO_RAD 4.848136811095359935899141023e-12 - static char -*usage = "<ASCII_dist_table local_bin_table"; /************************************************************************/ /* swap_words() */ @@ -18,10 +16,11 @@ static int byte_order_test = 1; #define IS_LSB (((unsigned char *) (&byte_order_test))[0] == 1) -static void swap_words( unsigned char *data, int word_size, int word_count ) +static void swap_words( void *data_in, int word_size, int word_count ) { int word; + unsigned char *data = (unsigned char *) data_in; for( word = 0; word < word_count; word++ ) { @@ -41,6 +40,17 @@ static void swap_words( unsigned char *data, int word_size, int word_count ) } /************************************************************************/ +/* Usage() */ +/************************************************************************/ + +static void Usage() +{ + fprintf(stderr, + "usage: nad2bin [-f ctable/ctable2/ntv2] binary_output < ascii_source\n" ); + exit(1); +} + +/************************************************************************/ /* main() */ /************************************************************************/ int main(int argc, char **argv) { @@ -51,7 +61,9 @@ int main(int argc, char **argv) { long lam, laml, phi, phil; FILE *fp; - const char *format = "ntv2"; + const char *output_file = NULL; + + const char *format = "ctable2"; const char *GS_TYPE = "SECONDS"; const char *VERSION = ""; const char *SYSTEM_F = "NAD27"; @@ -60,11 +72,28 @@ int main(int argc, char **argv) { const char *CREATED = ""; const char *UPDATED = ""; - if (argc != 2) { - fprintf(stderr,"usage: %s %s\n", argv[0], usage); - exit(1); +/* ==================================================================== */ +/* Process arguments. */ +/* ==================================================================== */ + for( i = 1; i < argc; i++ ) + { + if( strcmp(argv[i],"-f") && i < argc-1 ) + { + format = argv[++i]; + } + else if( output_file == NULL ) + { + output_file = argv[i]; + } + else + Usage(); } + if( output_file == NULL ) + Usage(); + + fprintf( stdout, "Output Binary File Format: %s\n", format ); + /* ==================================================================== */ /* Read the ASCII Table */ /* ==================================================================== */ @@ -109,8 +138,8 @@ int main(int argc, char **argv) { /* ==================================================================== */ if( strcmp(format,"ctable") == 0 ) { - if (!(fp = fopen(argv[1], "wb"))) { - perror(argv[1]); + if (!(fp = fopen(output_file, "wb"))) { + perror(output_file); exit(2); } if (fwrite(&ct, sizeof(ct), 1, fp) != 1 || @@ -123,13 +152,62 @@ int main(int argc, char **argv) { } /* ==================================================================== */ +/* Write out the old ctable format - this is machine and byte */ +/* order specific. */ +/* ==================================================================== */ + if( strcmp(format,"ctable2") == 0 ) + { + char header[160]; + + if (!(fp = fopen(output_file, "wb"))) { + perror(output_file); + exit(2); + } + + assert( MAX_TAB_ID == 80 ); + assert( sizeof(int) == 4 ); /* for ct.lim.lam/phi */ + + memset( header, 0, sizeof(header) ); + + memcpy( header + 0, "CTABLE V2.0 ", 16 ); + memcpy( header + 16, ct.id, 80 ); + memcpy( header + 96, &ct.ll.lam, 8 ); + memcpy( header + 104, &ct.ll.phi, 8 ); + memcpy( header + 112, &ct.del.lam, 8 ); + memcpy( header + 120, &ct.del.phi, 8 ); + memcpy( header + 128, &ct.lim.lam, 4 ); + memcpy( header + 132, &ct.lim.phi, 4 ); + + /* force into LSB format */ + if( !IS_LSB ) + { + swap_words( header + 96, 8, 4 ); + swap_words( header + 128, 4, 2 ); + swap_words( ct.cvs, 4, ct.lim.lam * ct.lim.phi ); + } + + if( fwrite( header, sizeof(header), 1, fp ) != 1 ) { + perror( "fwrite" ); + exit( 2 ); + } + + if (fwrite(ct.cvs, tsize, 1, fp) != 1) { + perror( "fwrite" ); + exit(2); + } + + fclose( fp ); + exit(0); /* normal completion */ + } + +/* ==================================================================== */ /* Write out the NTv2 format grid shift file. */ /* ==================================================================== */ if( strcmp(format,"ntv2") == 0 ) { - if (!(fp = fopen(argv[1], "wb"))) + if (!(fp = fopen(output_file, "wb"))) { - perror(argv[1]); + perror(output_file); exit(2); } @@ -266,7 +344,7 @@ int main(int argc, char **argv) { } if( !IS_LSB ) - swap_words( (unsigned char *) row_buf, 4, ct.lim.lam * 4 ); + swap_words( row_buf, 4, ct.lim.lam * 4 ); if( fwrite( row_buf, sizeof(float), ct.lim.lam*4, fp ) != 4 * ct.lim.lam ) @@ -280,4 +358,7 @@ int main(int argc, char **argv) { fclose( fp ); exit(0); /* normal completion */ } + + fprintf( stderr, "Unsupported format, nothing written.\n" ); + exit( 3 ); } diff --git a/src/nad_init.c b/src/nad_init.c index da10dd2b..20f1adb6 100644 --- a/src/nad_init.c +++ b/src/nad_init.c @@ -45,6 +45,38 @@ #endif /* _WIN32_WCE */ /************************************************************************/ +/* swap_words() */ +/* */ +/* Convert the byte order of the given word(s) in place. */ +/************************************************************************/ + +static int byte_order_test = 1; +#define IS_LSB (((unsigned char *) (&byte_order_test))[0] == 1) + +static void swap_words( void *data_in, int word_size, int word_count ) + +{ + int word; + unsigned char *data = (unsigned char *) data_in; + + for( word = 0; word < word_count; word++ ) + { + int i; + + for( i = 0; i < word_size/2; i++ ) + { + int t; + + t = data[i]; + data[i] = data[word_size-i-1]; + data[word_size-i-1] = t; + } + + data += word_size; + } +} + +/************************************************************************/ /* nad_ctable_load() */ /* */ /* Load the data portion of a ctable formatted grid. */ @@ -66,6 +98,79 @@ int nad_ctable_load( projCtx ctx, struct CTABLE *ct, FILE *fid ) pj_dalloc( ct->cvs ); ct->cvs = NULL; + pj_log( ctx, PJ_LOG_ERROR, + "ctable loading failed on fread() - binary incompatible?\n" ); + pj_ctx_set_errno( ctx, -38 ); + return 0; + } + + return 1; +} + +/************************************************************************/ +/* nad_ctable_init() */ +/* */ +/* Read the header portion of a "ctable" format grid. */ +/************************************************************************/ + +struct CTABLE *nad_ctable_init( projCtx ctx, FILE * fid ) +{ + struct CTABLE *ct; + int id_end; + + /* read the table header */ + ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); + if( ct == NULL + || fread( ct, sizeof(struct CTABLE), 1, fid ) != 1 ) + { + pj_ctx_set_errno( ctx, -38 ); + return NULL; + } + + /* do some minimal validation to ensure the structure isn't corrupt */ + if( ct->lim.lam < 1 || ct->lim.lam > 100000 + || ct->lim.phi < 1 || ct->lim.phi > 100000 ) + { + pj_ctx_set_errno( ctx, -38 ); + return NULL; + } + + /* trim white space and newlines off id */ + for( id_end = strlen(ct->id)-1; id_end > 0; id_end-- ) + { + if( ct->id[id_end] == '\n' || ct->id[id_end] == ' ' ) + ct->id[id_end] = '\0'; + else + break; + } + + ct->cvs = NULL; + + return ct; +} + +/************************************************************************/ +/* nad_ctable2_load() */ +/* */ +/* Load the data portion of a ctable2 formatted grid. */ +/************************************************************************/ + +int nad_ctable2_load( projCtx ctx, struct CTABLE *ct, FILE *fid ) + +{ + int a_size; + + fseek( fid, 160, SEEK_SET ); + + /* read all the actual shift values */ + a_size = ct->lim.lam * ct->lim.phi; + ct->cvs = (FLP *) pj_malloc(sizeof(FLP) * a_size); + if( ct->cvs == NULL + || fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size ) + { + pj_dalloc( ct->cvs ); + ct->cvs = NULL; + if( getenv("PROJ_DEBUG") != NULL ) { fprintf( stderr, @@ -76,29 +181,61 @@ int nad_ctable_load( projCtx ctx, struct CTABLE *ct, FILE *fid ) return 0; } + if( !IS_LSB ) + { + swap_words( ct->cvs, 4, a_size * 2 ); + } + return 1; } /************************************************************************/ -/* nad_ctable_init() */ +/* nad_ctable2_init() */ /* */ -/* Read the header portion of a "ctable" format grid. */ +/* Read the header portion of a "ctable2" format grid. */ /************************************************************************/ -struct CTABLE *nad_ctable_init( projCtx ctx, FILE * fid ) +struct CTABLE *nad_ctable2_init( projCtx ctx, FILE * fid ) { struct CTABLE *ct; int id_end; + char header[160]; + + if( fread( header, sizeof(header), 1, fid ) != 1 ) + { + pj_ctx_set_errno( ctx, -38 ); + return NULL; + } + + if( !IS_LSB ) + { + swap_words( header + 96, 8, 4 ); + swap_words( header + 128, 4, 2 ); + } + + if( strncmp(header,"CTABLE V2",9) != 0 ) + { + pj_log( ctx, PJ_LOG_ERROR, "ctable2 - wrong header!" ); + pj_ctx_set_errno( ctx, -38 ); + return NULL; + } /* read the table header */ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); - if( ct == NULL - || fread( ct, sizeof(struct CTABLE), 1, fid ) != 1 ) + if( ct == NULL ) { pj_ctx_set_errno( ctx, -38 ); return NULL; } + memcpy( ct->id, header + 16, 80 ); + memcpy( &ct->ll.lam, header + 96, 8 ); + memcpy( &ct->ll.phi, header + 104, 8 ); + memcpy( &ct->del.lam, header + 112, 8 ); + memcpy( &ct->del.phi, header + 120, 8 ); + memcpy( &ct->lim.lam, header + 128, 4 ); + memcpy( &ct->lim.phi, header + 132, 4 ); + /* do some minimal validation to ensure the structure isn't corrupt */ if( ct->lim.lam < 1 || ct->lim.lam > 100000 || ct->lim.phi < 1 || ct->lim.phi > 100000 ) @@ -142,7 +279,7 @@ struct CTABLE *nad_init(projCtx ctx, char *name) if (!(fid = pj_open_lib(ctx, fname, "rb"))) { return 0; } - + ct = nad_ctable_init( ctx, fid ); if( ct != NULL ) { diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c index 34e65fb2..cba1e672 100644 --- a/src/pj_gridinfo.c +++ b/src/pj_gridinfo.c @@ -122,8 +122,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) return 0; /* -------------------------------------------------------------------- */ -/* ctable is currently loaded on initialization though there is */ -/* no real reason not to support delayed loading for it as well. */ +/* Original platform specific CTable format. */ /* -------------------------------------------------------------------- */ if( strcmp(gi->format,"ctable") == 0 ) { @@ -146,6 +145,29 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) } /* -------------------------------------------------------------------- */ +/* CTable2 format. */ +/* -------------------------------------------------------------------- */ + else if( strcmp(gi->format,"ctable2") == 0 ) + { + FILE *fid; + int result; + + fid = pj_open_lib( ctx, gi->filename, "rb" ); + + if( fid == NULL ) + { + pj_ctx_set_errno( ctx, -38 ); + return 0; + } + + result = nad_ctable2_load( ctx, gi->ct, fid ); + + fclose( fid ); + + return result; + } + +/* -------------------------------------------------------------------- */ /* NTv1 format. */ /* We process one line at a time. Note that the array storage */ /* direction (e-w) is different in the NTv1 file and what */ @@ -810,6 +832,22 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) pj_gridinfo_init_gtx( ctx, fp, gilist ); } + else if( strncmp(header+0,"CTABLE V2",9) == 0 ) + { + struct CTABLE *ct = nad_ctable2_init( ctx, fp ); + + gilist->format = "ctable2"; + gilist->ct = ct; + + pj_log( ctx, PJ_LOG_DEBUG_MAJOR, + "Ctable2 %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)\n", + ct->id, + ct->lim.lam, ct->lim.phi, + ct->ll.lam * RAD_TO_DEG, ct->ll.phi * RAD_TO_DEG, + (ct->ll.lam + (ct->lim.lam-1)*ct->del.lam) * RAD_TO_DEG, + (ct->ll.phi + (ct->lim.phi-1)*ct->del.phi) * RAD_TO_DEG ); + } + else { struct CTABLE *ct = nad_ctable_init( ctx, fp ); diff --git a/src/projects.h b/src/projects.h index 7c41242b..fb49652d 100644 --- a/src/projects.h +++ b/src/projects.h @@ -416,6 +416,8 @@ LP nad_cvt(LP, int, struct CTABLE *); struct CTABLE *nad_init(projCtx ctx, char *); struct CTABLE *nad_ctable_init( projCtx ctx, FILE * fid ); int nad_ctable_load( projCtx ctx, struct CTABLE *, FILE * fid ); +struct CTABLE *nad_ctable2_init( projCtx ctx, FILE * fid ); +int nad_ctable2_load( projCtx ctx, struct CTABLE *, FILE * fid ); void nad_free(struct CTABLE *); /* higher level handling of datum grid shift files */ |
