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; }
struct CTABLE *nad_init(char *name) { char fname[MAX_PATH_FILENAME+1]; struct CTABLE *ct; FILE *fid; char header[512]; errno = pj_errno = 0; /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ strcpy(fname, name); if (!(fid = pj_open_lib(fname, "rb"))) { pj_errno = errno; return 0; } ct = nad_ctable_init( fid ); if( ct != NULL ) { if( !nad_ctable_load( ct, fid ) ) { nad_free( ct ); ct = NULL; } } fclose(fid); return ct; }
SEXP PROJcopyEPSG(SEXP tf) { SEXP ans; FILE *fp, *fptf; char buf[MAX_LINE_LEN+1]; /* input buffer */ int i=0; PROTECT(ans=NEW_INTEGER(1)); INTEGER_POINTER(ans)[0] = 0; #ifdef OSGEO4W fp = fopen("C:\\OSGeo4W\\share\\proj\\epsg", "rb"); #else fp = pj_open_lib("epsg", "rb"); #endif /* OSGEO4W */ if (fp == NULL) INTEGER_POINTER(ans)[0] = 0; else { fptf = fopen(CHAR(STRING_ELT(tf, 0)), "wb"); if (fptf == NULL) { INTEGER_POINTER(ans)[0] = 0; fclose(fp); UNPROTECT(1); return(ans); } /* copy from fp to fptf */ /* copy source file to target file, line by line. */ while (fgets(buf, MAX_LINE_LEN+1, fp)) { if (fputs(buf, fptf) == EOF) { /* error writing data */ INTEGER_POINTER(ans)[0] = 0; fclose(fp); fclose(fptf); UNPROTECT(1); return(ans); } i++; } if (!feof(fp)) { /* fgets failed _not_ due to encountering EOF */ INTEGER_POINTER(ans)[0] = 0; fclose(fp); fclose(fptf); UNPROTECT(1); return(ans); } INTEGER_POINTER(ans)[0] = i; fclose(fp); fclose(fptf); } UNPROTECT(1); return(ans); }
static paralist * get_defaults(paralist **start, paralist *next, char *name) { FILE *fid; if ((fid = pj_open_lib("proj_def.dat", "rt"))) { next = get_opt(start, fid, "general", next); rewind(fid); next = get_opt(start, fid, name, next); (void)fclose(fid); } if (errno) errno = 0; /* don't care if can't open file */ return next; }
static paralist * get_init(projCtx ctx, paralist **start, paralist *next, char *name) { char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt; FILE *fid; paralist *init_items = NULL; const paralist *orig_next = next; (void)strncpy(fname, name, MAX_PATH_FILENAME + ID_TAG_MAX + 1); /* ** Search for file/key pair in cache */ init_items = pj_search_initcache( name ); if( init_items != NULL ) { next->next = init_items; while( next->next != NULL ) next = next->next; return next; } /* ** Otherwise we try to open the file and search for it. */ if ((opt = strrchr(fname, ':')) != NULL) *opt++ = '\0'; else { pj_ctx_set_errno(ctx,-3); return NULL; } if ( (fid = pj_open_lib(ctx,fname, "rt")) != NULL) next = get_opt(ctx, start, fid, opt, next); else return NULL; (void)fclose(fid); if (errno == 25) errno = 0; /* unknown problem with some sys errno<-25 */ /* ** If we seem to have gotten a result, insert it into the ** init file cache. */ if( next != NULL && next != orig_next ) pj_insert_initcache( name, orig_next->next ); return next; }
static paralist * get_init(paralist **start, paralist *next, char *name) { char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt; FILE *fid; (void)strncpy(fname, name, MAX_PATH_FILENAME + ID_TAG_MAX + 1); if (opt = strrchr(fname, ':')) *opt++ = '\0'; else { pj_errno = -3; return(0); } if (fid = pj_open_lib(fname, "rt")) next = get_opt(start, fid, opt, next); else return(0); (void)fclose(fid); if (errno == 25) errno = 0; /* unknown problem with some sys errno<-25 */ return next; }
PJ_GridCatalog *pj_gc_readcatalog( projCtx ctx, const char *catalog_name ) { PAFile fid; PJ_GridCatalog *catalog; int entry_max; char line[302]; fid = pj_open_lib( ctx, (char *) catalog_name, "r" ); if (fid == NULL) return NULL; /* discard title line */ pj_ctx_fgets(ctx, line, sizeof(line)-1, fid); catalog = (PJ_GridCatalog *) calloc(1,sizeof(PJ_GridCatalog)); if( !catalog ) return NULL; catalog->catalog_name = strdup(catalog_name); entry_max = 10; catalog->entries = (PJ_GridCatalogEntry *) malloc(entry_max * sizeof(PJ_GridCatalogEntry)); while( pj_gc_readentry( ctx, fid, catalog->entries+catalog->entry_count) == 0) { catalog->entry_count++; if( catalog->entry_count == entry_max ) { entry_max = entry_max * 2; catalog->entries = (PJ_GridCatalogEntry *) realloc(catalog->entries, entry_max * sizeof(PJ_GridCatalogEntry)); if (catalog->entries == NULL ) return NULL; } } pj_gc_sortcatalog( ctx, catalog ); return catalog; }
SEXP PROJ4NADsInstalled(void) { SEXP ans; #ifdef OSGEO4W PROTECT(ans=NEW_LOGICAL(1)); LOGICAL_POINTER(ans)[0] = TRUE; #else FILE *fp; PROTECT(ans=NEW_LOGICAL(1)); fp = pj_open_lib("conus", "rb"); if (fp == NULL) LOGICAL_POINTER(ans)[0] = FALSE; else { LOGICAL_POINTER(ans)[0] = TRUE; fclose(fp); } #endif /* OSGEO4W */ UNPROTECT(1); return(ans); }
PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) { char fname[MAX_PATH_FILENAME+1]; PJ_GRIDINFO *gilist; PAFile fp; char header[160]; size_t header_size = 0; errno = pj_errno = 0; ctx->last_errno = 0; /* -------------------------------------------------------------------- */ /* Initialize a GRIDINFO with stub info we would use if it */ /* cannot be loaded. */ /* -------------------------------------------------------------------- */ gilist = (PJ_GRIDINFO *) pj_calloc(1, sizeof(PJ_GRIDINFO)); if (!gilist) { pj_ctx_set_errno(ctx, ENOMEM); return NULL; } gilist->gridname = pj_strdup( gridname ); if (!gilist->gridname) { pj_dalloc(gilist); pj_ctx_set_errno(ctx, ENOMEM); return NULL; } gilist->filename = NULL; gilist->format = "missing"; gilist->grid_offset = 0; gilist->ct = NULL; gilist->next = NULL; /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ strcpy(fname, gridname); if (!(fp = pj_open_lib(ctx, fname, "rb"))) { ctx->last_errno = 0; /* don't treat as a persistent error */ return gilist; } gilist->filename = pj_strdup(fname); if (!gilist->filename) { pj_dalloc(gilist->gridname); pj_dalloc(gilist); pj_ctx_set_errno(ctx, ENOMEM); return NULL; } /* -------------------------------------------------------------------- */ /* Load a header, to determine the file type. */ /* -------------------------------------------------------------------- */ if( (header_size = pj_ctx_fread( ctx, header, 1, sizeof(header), fp ) ) != sizeof(header) ) { /* some files may be smaller that sizeof(header), eg 160, so */ ctx->last_errno = 0; /* don't treat as a persistent error */ pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "pj_gridinfo_init: short header read of %d bytes", (int)header_size ); } pj_ctx_fseek( ctx, fp, SEEK_SET, 0 ); /* -------------------------------------------------------------------- */ /* Determine file type. */ /* -------------------------------------------------------------------- */ if( header_size >= 144 + 16 && strncmp(header + 0, "HEADER", 6) == 0 && strncmp(header + 96, "W GRID", 6) == 0 && strncmp(header + 144, "TO NAD83 ", 16) == 0 ) { pj_gridinfo_init_ntv1( ctx, fp, gilist ); } else if( header_size >= 48 + 7 && strncmp(header + 0, "NUM_OREC", 8) == 0 && strncmp(header + 48, "GS_TYPE", 7) == 0 ) { pj_gridinfo_init_ntv2( ctx, fp, gilist ); } else if( strlen(gridname) > 4 && (strcmp(gridname+strlen(gridname)-3,"gtx") == 0 || strcmp(gridname+strlen(gridname)-3,"GTX") == 0) ) { pj_gridinfo_init_gtx( ctx, fp, gilist ); } else if( header_size >= 9 && strncmp(header + 0,"CTABLE V2",9) == 0 ) { struct CTABLE *ct = nad_ctable2_init( ctx, fp ); gilist->format = "ctable2"; gilist->ct = ct; if (ct == NULL) { pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "CTABLE V2 ct is NULL."); } else { pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "Ctable2 %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)", 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 ); if (ct == NULL) { pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "CTABLE ct is NULL."); } else { gilist->format = "ctable"; gilist->ct = ct; pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "Ctable %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)", 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 ); } } pj_ctx_fclose(ctx, fp); return gilist; }
int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) { struct CTABLE ct_tmp; if( gi == NULL || gi->ct == NULL ) return 0; pj_acquire_lock(); if( gi->ct->cvs != NULL ) { pj_release_lock(); return 1; } memcpy(&ct_tmp, gi->ct, sizeof(struct CTABLE)); /* -------------------------------------------------------------------- */ /* Original platform specific CTable format. */ /* -------------------------------------------------------------------- */ if( strcmp(gi->format,"ctable") == 0 ) { PAFile fid; int result; fid = pj_open_lib( ctx, gi->filename, "rb" ); if( fid == NULL ) { pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } result = nad_ctable_load( ctx, &ct_tmp, fid ); pj_ctx_fclose( ctx, fid ); gi->ct->cvs = ct_tmp.cvs; pj_release_lock(); return result; } /* -------------------------------------------------------------------- */ /* CTable2 format. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"ctable2") == 0 ) { PAFile fid; int result; fid = pj_open_lib( ctx, gi->filename, "rb" ); if( fid == NULL ) { pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } result = nad_ctable2_load( ctx, &ct_tmp, fid ); pj_ctx_fclose( ctx, fid ); gi->ct->cvs = ct_tmp.cvs; pj_release_lock(); 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 */ /* the CTABLE is supposed to have. The phi/lam are also */ /* reversed, and we have to be aware of byte swapping. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"ntv1") == 0 ) { double *row_buf; int row; PAFile fid; fid = pj_open_lib( ctx, gi->filename, "rb" ); if( fid == NULL ) { pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); row_buf = (double *) pj_malloc(gi->ct->lim.lam * sizeof(double) * 2); ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || ct_tmp.cvs == NULL ) { pj_dalloc( row_buf ); pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } for( row = 0; row < gi->ct->lim.phi; row++ ) { int i; FLP *cvs; double *diff_seconds; if( pj_ctx_fread( ctx, row_buf, sizeof(double), gi->ct->lim.lam * 2, fid ) != (size_t)( 2 * gi->ct->lim.lam ) ) { pj_dalloc( row_buf ); pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } if( IS_LSB ) swap_words( (unsigned char *) row_buf, 8, gi->ct->lim.lam*2 ); /* convert seconds to radians */ diff_seconds = row_buf; for( i = 0; i < gi->ct->lim.lam; i++ ) { cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0)); cvs->lam = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0)); } } pj_dalloc( row_buf ); pj_ctx_fclose( ctx, fid ); gi->ct->cvs = ct_tmp.cvs; pj_release_lock(); return 1; } /* -------------------------------------------------------------------- */ /* NTv2 format. */ /* We process one line at a time. Note that the array storage */ /* direction (e-w) is different in the NTv2 file and what */ /* the CTABLE is supposed to have. The phi/lam are also */ /* reversed, and we have to be aware of byte swapping. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"ntv2") == 0 ) { float *row_buf; int row; PAFile fid; pj_log( ctx, PJ_LOG_DEBUG_MINOR, "NTv2 - loading grid %s", gi->ct->id ); fid = pj_open_lib( ctx, gi->filename, "rb" ); if( fid == NULL ) { pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); row_buf = (float *) pj_malloc(gi->ct->lim.lam * sizeof(float) * 4); ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || ct_tmp.cvs == NULL ) { pj_dalloc( row_buf ); pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } for( row = 0; row < gi->ct->lim.phi; row++ ) { int i; FLP *cvs; float *diff_seconds; if( pj_ctx_fread( ctx, row_buf, sizeof(float), gi->ct->lim.lam*4, fid ) != (size_t)( 4 * gi->ct->lim.lam ) ) { pj_dalloc( row_buf ); pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } if( gi->must_swap ) swap_words( (unsigned char *) row_buf, 4, gi->ct->lim.lam*4 ); /* convert seconds to radians */ diff_seconds = row_buf; for( i = 0; i < gi->ct->lim.lam; i++ ) { cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0)); cvs->lam = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0)); diff_seconds += 2; /* skip accuracy values */ } } pj_dalloc( row_buf ); pj_ctx_fclose( ctx, fid ); gi->ct->cvs = ct_tmp.cvs; pj_release_lock(); return 1; } /* -------------------------------------------------------------------- */ /* GTX format. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"gtx") == 0 ) { int words = gi->ct->lim.lam * gi->ct->lim.phi; PAFile fid; fid = pj_open_lib( ctx, gi->filename, "rb" ); if( fid == NULL ) { pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); ct_tmp.cvs = (FLP *) pj_malloc(words*sizeof(float)); if( ct_tmp.cvs == NULL ) { pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } if( pj_ctx_fread( ctx, ct_tmp.cvs, sizeof(float), words, fid ) != (size_t)words ) { pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } if( IS_LSB ) swap_words( (unsigned char *) ct_tmp.cvs, 4, words ); pj_ctx_fclose( ctx, fid ); gi->ct->cvs = ct_tmp.cvs; pj_release_lock(); return 1; } else { pj_release_lock(); return 0; } }
PJ_GRIDINFO *pj_gridinfo_init( const char *gridname ) { char fname[MAX_PATH_FILENAME+1]; PJ_GRIDINFO *gilist; FILE *fp; char header[160]; errno = pj_errno = 0; /* -------------------------------------------------------------------- */ /* Initialize a GRIDINFO with stub info we would use if it */ /* cannot be loaded. */ /* -------------------------------------------------------------------- */ gilist = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); memset( gilist, 0, sizeof(PJ_GRIDINFO) ); gilist->gridname = strdup( gridname ); gilist->filename = NULL; gilist->format = "missing"; gilist->grid_offset = 0; gilist->ct = NULL; gilist->next = NULL; /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ strcpy(fname, gridname); if (!(fp = pj_open_lib(fname, "rb"))) { pj_errno = errno; return gilist; } gilist->filename = strdup(fname); /* -------------------------------------------------------------------- */ /* Load a header, to determine the file type. */ /* -------------------------------------------------------------------- */ if( fread( header, sizeof(header), 1, fp ) != 1 ) { fclose( fp ); pj_errno = -38; return gilist; } fseek( fp, SEEK_SET, 0 ); /* -------------------------------------------------------------------- */ /* Determine file type. */ /* -------------------------------------------------------------------- */ if( strncmp(header + 0, "HEADER", 6) == 0 && strncmp(header + 96, "W GRID", 6) == 0 && strncmp(header + 144, "TO NAD83 ", 16) == 0 ) { pj_gridinfo_init_ntv1( fp, gilist ); } else if( strncmp(header + 0, "NUM_OREC", 8) == 0 && strncmp(header + 48, "GS_TYPE", 7) == 0 ) { pj_gridinfo_init_ntv2( fp, gilist ); } else { struct CTABLE *ct = nad_ctable_init( fp ); gilist->format = "ctable"; gilist->ct = ct; if( getenv("PROJ_DEBUG") != NULL ) fprintf( stderr, "Ctable %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 ); } fclose(fp); return gilist; }
int pj_gridinfo_load( PJ_GRIDINFO *gi ) { if( gi == NULL || gi->ct == NULL ) return 0; /* -------------------------------------------------------------------- */ /* ctable is currently loaded on initialization though there is */ /* no real reason not to support delayed loading for it as well. */ /* -------------------------------------------------------------------- */ if( strcmp(gi->format,"ctable") == 0 ) { FILE *fid; int result; fid = pj_open_lib( gi->filename, "rb" ); if( fid == NULL ) { pj_errno = -38; return 0; } result = nad_ctable_load( 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 */ /* the CTABLE is supposed to have. The phi/lam are also */ /* reversed, and we have to be aware of byte swapping. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"ntv1") == 0 ) { double *row_buf; int row; FILE *fid; fid = pj_open_lib( gi->filename, "rb" ); if( fid == NULL ) { pj_errno = -38; return 0; } fseek( fid, gi->grid_offset, SEEK_SET ); row_buf = (double *) pj_malloc(gi->ct->lim.lam * sizeof(double) * 2); gi->ct->cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || gi->ct->cvs == NULL ) { pj_errno = -38; return 0; } for( row = 0; row < gi->ct->lim.phi; row++ ) { int i; FLP *cvs; double *diff_seconds; if( fread( row_buf, sizeof(double), gi->ct->lim.lam * 2, fid ) != 2 * gi->ct->lim.lam ) { pj_dalloc( row_buf ); pj_dalloc( gi->ct->cvs ); pj_errno = -38; return 0; } if( IS_LSB ) swap_words( (unsigned char *) row_buf, 8, gi->ct->lim.lam*2 ); /* convert seconds to radians */ diff_seconds = row_buf; for( i = 0; i < gi->ct->lim.lam; i++ ) { cvs = gi->ct->cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0); cvs->lam = *(diff_seconds++) * ((PI/180.0) / 3600.0); } } pj_dalloc( row_buf ); fclose( fid ); return 1; } /* -------------------------------------------------------------------- */ /* NTv2 format. */ /* We process one line at a time. Note that the array storage */ /* direction (e-w) is different in the NTv2 file and what */ /* the CTABLE is supposed to have. The phi/lam are also */ /* reversed, and we have to be aware of byte swapping. */ /* -------------------------------------------------------------------- */ else if( strcmp(gi->format,"ntv2") == 0 ) { float *row_buf; int row; FILE *fid; if( getenv("PROJ_DEBUG") != NULL ) { fprintf( stderr, "NTv2 - loading grid %s\n", gi->ct->id ); } fid = pj_open_lib( gi->filename, "rb" ); if( fid == NULL ) { pj_errno = -38; return 0; } fseek( fid, gi->grid_offset, SEEK_SET ); row_buf = (float *) pj_malloc(gi->ct->lim.lam * sizeof(float) * 4); gi->ct->cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || gi->ct->cvs == NULL ) { pj_errno = -38; return 0; } for( row = 0; row < gi->ct->lim.phi; row++ ) { int i; FLP *cvs; float *diff_seconds; if( fread( row_buf, sizeof(float), gi->ct->lim.lam*4, fid ) != 4 * gi->ct->lim.lam ) { pj_dalloc( row_buf ); pj_dalloc( gi->ct->cvs ); gi->ct->cvs = NULL; pj_errno = -38; return 0; } if( !IS_LSB ) swap_words( (unsigned char *) row_buf, 4, gi->ct->lim.lam*4 ); /* convert seconds to radians */ diff_seconds = row_buf; for( i = 0; i < gi->ct->lim.lam; i++ ) { cvs = gi->ct->cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0); cvs->lam = *(diff_seconds++) * ((PI/180.0) / 3600.0); diff_seconds += 2; /* skip accuracy values */ } } pj_dalloc( row_buf ); fclose( fid ); return 1; } else { return 0; } }
static char *get_init_string (PJ_CONTEXT *ctx, char *name) { /*************************************************************************************** Read a section of an init file. Return its contents as a plain character string. It is the duty of the caller to free the memory allocated for the string. ***************************************************************************************/ #define MAX_LINE_LENGTH 1000 size_t current_buffer_size = 5 * (MAX_LINE_LENGTH + 1); char *fname, *section, *key; char *buffer = 0; char *line = 0; PAFile fid; size_t n; line = pj_malloc (MAX_LINE_LENGTH + 1); if (0==line) return 0; fname = pj_malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3); if (0==fname) { pj_dealloc (line); return 0; } /* Support "init=file:section", "+init=file:section", and "file:section" format */ key = strstr (name, "init="); if (0==key) key = name; else key += 5; if (MAX_PATH_FILENAME + ID_TAG_MAX + 2 < strlen (key)) { pj_dealloc (fname); pj_dealloc (line); return 0; } memmove (fname, key, strlen (key) + 1); /* Locate the name of the section we search for */ section = strrchr(fname, ':'); if (0==section) { proj_context_errno_set (ctx, PJD_ERR_NO_COLON_IN_INIT_STRING); pj_dealloc (fname); pj_dealloc (line); return 0; } *section = 0; section++; n = strlen (section); pj_log (ctx, PJ_LOG_TRACE, "get_init_string: searching for section [%s] in init file [%s]", section, fname); fid = pj_open_lib (ctx, fname, "rt"); if (0==fid) { pj_dealloc (fname); pj_dealloc (line); proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE); return 0; } /* Search for section in init file */ for (;;) { /* End of file? */ if (0==pj_ctx_fgets (ctx, line, MAX_LINE_LENGTH, fid)) { pj_dealloc (buffer); pj_dealloc (fname); pj_dealloc (line); pj_ctx_fclose (ctx, fid); proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE); return 0; } /* At start of right section? */ pj_chomp (line); if ('<'!=line[0]) continue; if (strlen (line) < n + 2) continue; if (line[n + 1] != '>') continue; if (0==strncmp (line + 1, section, n)) break; } /* We're at the first line of the right section - copy line to buffer */ buffer = pj_malloc (current_buffer_size); if (0==buffer) { pj_dealloc (fname); pj_dealloc (line); pj_ctx_fclose (ctx, fid); return 0; } /* Skip the "<section>" indicator, and copy the rest of the line over */ strcpy (buffer, line + strlen (section) + 2); /* Copy the remaining lines of the section to buffer */ for (;;) { char *end_i_cator; size_t next_length, buffer_length; /* Did the section end somewhere in the most recently read line? */ end_i_cator = strchr (buffer, '<'); if (end_i_cator) { *end_i_cator = 0; break; } /* End of file? - done! */ if (0==pj_ctx_fgets (ctx, line, MAX_LINE_LENGTH, fid)) break; /* Otherwise, handle the line. It MAY be the start of the next section, */ /* but that will be handled at the start of next trip through the loop */ buffer_length = strlen (buffer); pj_chomp (line); /* Remove '#' style comments */ next_length = strlen (line) + buffer_length + 2; if (next_length > current_buffer_size) { char *b = pj_malloc (2 * current_buffer_size); if (0==b) { pj_dealloc (buffer); buffer = 0; break; } strcpy (b, buffer); current_buffer_size *= 2; pj_dealloc (buffer); buffer = b; } buffer[buffer_length] = ' '; strcpy (buffer + buffer_length + 1, line); } pj_ctx_fclose (ctx, fid); pj_dealloc (fname); pj_dealloc (line); if (0==buffer) return 0; pj_shrink (buffer); pj_log (ctx, PJ_LOG_TRACE, "key=%s, value: [%s]", key, buffer); return buffer; }
PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) { char fname[MAX_PATH_FILENAME+1]; PJ_GRIDINFO *gilist; FILE *fp; char header[160]; errno = pj_errno = 0; ctx->last_errno = 0; /* -------------------------------------------------------------------- */ /* Initialize a GRIDINFO with stub info we would use if it */ /* cannot be loaded. */ /* -------------------------------------------------------------------- */ gilist = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); memset( gilist, 0, sizeof(PJ_GRIDINFO) ); gilist->gridname = strdup( gridname ); gilist->filename = NULL; gilist->format = "missing"; gilist->grid_offset = 0; gilist->ct = NULL; gilist->next = NULL; /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ strcpy(fname, gridname); if (!(fp = pj_open_lib(ctx, fname, "rb"))) { ctx->last_errno = 0; /* don't treat as a persistent error */ return gilist; } gilist->filename = strdup(fname); /* -------------------------------------------------------------------- */ /* Load a header, to determine the file type. */ /* -------------------------------------------------------------------- */ if( fread( header, sizeof(header), 1, fp ) != 1 ) { fclose( fp ); pj_ctx_set_errno( ctx, -38 ); return gilist; } fseek( fp, SEEK_SET, 0 ); /* -------------------------------------------------------------------- */ /* Determine file type. */ /* -------------------------------------------------------------------- */ if( strncmp(header + 0, "HEADER", 6) == 0 && strncmp(header + 96, "W GRID", 6) == 0 && strncmp(header + 144, "TO NAD83 ", 16) == 0 ) { pj_gridinfo_init_ntv1( ctx, fp, gilist ); } else if( strncmp(header + 0, "NUM_OREC", 8) == 0 && strncmp(header + 48, "GS_TYPE", 7) == 0 ) { pj_gridinfo_init_ntv2( ctx, fp, gilist ); } else if( strlen(gridname) > 4 && (strcmp(gridname+strlen(gridname)-3,"gtx") == 0 || strcmp(gridname+strlen(gridname)-3,"GTX") == 0) ) { 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 ); gilist->format = "ctable"; gilist->ct = ct; pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "Ctable %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 ); } fclose(fp); return gilist; }
static CPLString GetProj4Filename(const char* pszFilename) { CPLString osFilename; /* or fixed path: /name, ./name or ../name */ if ( !CPLIsFilenameRelative(pszFilename) || *pszFilename == '.' ) { return pszFilename; } #if defined(PROJ_STATIC) && PROJ_VERSION >= 5 PJ_GRID_INFO info = proj_grid_info(pszFilename); if( info.filename[0] ) { osFilename = info.filename; } #elif defined(PROJ_STATIC) && PJ_VERSION > 493 osFilename.resize(2048); projCtx ctx = pj_ctx_alloc(); if( pj_find_file(ctx, pszFilename, &osFilename[0], osFilename.size()) ) { osFilename.resize( strlen(osFilename) ); } else { osFilename.clear(); } pj_ctx_free(ctx); #else // Transpose some of the proj.4 pj_open_lib() logic... /* check if ~/name */ char* pszSysname; if (*pszFilename == '~' && (pszFilename[1] == '/' || pszFilename[1] == '\\') ) { if ((pszSysname = getenv("HOME")) != nullptr) { osFilename = CPLFormFilename(pszSysname, pszFilename + 1, nullptr); } return osFilename; } /* or is environment PROJ_LIB defined */ else if ((pszSysname = getenv("PROJ_LIB")) != nullptr) { osFilename = CPLFormFilename(pszSysname, pszFilename, nullptr); VSIStatBufL sStat; if( VSIStatL(osFilename, &sStat) == 0 ) return osFilename; osFilename.clear(); } #if defined(PROJ_STATIC) && PJ_VERSION >= 490 // Super messy. proj.4 up to 4.9.3 had no public API to return the full // path to a resource file, so we rely on the fact that it emits a log // message with it... // Basically this is needed in the case where the file is in the // resource installation directory of proj.4, which we have no way to // know otherwise. CPLString osMsg; projCtx ctx = pj_ctx_alloc(); pj_ctx_set_app_data(ctx, &osMsg); pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR); pj_ctx_set_logger(ctx, my_proj4_logger); PAFile f = pj_open_lib(ctx, pszFilename, "rb"); if( f ) { pj_ctx_fclose(ctx, f); size_t nPos = osMsg.find("fopen("); if( nPos != std::string::npos ) { osFilename = osMsg.substr(nPos + strlen("fopen(")); nPos = osFilename.find(")"); if( nPos != std::string::npos ) osFilename = osFilename.substr(0, nPos); } } pj_ctx_free(ctx); #endif #endif return osFilename; }