aboutsummaryrefslogtreecommitdiff
path: root/src/nad_init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/nad_init.cpp')
-rw-r--r--src/nad_init.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/src/nad_init.cpp b/src/nad_init.cpp
new file mode 100644
index 00000000..8b024ac7
--- /dev/null
+++ b/src/nad_init.cpp
@@ -0,0 +1,305 @@
+/******************************************************************************
+ * Project: PROJ.4
+ * Purpose: Load datum shift files into memory.
+ * Author: Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2000, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#define PJ_LIB__
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "projects.h"
+
+/************************************************************************/
+/* swap_words() */
+/* */
+/* Convert the byte order of the given word(s) in place. */
+/************************************************************************/
+
+static const int byte_order_test = 1;
+#define IS_LSB (((const 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++ )
+ {
+ unsigned char 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. */
+/************************************************************************/
+
+int nad_ctable_load( projCtx ctx, struct CTABLE *ct, PAFile fid )
+
+{
+ size_t a_size;
+
+ pj_ctx_fseek( ctx, fid, sizeof(struct CTABLE), 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
+ || pj_ctx_fread(ctx, ct->cvs, sizeof(FLP), a_size, fid) != a_size )
+ {
+ pj_dalloc( ct->cvs );
+ ct->cvs = NULL;
+
+ pj_log( ctx, PJ_LOG_ERROR,
+ "ctable loading failed on fread() - binary incompatible?" );
+ pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
+ return 0;
+ }
+
+ return 1;
+}
+
+/************************************************************************/
+/* nad_ctable_init() */
+/* */
+/* Read the header portion of a "ctable" format grid. */
+/************************************************************************/
+
+struct CTABLE *nad_ctable_init( projCtx ctx, PAFile fid )
+{
+ struct CTABLE *ct;
+ int id_end;
+
+ /* read the table header */
+ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
+ if( ct == NULL
+ || pj_ctx_fread( ctx, ct, sizeof(struct CTABLE), 1, fid ) != 1 )
+ {
+ pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
+ pj_dalloc( ct );
+ 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, PJD_ERR_FAILED_TO_LOAD_GRID );
+ pj_dalloc( ct );
+ return NULL;
+ }
+
+ /* trim white space and newlines off id */
+ for( id_end = (int)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, PAFile fid )
+
+{
+ size_t a_size;
+
+ pj_ctx_fseek( ctx, 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
+ || pj_ctx_fread(ctx, ct->cvs, sizeof(FLP), a_size, fid) != a_size )
+ {
+ pj_dalloc( ct->cvs );
+ ct->cvs = NULL;
+
+ if( getenv("PROJ_DEBUG") != NULL )
+ {
+ fprintf( stderr,
+ "ctable2 loading failed on fread() - binary incompatible?\n" );
+ }
+
+ pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
+ return 0;
+ }
+
+ if( !IS_LSB )
+ {
+ swap_words( ct->cvs, 4, (int)a_size * 2 );
+ }
+
+ return 1;
+}
+
+/************************************************************************/
+/* nad_ctable2_init() */
+/* */
+/* Read the header portion of a "ctable2" format grid. */
+/************************************************************************/
+
+struct CTABLE *nad_ctable2_init( projCtx ctx, PAFile fid )
+{
+ struct CTABLE *ct;
+ int id_end;
+ char header[160];
+
+ if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
+ {
+ pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
+ 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, PJD_ERR_FAILED_TO_LOAD_GRID );
+ return NULL;
+ }
+
+ /* read the table header */
+ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
+ if( ct == NULL )
+ {
+ pj_ctx_set_errno( ctx, ENOMEM );
+ 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 )
+ {
+ pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
+ pj_dalloc( ct );
+ return NULL;
+ }
+
+ /* trim white space and newlines off id */
+ for( id_end = (int)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_init() */
+/* */
+/* Read a datum shift file in any of the supported binary formats. */
+/************************************************************************/
+
+struct CTABLE *nad_init(projCtx ctx, char *name)
+{
+ char fname[MAX_PATH_FILENAME+1];
+ struct CTABLE *ct;
+ PAFile fid;
+
+ ctx->last_errno = 0;
+
+/* -------------------------------------------------------------------- */
+/* Open the file using the usual search rules. */
+/* -------------------------------------------------------------------- */
+ strcpy(fname, name);
+ if (!(fid = pj_open_lib(ctx, fname, "rb"))) {
+ return 0;
+ }
+
+ ct = nad_ctable_init( ctx, fid );
+ if( ct != NULL )
+ {
+ if( !nad_ctable_load( ctx, ct, fid ) )
+ {
+ nad_free( ct );
+ ct = NULL;
+ }
+ }
+
+ pj_ctx_fclose(ctx, fid);
+ return ct;
+}
+
+/************************************************************************/
+/* nad_free() */
+/* */
+/* Free a CTABLE grid shift structure produced by nad_init(). */
+/************************************************************************/
+
+void nad_free(struct CTABLE *ct)
+{
+ if (ct) {
+ if( ct->cvs != NULL )
+ pj_dalloc(ct->cvs);
+
+ pj_dalloc(ct);
+ }
+}