From 9181fcfebde8a3969dc49100674f16286119059b Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 16 Jan 2018 13:16:18 +0100 Subject: Fix "double inversions" in pipelines, require a defined forward operation. "+proj=pipeline +inv +step +urm5 +n=0.5 +inv" now works as expected, returning the forward operation of urm5. In principle adding more +inv's should also work, resulting in the forward operation when an even number of +inv's are present, and the inverse when an odd number of +inv's are present. "+proj=pipeline +step +urm5 +n=0.5 +inv" fails at initialization since no forward operation can be performed. This is a new requirement, but aligns perfectly with the rest of the library since no operation without a forward method exists. --- src/PJ_pipeline.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 3dcc85d9..befc8557 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -320,7 +320,6 @@ PJ *OPERATION(pipeline,0) { int i, nsteps = 0, argc; int i_pipeline = -1, i_first_step = -1, i_current_step; char **argv, **current_argv; - PJ *Q; P->fwd4d = pipeline_forward_4d; P->inv4d = pipeline_reverse_4d; @@ -431,7 +430,8 @@ PJ *OPERATION(pipeline,0) { /* Is this step inverted? */ for (j = 0; j < current_argc; j++) if (0==strcmp("inv", current_argv[j])) { - next_step->inverted = 1; + /* if +inv exists in both global and local args the forward operation should be used */ + next_step->inverted = next_step->inverted == 0 ? 1 : 0; } P->opaque->pipeline[i+1] = next_step; @@ -439,9 +439,21 @@ PJ *OPERATION(pipeline,0) { proj_log_trace (P, "Pipeline at [%p]: step at [%p] done", P, next_step); } + /* Require a forward path through the pipeline */ + for (i = 1; i <= nsteps; i++) { + PJ *Q = P->opaque->pipeline[i]; + if ( ( Q->inverted && (Q->inv || Q->inv3d || Q->fwd4d) ) || + (!Q->inverted && (Q->fwd || Q->fwd3d || Q->fwd4d) ) ) { + continue; + } else { + proj_log_error (P, "Pipeline: A forward operation couldn't be constructed"); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); + } + } + /* determine if an inverse operation is possible */ for (i = 1; i <= nsteps; i++) { - Q = P->opaque->pipeline[i]; + PJ *Q = P->opaque->pipeline[i]; if ( ( Q->inverted && (Q->fwd || Q->fwd3d || Q->fwd4d) ) || ( Q->inv || Q->inv3d || Q->inv4d) ) { continue; -- cgit v1.2.3