From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- pkg/proto/masks/mptools.x | 468 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 pkg/proto/masks/mptools.x (limited to 'pkg/proto/masks/mptools.x') diff --git a/pkg/proto/masks/mptools.x b/pkg/proto/masks/mptools.x new file mode 100644 index 00000000..7e08cab1 --- /dev/null +++ b/pkg/proto/masks/mptools.x @@ -0,0 +1,468 @@ +include +include +include +include + +# MP_OPEN -- Open the specified mask for image i/o +# +# Open the specified pixel mask. The input pixel mask specification may be +# +# "" The mask is undefined +# +# "EMPTY" The mask is undefined +# +# "!KEYWORD" The mask is the pixel mask pointed to by the reference +# image header keyword KEYWORD +# "!^KEYWORD" The mask is inverse of the pixel mask pointed to by the +# reference image header keyword KEYWORD +# "MASK" The mask is a pixel mask or image +# +# "^MASK" The mask is inverse of the pixel mask or image +# +# "EXPR" The mask is specified by an integer expression +# +# "@FILE" The mask is specified by the an integer expression in +# the text file FILE +# +# The input mask specification is transformed into a simple 0 and 1 mask +# internally where 0 is the pass value and 1 is the stop value. The format +# of EXPR is still a TBD but I would eventually like to support +# an algebra that includes simple image expressions as in the IMEXPR task, +# and regions descriptors similar to those defined in the PROS XRAY package. +# The latter have the problem in that they must be limited to 1D images (point, +# line egments) or 2D images (box, rectangle, ellipse, # annulus, wedge, etc). +# It maybe possible to expand this to 3D in some cases, e.g. cubes, spheres, +# ellipsoids etc although dealing with the angles may become complicated. At +# any rate I will put aside the issue of on the fly mask generation for the +# moment. If a section is specified on the input image but not on the mask +# image then imio/mio will automatically track the proper section in the mask. +# If a section is specified on the mask that section of the mask will be used, +# and it must correspond in size to the input image or image section. + +pointer procedure mp_open (pmsource, refim, pmname, sz_pmname) + +char pmsource[ARB] #I the pixel mask specificiation +pointer refim #I the reference image pointer +char pmname[ARB] #O the pixel mask name +int sz_pmname #I the maximum pixel name length + +pointer sp, fname, kfname +pointer pmim, pm +int ip, flags, invflag +pointer im_pmmap(), mp_pmmap() +int imaccess(), imstati() +bool streq() +errchk im_pmmap(), mp_pmmap(), imgstr() + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (kfname, SZ_FNAME, TY_CHAR) + + # Remove leading whitespace from the pixel source specification. + ip = 1 + while (IS_WHITE(pmsource[ip])) + ip = ip + 1 + call strcpy (pmsource[ip], Memc[fname], SZ_FNAME) + flags = 0 + pmname[1] = EOS + + # If the mask is undefined specify an empty mask. + if (Memc[fname] == EOS || streq (Memc[fname], "EMPTY")) { + + ifnoerr (pmim = im_pmmap ("EMPTY", READ_ONLY+BOOLEAN_MASK, refim)) { + call strcpy ("EMPTY", pmname, sz_pmname) + pm = imstati (pmim, IM_PMDES) + call mp_invert (pm) + call imseti (pmim, IM_PMDES, pm) + } else + pmim = NULL + + # If the mask specification is a keyword. + } else if (Memc[fname] == '!') { + + # Invert the specified mask. Note there is a bug in the + # invert mask flag which needs to be worked around. + ip = 1 + if (Memc[fname+ip] == '^') { + ip = ip + 1 + flags = BOOLEAN_MASK + invflag = NO + } else { + #flags = INVERT_MASK + BOOLEAN_MASK + flags = BOOLEAN_MASK + invflag = YES + } + + # Find the mask name. + ifnoerr (call imgstr (refim, Memc[fname+ip], Memc[kfname], + SZ_FNAME)) { + iferr (pmim = mp_pmmap (Memc[kfname], refim, flags, invflag)) { + pmim = NULL + } else if (invflag == NO) { + call strcpy ("^", pmname, sz_pmname) + call strcat (Memc[kfname], pmname, sz_pmname) + } else { + call strcpy (Memc[kfname], pmname, sz_pmname) + } + } else + pmim = NULL + + # If the mask specification is a mask / or image file. + } else if (imaccess (Memc[fname], READ_ONLY) == YES) { + + #flags = BOOLEAN_MASK+INVERT_MASK + flags = BOOLEAN_MASK + invflag = YES + call strcpy (Memc[fname], pmname, sz_pmname) + iferr (pmim = mp_pmmap (Memc[fname], refim, flags, invflag)) + pmim = NULL + else + call strcpy (Memc[fname], pmname, sz_pmname) + + } else if (Memc[fname] == '^') { + if (imaccess (Memc[fname+1], READ_ONLY) == YES) { + flags = BOOLEAN_MASK + invflag = NO + call strcpy (Memc[fname], pmname, sz_pmname) + iferr (pmim = mp_pmmap (Memc[fname+1], refim, flags, invflag)) + pmim = NULL + else + call strcpy (Memc[fname], pmname, sz_pmname) + } else + pmim = NULL + + } else { + pmim = NULL + } + + call sfree (sp) + + return (pmim) +end + + +# MP_PMMAP - Open a pixel mask READ_ONLY. The input mask may be a pixel +# list image or a non-pixel list image. The invflag is temporary, put into +# deal with the fact that mio has a bug in this flag. + + +pointer procedure mp_pmmap (pmname, refim, flags, invflag) + +char pmname[ARB] #I the pixel list or image name +pointer refim #I the reference image descriptor +int flags #I the pixel list or image flags +int invflag #I invert mask flag, remove when pmio fixed + +pointer sp, section, pmim, pm, tmp_refim +int use_section +pointer im_pmmap(), mp_immap() +int imstati() +errchk im_pmmap(), mp_immap() + +begin + # Does the pmname include an image section. + call smark (sp) + call salloc (section, SZ_FNAME, TY_CHAR) + call imgsection (pmname, Memc[section], SZ_FNAME) + if (Memc[section] == EOS) { + use_section = NO + tmp_refim = refim + } else { + use_section = YES + tmp_refim = NULL + } + + # Open the mask as a pixel list. + ifnoerr (pmim = im_pmmap (pmname, READ_ONLY+flags, tmp_refim)) { + + if (use_section == YES) + call mp_section (pmim) + if (invflag == YES) { + pm = imstati (pmim, IM_PMDES) + call mp_invert (pm) + call imseti (pmim, IM_PMDES, pm) + } + + # Open the mask as an image file. + } else ifnoerr (pmim = mp_immap (pmname)) { + + if (invflag == YES) { + pm = imstati (pmim, IM_PMDES) + call mp_invert (pm) + call imseti (pmim, IM_PMDES, pm) + } + + } else { + pmim = NULL + } + + call sfree (sp) + + return (pmim) +end + + +# MP_IMMAP -- Map an image as a pixel file + +pointer procedure mp_immap (pmname) + +char pmname[ARB] #I the pixel list or image name + +pointer sp, v1, v2, im, pm, data, pmim +int ndim, npix +pointer immap(), pm_newmask(), im_pmmapo() +int imgnli() + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + + # Open the input image. + im = immap (pmname, READ_ONLY, 0) + ndim = IM_NDIM(im) + npix = IM_LEN(im,1) + + # Open the mask with a depth of 1 bit. + pm = pm_newmask (im, 1) + + # Copy the image to a mask. + while (imgnli (im, data, Meml[v1]) != EOF) { + # may need to convert negative values here ... + call pm_plpi (pm, Meml[v2], Memi[data], 0, npix, PIX_SRC) + call amovl (Meml[v1], Meml[v2], ndim) + } + call imunmap (im) + + pmim = im_pmmapo (pm, NULL) + + call sfree (sp) + + return (pmim) +end + + +# MP_SECTION -- Create the a new mask from the specified mask section. + +procedure mp_section (pmim) + +pointer pmim #U mask image descriptor + +pointer newpm, newpmim, sp, v1, v2, ibuf +pointer pl_create(), im_pmmapo() +int ndim, depth, npix +int imgnls() + +begin + call smark (sp) + call salloc (v1, IM_MAXDIM, TY_LONG) + call salloc (v2, IM_MAXDIM, TY_LONG) + call amovkl (long(1), Meml[v1], IM_MAXDIM) + call amovkl (long(1), Meml[v2], IM_MAXDIM) + + ndim = IM_NDIM(pmim) + depth = 1 + npix = IM_LEN(pmim,1) + + newpm = pl_create (ndim, IM_LEN(pmim,1), depth) + while (imgnls (pmim, ibuf, Meml[v1]) != EOF) { + call pm_plps (newpm, Meml[v2], Mems[ibuf], 1, npix, PIX_SRC) + call amovl (Meml[v1], Meml[v2], ndim) + } + + call imunmap (pmim) + newpmim = im_pmmapo (newpm, NULL) + pmim = newpmim + + call sfree (sp) +end + + +# MP_MPCOPY -- Copy the input to the output mask setting the mapping +# parameters appropriately + +procedure mp_mpcopy (im, pmim, pmout) + +pointer im #I the input image descriptor +pointer pmim #I the input mask descriptor +pointer pmout #I the output mask descriptor + +pointer sp, axlen, v, oldpm, newpm +int naxes, depth +pointer pl_create() +int imstati(), mp_samesize() + +int pm_stati() +int refim, mapstat + +begin + call smark (sp) + call salloc (axlen, IM_MAXDIM, TY_LONG) + call salloc (v, IM_MAXDIM, TY_LONG) + + # Create new mask. + oldpm = imstati (pmim, IM_PLDES) + call pl_gsize (oldpm, naxes, Meml[axlen], depth) + newpm = pl_create (naxes, Meml[axlen], depth) + + # Store old values of the input mask reference image and mapping + # descriptors here. Maybe ... + refim = pm_stati (oldpm, P_REFIM) + mapstat = pm_stati (oldpm, P_MAPXY) + + # Set the input mask mapping parameters. + call pm_seti (oldpm, P_REFIM, im) + if (mp_samesize (im, pmim) == YES) + call pm_seti (oldpm, P_MAPXY, NO) + + # Restore old values of the input mask reference image and mapping + # descriptors here. Maybe ... + + # Store old values of the output reference image and mapping descriptors + # here. Don't need to do this since this is the desired behavior. + + # Set the input mask mapping parameters. + call pm_seti (newpm, P_REFIM, im) + if (mp_samesize (im, pmim) == YES) + call pm_seti (newpm, P_MAPXY, NO) + + # Restore old values of the output mask reference image and mapping + # descriptors here. Don't need to do this since this is the + # desired behavior. + + # Copy the input to the output mask using the mapping parameters + # as appropriate + call amovkl (long(1), Meml[v], IM_MAXDIM) + call pm_rop (oldpm, Meml[v], newpm, Meml[v], Meml[axlen], PIX_SRC) + + call imseti (pmout, IM_PLDES, newpm) + call sfree (sp) +end + + +# MP_MIOPEN - Open an mio descriptor and set the mapping parameters +# appropriately. This should be done by doing pm_stati calls on +# the pm descriptor via the P_REFIM and P_MAPXY parameters and the +# corresponding PRIVATE1 / PRIVATE2 parameters in plio but this +# mechanism is not working at present. For now test im / pmim for +# equality in number of dimensions and size. + +pointer procedure mp_miopen (im, pmim) + +pointer im #I the input image descriptor +pointer pmim #I the input mask image descriptor + +pointer pm, mp +int samesize +pointer mio_openo() +int imstati(), mp_samesize() + +begin + # Open the pixel mask. + pm = imstati (pmim, IM_PLDES) + + # Open the mio descriptor which set the mapping status using + # the image descriptor, i.e. the mapping status is yes if the + # image was opened with a section. + mp = mio_openo (pm, im) + + # Turn off mapping if the image and mask are exactly the same + # size. + samesize = mp_samesize (im, pmim) + if (samesize == YES) + call pm_seti (pm, P_MAPXY, NO) + + return (mp) +end + + +# MP_SAMESIZE -- Return YES if the image and mask are the same size. + +int procedure mp_samesize (im, pmim) + +pointer im #I the input image descriptor +pointer pmim #I the input image descriptor + +int i, samesize + +begin + if (IM_NDIM(im) == IM_NDIM(pmim)) { + samesize = YES + do i = 1, IM_NDIM(im) { + if (IM_LEN(im,i) == IM_LEN(pmim,i)) + next + samesize = NO + break + } + } else { + samesize = NO + } + + return (samesize) +end + + +# MP_INVERT -- Invert a pixel mask. + +procedure mp_invert (pm) + +pointer pm #U plio descriptor + +pointer sp, axlen, v, newpm +int naxes, depth +pointer pl_create() + +begin + # Allocate some working space. + call smark (sp) + call salloc (axlen, IM_MAXDIM, TY_LONG) + call salloc (v, IM_MAXDIM, TY_LONG) + + # Get pixel mask characteristics. + call pl_gsize (pm, naxes, Meml[axlen], depth) + + # Create the new inverted mask. + newpm = pl_create (naxes, Meml[axlen], depth) + call amovkl (long(1), Meml[v], IM_MAXDIM) + call pl_rop (pm, Meml[v], newpm, Meml[v], Meml[axlen], + PIX_NOT(PIX_SRC)) + + # Close the old mask and update the mask pointer. + call pl_close (pm) + pm = newpm + + call sfree (sp) +end + + +# MP_COPY -- Make a copy of an existing pixel mask. + +pointer procedure mp_copy (oldpm) + +pointer oldpm #I old pixel mask pointer + +pointer sp, axlen, v, newpm +int naxes, depth +pointer pl_create() + +begin + call smark (sp) + call salloc (axlen, IM_MAXDIM, TY_LONG) + call salloc (v, IM_MAXDIM, TY_LONG) + + call pl_gsize (oldpm, naxes, Meml[axlen], depth) + newpm = pl_create (naxes, Meml[axlen], depth) + + call amovkl (long(1), Meml[v], IM_MAXDIM) + call pl_rop (oldpm, Meml[v], newpm, Meml[v], Meml[axlen], + PIX_SRC) + + call sfree (sp) + + return (newpm) +end + -- cgit