diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/images/imgeom/src/t_magnify.x | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/images/imgeom/src/t_magnify.x')
-rw-r--r-- | pkg/images/imgeom/src/t_magnify.x | 624 |
1 files changed, 624 insertions, 0 deletions
diff --git a/pkg/images/imgeom/src/t_magnify.x b/pkg/images/imgeom/src/t_magnify.x new file mode 100644 index 00000000..ed797500 --- /dev/null +++ b/pkg/images/imgeom/src/t_magnify.x @@ -0,0 +1,624 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <imhdr.h> +include <imset.h> +include <math/iminterp.h> + +# T_MAGNIFY -- Change coordinate origin and pixel interval in 2D images. +# +# The input and output images are given by image template lists. The +# number of output images must match the number of input images. Image +# sections are allowed in the input images and ignored in the output +# images. If the input and output image names are the same then the +# magnification is performed to a temporary file which then replaces +# the input image. + +# Interpolation types and boundary extension types. + +define BTYPES "|constant|nearest|reflect|wrap|project|" +define SZ_BTYPE 8 + +procedure t_magnify () + +pointer input # Pointer to input image list +pointer output # Pointer to output image list +pointer interp # Pointer to image interpolation type +pointer boundary # Pointer to boundary extension type +real bconst # Boundary extension pixel value +real xmag, ymag # Image magnifications +real dx, dy # Step size +real x1, y1 # Starting coordinates +real x2, y2 # Ending coordinates +int flux # Flux conserve + +int list1, list2, btype, logfd +pointer sp, in, out, image1, image2, image3, mw, errmsg +real a, b, c, d, shifts[2], scale[2] + +bool clgetb(), envgetb(), fp_equalr() +int clgwrd(), imtopen(), imtgetim(), imtlen(), open(), btoi(), errget() +pointer mw_openim(), immap() +real clgetr() +errchk open(), mg_magnify1(), mg_magnify2() + +begin + call smark (sp) + call salloc (input, SZ_LINE, TY_CHAR) + call salloc (output, SZ_LINE, TY_CHAR) + call salloc (interp, SZ_FNAME, TY_CHAR) + call salloc (boundary, SZ_BTYPE, TY_CHAR) + call salloc (image1, SZ_FNAME, TY_CHAR) + call salloc (image2, SZ_FNAME, TY_CHAR) + call salloc (image3, SZ_FNAME, TY_CHAR) + call salloc (errmsg, SZ_FNAME, TY_CHAR) + + # Get task parameters. + call clgstr ("input", Memc[input], SZ_LINE) + call clgstr ("output", Memc[output], SZ_LINE) + call clgstr ("interpolation", Memc[interp], SZ_FNAME) + btype = clgwrd ("boundary", Memc[boundary], SZ_BTYPE, BTYPES) + bconst = clgetr ("constant") + a = clgetr ("x1") + b = clgetr ("x2") + dx = clgetr ("dx") + c = clgetr ("y1") + d = clgetr ("y2") + dy = clgetr ("dy") + flux = btoi (clgetb ("fluxconserve")) + + # If the pixel interval INDEF then use the a magnification factor + # to determine the pixel interval. + + if (IS_INDEF (dx)) { + xmag = clgetr ("xmag") + if (xmag < 0.0) + dx = -xmag + else if (xmag > 0.0) + dx = 1.0 / xmag + else + dx = 0.0 + } + + if (IS_INDEF (dy)) { + ymag = clgetr ("ymag") + if (ymag < 0.0) + dy = -ymag + else if (ymag > 0.0) + dy = 1.0 / ymag + else + dy = 0.0 + } + + if (fp_equalr (dx, 0.0) || fp_equalr (dy, 0.0)) { + call error (0, "Illegal magnification") + } else { + xmag = 1.0 / dx + ymag = 1.0 / dy + } + + + # Open the log file. + call clgstr ("logfile", Memc[image1], SZ_FNAME) + iferr (logfd = open (Memc[image1], APPEND, TEXT_FILE)) + logfd = NULL + + # Expand the input and output image lists. + list1 = imtopen (Memc[input]) + list2 = imtopen (Memc[output]) + if (imtlen (list1) != imtlen (list2)) { + call imtclose (list1) + call imtclose (list2) + call error (0, "Number of input and output images not the same") + } + + # Magnify each set of input/output images with the 2D interpolation + # package. + + while ((imtgetim (list1, Memc[image1], SZ_FNAME) != EOF) && + (imtgetim (list2, Memc[image2], SZ_FNAME) != EOF)) { + + # Map the input and output images. + call xt_mkimtemp (Memc[image1], Memc[image2], Memc[image3], + SZ_FNAME) + in = immap (Memc[image1], READ_ONLY, 0) + out = immap (Memc[image2], NEW_COPY, in) + + # Set the limits of the output image. + x1 = a + x2 = b + y1 = c + y2 = d + + # Magnify the image making sure to update the wcs. + iferr { + if (IM_NDIM(in) == 1) { + call mg_magnify1 (in, out, Memc[interp], btype, bconst, + x1, x2, dx, flux) + if (!envgetb ("nomwcs")) { + mw = mw_openim (in) + scale[1] = xmag + shifts[1] = 1. - xmag * x1 + call mw_scale (mw, scale, 01B) + call mw_shift (mw, shifts, 01B) + call mw_saveim (mw, out) + call mw_close (mw) + } + } else if (IM_NDIM(in) == 2) { + call mg_magnify2 (in, out, Memc[interp], btype, bconst, + x1, x2, dx, y1, y2, dy, flux) + if (!envgetb ("nomwcs")) { + mw = mw_openim (in) + scale[1] = xmag + scale[2] = ymag + shifts[1] = 1. - xmag * x1 + shifts[2] = 1. - ymag * y1 + call mw_scale (mw, scale, 03B) + call mw_shift (mw, shifts, 03B) + call mw_saveim (mw, out) + call mw_close (mw) + } + } else { + call imunmap (out) + call imunmap (in) + call xt_delimtemp (Memc[image2], Memc[image3]) + if (logfd != NULL) { + call fprintf (logfd, "\n%s\n") + call pargstr (Memc[image3]) + call fprintf (logfd, + " Cannot magnify image %s to image %s.\n") + call pargstr (Memc[image1]) + call pargstr (Memc[image3]) + call fprintf (logfd, + " Dimensions are greater than 2.\n") + } + call imdelete (Memc[image3]) + next + } + + } then { + if (logfd != NULL) { + call fprintf (logfd, "\n%s\n") + call pargstr (Memc[image3]) + call fprintf (logfd, + " Cannot magnify image %s to image %s.\n") + call pargstr (Memc[image1]) + call pargstr (Memc[image3]) + if (errget (Memc[errmsg], SZ_FNAME) <= 0) + ; + call fprintf (logfd, "%s") + call pargstr (Memc[errmsg]) + } + call imdelete (Memc[image3]) + call imunmap (out) + call imunmap (in) + call xt_delimtemp (Memc[image2], Memc[image3]) + } else { + + if (logfd != NULL) { + call fprintf (logfd, "\n%s\n") + call pargstr (Memc[image3]) + call fprintf (logfd, " Magnify image %s to image %s.\n") + call pargstr (Memc[image1]) + call pargstr (Memc[image3]) + call fprintf (logfd, " Interpolation is %s.\n") + call pargstr (Memc[interp]) + call fprintf (logfd, " Boundary extension is %s.\n") + call pargstr (Memc[boundary]) + if (btype == 1) { + call fprintf (logfd, + " Boundary pixel constant is %g.\n") + call pargr (bconst) + } + call fprintf (logfd, + " Output coordinates in terms of input coordinates:\n") + call fprintf (logfd, + " x1 = %10.4g, x2 = %10.4g, dx = %10.6g\n") + call pargr (x1) + call pargr (x2) + call pargr (dx) + if (IM_NDIM(in) == 2) { + call fprintf (logfd, + " y1 = %10.4g, y2 = %10.4g, dy = %10.6g\n") + call pargr (y1) + call pargr (y2) + call pargr (dy) + } + } + + call imunmap (out) + call imunmap (in) + call xt_delimtemp (Memc[image2], Memc[image3]) + } + + } + + call imtclose (list1) + call imtclose (list2) + call close (logfd) + call sfree (sp) +end + + +define NYOUT2 16 # Number of input lines to use for interpolation +define NMARGIN 3 # Number of edge lines to add for interpolation +define NMARGIN_SPLINE3 16 # Number of edge lines to add for interpolation + + +# MG_MAGNIFY1 -- Magnify the input input image to create the output image. + +procedure mg_magnify1 (in, out, interp, btype, bconst, x1, x2, dx, flux) + +pointer in # pointer to the input image +pointer out # pointer to the output image +char interp[ARB] # Interpolation type +int btype # Boundary extension type +real bconst # Boundary extension constant +real x1, x2 # Starting and ending points of output image +real dx # Pixel interval +int flux # Conserve flux? + +int i, nxin, nxout, nxymargin, itype, nsinc, nincr, col1, col2 +pointer sp, x, z, buf, asi +real xshift +pointer imgs1r(), impl1r() +int asigeti() + +begin + # Set the default values for the output image limits if they are INDEF + # and calculate the number of output pixels. + + if (IS_INDEF (x1)) + x1 = 1. + if (IS_INDEF (x2)) + x2 = IM_LEN (in, 1) + if (x1 > x2) + call error (0, " X1 cannot be greater than X2\n") + + # Set the number of output pixels in the image header. + + nxout = (x2 - x1) / dx + 1 + IM_LEN(out, 1) = nxout + + # Initialize the interpolator. + + call asitype (interp, itype, nsinc, nincr, xshift) + call asisinit (asi, itype, nsinc, nincr, xshift, 0.0) + + # Round the coordinate limits to include the output image coordinate + # limits and the set boundary. + + col1 = x1 + col2 = nint (x2) + if (itype == II_SPLINE3) + nxymargin = NMARGIN_SPLINE3 + else if (itype == II_SINC || itype == II_LSINC) + nxymargin = asigeti (asi, II_ASINSINC) + else if (itype == II_DRIZZLE) + nxymargin = max (nint (dx), NMARGIN) + else + nxymargin = NMARGIN + call mg_setboundary1 (in, col1, col2, btype, bconst, nxymargin) + col1 = col1 - nxymargin + if (col1 <= 0) + col1 = col1 - 1 + col2 = col2 + nxymargin + 1 + + # Allocate memory for the interpolation coordinates. + # Also initialize the image data buffer. + + call smark (sp) + call salloc (x, 2 * nxout, TY_REAL) + + # Set the x interpolation coordinates. The coordinates are relative + # to the boundary extended input image. + + if (itype == II_DRIZZLE) { + do i = 1, nxout { + Memr[x+2*i-2] = x1 + (i - 1.5) * dx - col1 + 1 + Memr[x+2*i-1] = x1 + (i - 0.5) * dx - col1 + 1 + } + } else { + do i = 1, nxout + Memr[x+i-1] = x1 + (i - 1) * dx - col1 + 1 + } + + # Fit the output image. + nxin = col2 - col1 + 1 + buf = imgs1r (in, col1, col2) + call asifit (asi, Memr[buf], nxin) + + # Evaluate the output image pixel values. + z = impl1r (out) + call asivector (asi, Memr[x], Memr[z], nxout) + #if (itype != II_DRIZZLE && flux == YES) + if (flux == YES) + call amulkr (Memr[z], dx, Memr[z], nxout) + + # Free memory and unmap the images. + call asifree (asi) + call sfree (sp) +end + + +# MG_MAGNIFY2 -- Magnify the input input image to create the output image. + +procedure mg_magnify2 (in, out, interp, btype, bconst, x1, x2, dx, y1, y2, + dy, flux) + +pointer in # pointer to the input image +pointer out # pointer to the output image +char interp[ARB] # Interpolation type +int btype # Boundary extension type +real bconst # Boundary extension constant +real x1, y1 # Starting point of output image +real x2, y2 # Ending point of output image +real dx, dy # Pixel interval +int flux # Conserve flux? + +int i, nxin, nxout, nyout, nxymargin, itype, nsinc, nincr +int l1out, l2out, nlout, l1in, l2in, nlin, fstline, lstline +int col1, col2, line1, line2 +real shift +pointer msi +pointer sp, x, y, z, buf + +pointer imps2r() +int msigeti() + +begin + # Set the default values for the output image limits if they are INDEF + # and calculate the number of output pixels. + + if (IS_INDEF (x1)) + x1 = 1. + if (IS_INDEF (x2)) + x2 = IM_LEN (in, 1) + if (IS_INDEF (y1)) + y1 = 1. + if (IS_INDEF (y2)) + y2 = IM_LEN (in, 2) + if (x1 > x2) + call error (0, " X1 cannot be greater than X2\n") + if (y1 > y2) + call error (0, " Y1 cannot be greater than Y2\n") + nxout = (x2 - x1) / dx + 1 + nyout = (y2 - y1) / dy + 1 + + # Set the number of output pixels in the image header. + + IM_LEN(out, 1) = nxout + IM_LEN(out, 2) = nyout + + # Initialize the interpolator. + + call msitype (interp, itype, nsinc, nincr, shift) + call msisinit (msi, itype, nsinc, nincr, nincr, shift, shift, 0.0) + + # Compute the number of margin pixels required + + if (itype == II_BISPLINE3) + nxymargin = NMARGIN_SPLINE3 + else if (itype == II_BISINC || itype == II_BILSINC) + nxymargin = msigeti (msi, II_MSINSINC) + else if (itype == II_BIDRIZZLE) + nxymargin = max (nint (dx), nint(dy), NMARGIN) + else + nxymargin = NMARGIN + + # Round the coordinate limits to include the output image coordinate + # limits and the set boundary. + + col1 = x1 + col2 = nint (x2) + line1 = y1 + line2 = nint (y2) + call mg_setboundary2 (in, col1, col2, line1, line2, btype, bconst, + nxymargin) + + # Compute the input image column limits. + col1 = col1 - nxymargin + if (col1 <= 0) + col1 = col1 - 1 + col2 = col2 + nxymargin + 1 + nxin = col2 - col1 + 1 + + # Allocate memory for the interpolation coordinates. + # Also initialize the image data buffer. + + call smark (sp) + call salloc (x, 2 * nxout, TY_REAL) + call salloc (y, 2 * NYOUT2, TY_REAL) + buf = NULL + fstline = 0 + lstline = 0 + + # Set the x interpolation coordinates which do not change from + # line to line. The coordinates are relative to the boundary + # extended input image. + + if (itype == II_BIDRIZZLE) { + do i = 1, nxout { + Memr[x+2*i-2] = x1 + (i - 1.5) * dx - col1 + 1 + Memr[x+2*i-1] = x1 + (i - 0.5) * dx - col1 + 1 + } + } else { + do i = 1, nxout + Memr[x+i-1] = x1 + (i - 1) * dx - col1 + 1 + } + + # Loop over the image sections. + for (l1out = 1; l1out <= nyout; l1out = l1out + NYOUT2) { + + # Define the range of output lines. + l2out = min (l1out + NYOUT2 - 1, nyout) + nlout = l2out - l1out + 1 + + # Define the corresponding range of input lines. + l1in = y1 + (l1out - 1) * dy - nxymargin + if (l1in <= 0) + l1in = l1in - 1 + l2in = y1 + (l2out - 1) * dy + nxymargin + 1 + nlin = l2in - l1in + 1 + + # Get the apporiate image section and compute the coefficients. + if ((buf == NULL) || (l1in < fstline) || (l2in > lstline)) { + fstline = l1in + lstline = l2in + call mg_bufl2r (in, col1, col2, l1in, l2in, buf) + call msifit (msi, Memr[buf], nxin, nlin, nxin) + } + + # Output the section. + z = imps2r (out, 1, nxout, l1out, l2out) + + # Compute the y values. + if (itype == II_BIDRIZZLE) { + do i = l1out, l2out { + Memr[y+2*(i-l1out)] = y1 + (i - 1.5) * dy - fstline + 1 + Memr[y+2*(i-l1out)+1] = y1 + (i - 0.5) * dy - fstline + 1 + } + } else { + do i = l1out, l2out + Memr[y+i-l1out] = y1 + (i - 1) * dy - fstline + 1 + } + + # Evaluate the interpolant. + call msigrid (msi, Memr[x], Memr[y], Memr[z], nxout, nlout, nxout) + if (flux == YES) + call amulkr (Memr[z], dx * dy, Memr[z], nxout * nlout) + } + + # Free memory and buffers. + call msifree (msi) + call mfree (buf, TY_REAL) + call sfree (sp) +end + + +# MG_BUFL2R -- Maintain buffer of image lines. A new buffer is created when +# the buffer pointer is null or if the number of lines requested is changed. +# The minimum number of image reads is used. + +procedure mg_bufl2r (im, col1, col2, line1, line2, buf) + +pointer im # Image pointer +int col1 # First image column of buffer +int col2 # Last image column of buffer +int line1 # First image line of buffer +int line2 # Last image line of buffer +pointer buf # Buffer + +int i, ncols, nlines, nclast, llast1, llast2, nllast +pointer buf1, buf2 + +pointer imgs2r() + +begin + ncols = col2 - col1 + 1 + nlines = line2 - line1 + 1 + + # If the buffer pointer is undefined then allocate memory for the + # buffer. If the number of columns or lines requested changes + # reallocate the buffer. Initialize the last line values to force + # a full buffer image read. + + if (buf == NULL) { + call malloc (buf, ncols * nlines, TY_REAL) + llast1 = line1 - nlines + llast2 = line2 - nlines + } else if ((nlines != nllast) || (ncols != nclast)) { + call realloc (buf, ncols * nlines, TY_REAL) + llast1 = line1 - nlines + llast2 = line2 - nlines + } + + # Read only the image lines with are different from the last buffer. + + if (line1 < llast1) { + do i = line2, line1, -1 { + if (i > llast1) + buf1 = buf + (i - llast1) * ncols + else + buf1 = imgs2r (im, col1, col2, i, i) + + buf2 = buf + (i - line1) * ncols + call amovr (Memr[buf1], Memr[buf2], ncols) + } + } else if (line2 > llast2) { + do i = line1, line2 { + if (i < llast2) + buf1 = buf + (i - llast1) * ncols + else + buf1 = imgs2r (im, col1, col2, i, i) + + buf2 = buf + (i - line1) * ncols + call amovr (Memr[buf1], Memr[buf2], ncols) + } + } + + # Save the buffer parameters. + + llast1 = line1 + llast2 = line2 + nclast = ncols + nllast = nlines +end + + +# MG_SETBOUNDARY1 -- Set boundary extension for a 1D image. + +procedure mg_setboundary1 (im, col1, col2, btype, bconst, nxymargin) + +pointer im # IMIO pointer +int col1, col2 # Range of columns +int btype # Boundary extension type +real bconst # Constant for constant boundary extension +int nxymargin # Number of margin pixels + +int btypes[5] +int nbndrypix + +data btypes /BT_CONSTANT, BT_NEAREST, BT_REFLECT, BT_WRAP, BT_PROJECT/ + +begin + nbndrypix = 0 + nbndrypix = max (nbndrypix, 1 - col1) + nbndrypix = max (nbndrypix, col2 - IM_LEN(im, 1)) + + call imseti (im, IM_TYBNDRY, btypes[btype]) + call imseti (im, IM_NBNDRYPIX, nbndrypix + nxymargin + 1) + if (btypes[btype] == BT_CONSTANT) + call imsetr (im, IM_BNDRYPIXVAL, bconst) +end + + +# MG_SETBOUNDARY2 -- Set boundary extension for a 2D image. + +procedure mg_setboundary2 (im, col1, col2, line1, line2, btype, bconst, + nxymargin) + +pointer im # IMIO pointer +int col1, col2 # Range of columns +int line1, line2 # Range of lines +int btype # Boundary extension type +real bconst # Constant for constant boundary extension +int nxymargin # Number of margin pixels to allow + +int btypes[5] +int nbndrypix + +data btypes /BT_CONSTANT, BT_NEAREST, BT_REFLECT, BT_WRAP, BT_PROJECT/ + +begin + nbndrypix = 0 + nbndrypix = max (nbndrypix, 1 - col1) + nbndrypix = max (nbndrypix, col2 - IM_LEN(im, 1)) + nbndrypix = max (nbndrypix, 1 - line1) + nbndrypix = max (nbndrypix, line2 - IM_LEN(im, 2)) + + call imseti (im, IM_TYBNDRY, btypes[btype]) + call imseti (im, IM_NBNDRYPIX, nbndrypix + nxymargin + 1) + if (btypes[btype] == BT_CONSTANT) + call imsetr (im, IM_BNDRYPIXVAL, bconst) +end |