include include include include define GEO_LINEAR 1 # Linear transformation only define GEO_DISTORTION 2 # Distortion correction only define GEO_GEOMETRIC 3 # Full transformation $for (rd) # GEO_LINIT -- Initialize the linear part of the transformation. $if (datatype == r) procedure geo_linitr (sx1, sy1, sx2, sy2) $else procedure geo_linitd (sx1, sy1, sx2, sy2) $endif pointer sx1, sy1 #I/O pointers to the linear x and y surfaces pointer sx2, sy2 #I/O pointer to the distortion x and y surfaces PIXEL xmag, ymag, xrot, yrot, xref, yref, xout, yout, xshift, yshift $if (datatype == r) real clgetr(), gseval() $else double clgetd(), dgseval() $endif begin # Initialize the surfaces. $if (datatype == r) call gsinit (sx1, GS_POLYNOMIAL, 2, 2, GS_XNONE, -MAX_REAL, MAX_REAL, -MAX_REAL, MAX_REAL) call gsinit (sy1, GS_POLYNOMIAL, 2, 2, GS_XNONE, -MAX_REAL, MAX_REAL, -MAX_REAL, MAX_REAL) $else call dgsinit (sx1, GS_POLYNOMIAL, 2, 2, GS_XNONE, double (-MAX_REAL), double (MAX_REAL), double (-MAX_REAL), double (MAX_REAL)) call dgsinit (sy1, GS_POLYNOMIAL, 2, 2, GS_XNONE, double (-MAX_REAL), double (MAX_REAL), double (-MAX_REAL), double (MAX_REAL)) $endif sx2 = NULL sy2 = NULL # Get the magnification parameters. xmag = clget$t ("xmag") if (IS_$INDEF$T(xmag)) xmag = PIXEL(1.0) ymag = clget$t ("ymag") if (IS_$INDEF$T(ymag)) ymag = PIXEL(1.0) # Get the rotation parameters. xrot = clget$t ("xrot") if (IS_$INDEF$T(xrot)) xrot = PIXEL(0.0) xrot = -DEGTORAD(xrot) yrot = clget$t ("yrot") if (IS_$INDEF$T(yrot)) yrot = PIXEL(0.0) yrot = -DEGTORAD(yrot) # Set the magnification and rotation coefficients. call geo_rotmag$t (sx1, sy1, xmag, ymag, xrot, yrot) # Compute the origin of the reference coordinates. xref = clget$t ("xref") if (IS_$INDEF$T(xref)) xref = PIXEL(0.0) yref = clget$t ("yref") if (IS_$INDEF$T(yref)) yref = PIXEL(0.0) # Compute the corresponding input coordinates. xout = clget$t ("xout") if (IS_$INDEF$T(xout)) $if (datatype == r) xout = gseval (sx1, xref, yref) $else xout = dgseval (sx1, xref, yref) $endif yout = clget$t ("yout") if (IS_$INDEF$T(yout)) $if (datatype == r) yout = gseval (sy1, xref, yref) $else yout = dgseval (sy1, xref, yref) $endif # Set the shifts. xshift = clget$t ("xshift") yshift = clget$t ("yshift") $if (datatype == r) if (IS_$INDEF$T(xshift)) xshift = xout - gseval (sx1, xref, yref) if (IS_$INDEF$T(yshift)) yshift = yout - gseval (sy1, xref, yref) $else if (IS_$INDEF$T(xshift)) xshift = xout - $tgseval (sx1, xref, yref) if (IS_$INDEF$T(yshift)) yshift = yout - $tgseval (sy1, xref, yref) $endif call geo_xyshift$t (sx1, sy1, xshift, yshift) end # GEO_SFREE -- Free the x and y surface fitting descriptors. $if (datatype == r) procedure geo_sfreer (sx1, sy1, sx2, sy2) $else procedure geo_sfreed (sx1, sy1, sx2, sy2) $endif pointer sx1, sy1 #I/O pointers to the linear x and y surfaces pointer sx2, sy2 #I/O pointer to the distortion x and y surfaces begin $if (datatype == r) call gsfree (sx1) call gsfree (sy1) if (sx2 != NULL) call gsfree (sx2) if (sy2 != NULL) call gsfree (sy2) $else call dgsfree (sx1) call dgsfree (sy1) if (sx2 != NULL) call dgsfree (sx2) if (sy2 != NULL) call dgsfree (sy2) $endif end # GEO_SINIT -- Read the surface fits from the database file and make # any requested changes. procedure geo_sinit$t (dt, record, geometry, sx1, sy1, sx2, sy2) pointer dt #I pointer to database file produced by geomap char record[ARB] #I the name of the database record int geometry #I the type of geometry to be computed pointer sx1, sy1 #O pointers to the linear x and y surfaces pointer sx2, sy2 #O pointers to the x and y distortion surfaces int i, rec, ncoeff, junk PIXEL xmag, ymag, xrot, yrot, xref, yref, xout, yout, xshift, yshift pointer newsx1, newsy1, xcoeff, ycoeff int dtlocate(), dtscan(), dtgeti() PIXEL clget$t() $if (datatype == r) errchk gsrestore $else errchk dgsrestore $endif begin # Locate record. rec = dtlocate (dt, record) # Get linear part of fit. ncoeff = dtgeti (dt, rec, "surface1") call malloc (xcoeff, ncoeff, TY_PIXEL) call malloc (ycoeff, ncoeff, TY_PIXEL) do i = 1, ncoeff { junk = dtscan (dt) call garg$t (Mem$t[xcoeff+i-1]) call garg$t (Mem$t[ycoeff+i-1]) } # Restore linear part of fit. $if (datatype == r) call gsrestore (sx1, Mem$t[xcoeff]) call gsrestore (sy1, Mem$t[ycoeff]) $else call dgsrestore (sx1, Mem$t[xcoeff]) call dgsrestore (sy1, Mem$t[ycoeff]) $endif # Get geometric transformation. xmag = clget$t ("xmag") ymag = clget$t ("ymag") xrot = clget$t ("xrotation") yrot = clget$t ("yrotation") xout = clget$t ("xout") yout = clget$t ("yout") xref = clget$t ("xref") yref = clget$t ("yref") xshift = clget$t ("xshift") yshift = clget$t ("yshift") # Get set to adjust linear part of the fit. $if (datatype == r) call gscopy (sx1, newsx1) call gscopy (sy1, newsy1) $else call dgscopy (sx1, newsx1) call dgscopy (sy1, newsy1) $endif if (geometry == GEO_DISTORTION) call geo_rotmag$t (newsx1, newsy1, PIXEL(1.0), PIXEL(1.0), PIXEL(0.0), PIXEL(0.0)) else if (! IS_$INDEF$T(xmag) || ! IS_$INDEF$T(ymag) || ! IS_$INDEF$T(xrot) || ! IS_$INDEF$T(yrot)) call geo_drotmag$t (dt, rec, newsx1, newsy1, xmag, ymag, xrot, yrot) call geo_dxyshift$t (dt, rec, newsx1, newsy1, xout, yout, xref, yref, xshift, yshift) $if (datatype == r) call gssave (newsx1, Mem$t[xcoeff]) call gssave (newsy1, Mem$t[ycoeff]) $else call dgssave (newsx1, Mem$t[xcoeff]) call dgssave (newsy1, Mem$t[ycoeff]) $endif # Get distortion part of fit. ncoeff = dtgeti (dt, rec, "surface2") if (ncoeff > 0 && (geometry == GEO_GEOMETRIC || geometry == GEO_DISTORTION)) { call realloc (xcoeff, ncoeff, TY_PIXEL) call realloc (ycoeff, ncoeff, TY_PIXEL) do i = 1, ncoeff { junk = dtscan (dt) call garg$t (Mem$t[xcoeff+i-1]) call garg$t (Mem$t[ycoeff+i-1]) } # Restore distortion part of fit. $if (datatype == r) iferr { call gsrestore (sx2, Mem$t[xcoeff]) } then { call mfree (sx2, TY_STRUCT) sx2 = NULL } iferr { call gsrestore (sy2, Mem$t[ycoeff]) } then { call mfree (sy2, TY_STRUCT) sy2 = NULL } $else iferr { call dgsrestore (sx2, Mem$t[xcoeff]) } then { call mfree (sx2, TY_STRUCT) sx2 = NULL } iferr { call dgsrestore (sy2, Mem$t[ycoeff]) } then { call mfree (sy2, TY_STRUCT) sy2 = NULL } $endif } else { sx2 = NULL sy2 = NULL } # Redefine the linear surfaces. $if (datatype == r) call gsfree (sx1) call gscopy (newsx1, sx1) call gsfree (newsx1) call gsfree (sy1) call gscopy (newsy1, sy1) call gsfree (newsy1) $else call dgsfree (sx1) call dgscopy (newsx1, sx1) call dgsfree (newsx1) call dgsfree (sy1) call dgscopy (newsy1, sy1) call dgsfree (newsy1) $endif # Cleanup. call mfree (xcoeff, TY_PIXEL) call mfree (ycoeff, TY_PIXEL) end # GEO_DO_TRANSFORM -- The linear transformation is performed in this procedure. # First the coordinates are scaled, then rotated and translated. The # transformed coordinates are returned. procedure geo_do_transform$t (x, y, xt, yt, sx1, sy1, sx2, sy2) PIXEL x, y # initial positions PIXEL xt, yt # transformed positions pointer sx1, sy1 # pointer to linear surfaces pointer sx2, sy2 # pointer to distortion surfaces $if (datatype == r) real gseval() $else double dgseval() $endif begin $if (datatype == r) xt = gseval (sx1, x, y) if (sx2 != NULL) xt = xt + gseval (sx2, x, y) yt = gseval (sy1, x, y) if (sy2 != NULL) yt = yt + gseval (sy2, x, y) $else xt = dgseval (sx1, x, y) if (sx2 != NULL) xt = xt + dgseval (sx2, x, y) yt = dgseval (sy1, x, y) if (sy2 != NULL) yt = yt + dgseval (sy2, x, y) $endif end $endfor