aboutsummaryrefslogtreecommitdiff
path: root/noao/artdata/t_mkpattern.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /noao/artdata/t_mkpattern.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'noao/artdata/t_mkpattern.x')
-rw-r--r--noao/artdata/t_mkpattern.x318
1 files changed, 318 insertions, 0 deletions
diff --git a/noao/artdata/t_mkpattern.x b/noao/artdata/t_mkpattern.x
new file mode 100644
index 00000000..08b1973b
--- /dev/null
+++ b/noao/artdata/t_mkpattern.x
@@ -0,0 +1,318 @@
+include <error.h>
+include <imhdr.h>
+
+define LEN_UA 20000
+
+# Editing options
+define OPTIONS "|replace|add|multiply|"
+define REPLACE 1 # Replace pixels
+define ADD 2 # Add to pixels
+define MULTIPLY 3 # Multiply pixels
+
+# Patterns
+define PATTERNS "|constant|grid|checker|coordinates|slope|square"
+define CONST 1 # Constant = v1
+define GRID 2 # Grid lines of v2 with given spacing
+define CHECK 3 # Checkboard of given size
+define COORD 4 # Coordinates
+define SLOPE 5 # Slope
+define SQUARE 6 # Square root checkerboard
+
+# T_MKPATTERN -- Create or modify images using simple patterns.
+# Images may be created of a specified size, dimensionality, and pixel
+# datatype. The images may be modified to replace, add, or multiply
+# by specified values. The patterns include a constant value,
+# a grid, a checkerboard or fixed size or increasing size, the
+# 1D pixel coordinate, and a slope. For dimensions greater than
+# 2 the 2D pattern is repeated.
+
+procedure t_mkpattern ()
+
+
+int ilist # Input image list
+int olist # Output image list
+int op # Operation option
+int pat # Pattern
+real v1 # Pattern value 1
+real v2 # Pattern value 2
+int size # Pattern size
+int nl # Number of lines
+int nc # Number of columns
+
+bool new
+int i
+long vin[IM_MAXDIM], vout[IM_MAXDIM]
+pointer sp, input, output, header, in, out, indata, outdata, pat1, pat2
+
+char clgetc()
+bool streq()
+int clgwrd(), clgeti()
+int imtopenp(), imtlen(), imtgetim(), imgnlr(), impnlr()
+real clgetr()
+pointer immap()
+errchk immap
+
+begin
+ call smark (sp)
+ call salloc (input, SZ_FNAME, TY_CHAR)
+ call salloc (output, SZ_FNAME, TY_CHAR)
+ call salloc (header, SZ_FNAME, TY_CHAR)
+
+ # Set the task parameters which apply to all images.
+ ilist = imtopenp ("input")
+ olist = imtopenp ("output")
+ pat = clgwrd ("pattern", Memc[input], SZ_FNAME, PATTERNS)
+ op = clgwrd ("option", Memc[input], SZ_FNAME, OPTIONS)
+ v1 = clgetr ("v1")
+ v2 = clgetr ("v2")
+ size = max (1, clgeti ("size"))
+
+ if (max (1, imtlen (olist)) != imtlen (ilist))
+ call error (1, "Output image list does not match input image list")
+
+ # Loop over the input image lists. If no output list is given
+ # then create or modify the input image.
+
+ while (imtgetim (ilist, Memc[input], SZ_FNAME) != EOF) {
+ if (imtgetim (olist, Memc[output], SZ_FNAME) == EOF)
+ call strcpy (Memc[input], Memc[output], SZ_FNAME)
+
+ # Map images. Check for new, existing, and inplace images.
+ if (streq (Memc[input], Memc[output])) {
+ ifnoerr (out = immap (Memc[output], READ_WRITE, 0)) {
+ in = out
+ new = false
+ } else {
+ iferr (out = immap (Memc[output], NEW_IMAGE, LEN_UA)) {
+ call erract (EA_WARN)
+ next
+ }
+
+ call clgstr ("header", Memc[header], SZ_FNAME)
+ iferr (call mkh_header (out, Memc[header], false, false))
+ call erract (EA_WARN)
+
+ IM_NDIM(out) = clgeti ("ndim")
+ IM_LEN(out,1) = clgeti ("ncols")
+ IM_LEN(out,2) = clgeti ("nlines")
+ IM_LEN(out,3) = clgeti ("n3")
+ IM_LEN(out,4) = clgeti ("n4")
+ IM_LEN(out,5) = clgeti ("n5")
+ IM_LEN(out,6) = clgeti ("n6")
+ IM_LEN(out,7) = clgeti ("n7")
+ switch (clgetc ("pixtype")) {
+ case 'u':
+ IM_PIXTYPE(out) = TY_USHORT
+ case 's':
+ IM_PIXTYPE(out) = TY_SHORT
+ case 'i':
+ IM_PIXTYPE(out) = TY_INT
+ case 'l':
+ IM_PIXTYPE(out) = TY_LONG
+ case 'r':
+ IM_PIXTYPE(out) = TY_REAL
+ case 'd':
+ IM_PIXTYPE(out) = TY_DOUBLE
+ case 'c':
+ IM_PIXTYPE(out) = TY_COMPLEX
+ default:
+ call error (0, "Bad pixel type")
+ }
+ call clgstr ("title", IM_TITLE(out), SZ_IMTITLE)
+ in = out
+ new = true
+ }
+ } else {
+ iferr (in = immap (Memc[input], READ_ONLY, 0)) {
+ call erract (EA_WARN)
+ next
+ }
+ iferr (out = immap (Memc[output], NEW_COPY, in)) {
+ call erract (EA_WARN)
+ call imunmap (in)
+ next
+ }
+ new = false
+ }
+ nc = IM_LEN(out,1)
+ nl = IM_LEN(out,2)
+
+ call amovkl (long (1), vin, IM_MAXDIM)
+ call amovkl (long (1), vout, IM_MAXDIM)
+
+ # Initialize the pattern; two pointers are returned.
+ call mkpatinit (pat, size, v1, v2, pat1, pat2, nc, nl)
+
+ # Create or modify the image with the specified pattern.
+ # A new image is always the same as replace.
+
+ if (new) {
+ while (impnlr (out, outdata, vout) != EOF)
+ call mkpattern (pat, size, v1, v2, pat1, pat2,
+ vout[2]-1, outdata, nc, nl)
+ } else {
+ switch (op) {
+ case REPLACE:
+ while (impnlr (out, outdata, vout) != EOF)
+ call mkpattern (pat, size, v1, v2, pat1, pat2,
+ vout[2]-1, outdata, nc, nl)
+ case ADD:
+ while (impnlr (out, outdata, vout) != EOF) {
+ i = imgnlr (in, indata, vin)
+ call mkpattern (pat, size, v1, v2, pat1, pat2,
+ vout[2]-1, outdata, nc, nl)
+ call aaddr (Memr[indata], Memr[outdata], Memr[outdata],
+ nc)
+ }
+ case MULTIPLY:
+ while (impnlr (out, outdata, vout) != EOF) {
+ i = imgnlr (in, indata, vin)
+ call mkpattern (pat, size, v1, v2, pat1, pat2,
+ vout[2]-1, outdata, nc, nl)
+ call amulr (Memr[indata], Memr[outdata], Memr[outdata],
+ nc)
+ }
+ }
+ }
+
+ call mkpatfree (pat1, pat2)
+ if (in != out)
+ call imunmap (in)
+ call imunmap (out)
+ }
+
+ call imtclose (ilist)
+ call imtclose (olist)
+ call sfree (sp)
+end
+
+
+# MKPATINIT -- Initialize the pattern. For speed one or two lines of the
+# pattern are created and then used over the image by simple array
+# operations.
+
+procedure mkpatinit (pat, size, v1, v2, pat1, pat2, nc, nl)
+
+int pat # Pattern
+int size # Pattern size
+real v1 # Value 1 for pattern
+real v2 # Value 2 for pattern
+pointer pat1 # Pattern 1 buffer
+pointer pat2 # Pattern 2 buffer
+int nc # Number of columns
+int nl # Number of lines
+
+int i
+
+begin
+ pat1 = NULL
+ pat2 = NULL
+
+ switch (pat) {
+ case CONST:
+ call malloc (pat1, nc, TY_REAL)
+ call amovkr (v1, Memr[pat1], nc)
+ case GRID:
+ call malloc (pat1, nc, TY_REAL)
+ call malloc (pat2, nc, TY_REAL)
+ call amovkr (v1, Memr[pat1], nc)
+ call amovkr (v2, Memr[pat2], nc)
+ size = max (size, 2)
+ do i = 1, nc-1, size
+ Memr[pat1+i] = v2
+ case CHECK:
+ call malloc (pat1, nc, TY_REAL)
+ call malloc (pat2, nc, TY_REAL)
+ do i = 0, nc-1 {
+ if (mod (i/size, 2) == 0) {
+ Memr[pat1+i] = v1
+ Memr[pat2+i] = v2
+ } else {
+ Memr[pat1+i] = v2
+ Memr[pat2+i] = v1
+ }
+ }
+ case COORD:
+ call malloc (pat1, nc, TY_REAL)
+ do i = 0, nc-1
+ Memr[pat1+i] = i / size + 1
+ case SLOPE:
+ call malloc (pat1, nc, TY_REAL)
+ call malloc (pat2, 1, TY_REAL)
+ Memr[pat2] = (v2 - v1) / ((nc + nl - 2) / size)
+ do i = 0, nc - 1
+ Memr[pat1+i] = v1 + Memr[pat2] * i / size
+ case SQUARE:
+ call malloc (pat1, nc, TY_REAL)
+ call malloc (pat2, nc, TY_REAL)
+ do i = 0, nc-1 {
+ if (mod (int (sqrt (real (i/size))), 2) == 0) {
+ Memr[pat1+i] = v1
+ Memr[pat2+i] = v2
+ } else {
+ Memr[pat1+i] = v2
+ Memr[pat2+i] = v1
+ }
+ }
+ }
+end
+
+
+# MKPATFREE -- Free memory used in the pattern buffers.
+
+procedure mkpatfree (pat1, pat2)
+
+pointer pat1, pat2 # Pattern buffers
+
+begin
+ call mfree (pat1, TY_REAL)
+ call mfree (pat2, TY_REAL)
+end
+
+
+# MKPATTERN -- Make a line of data.
+
+procedure mkpattern (pat, size, v1, v2, pat1, pat2, line, data, nc, nl)
+
+int pat # Pattern
+int size # Pattern size
+real v1 # Pattern value
+real v2 # Pattern value
+pointer pat1 # Pattern 1
+pointer pat2 # Pattern 2
+int line # Line
+pointer data # Data
+int nc # Number of columns
+int nl # Number of lines
+
+int i
+
+begin
+ i = max (0, line-1) / size
+
+ switch (pat) {
+ case CONST:
+ call amovr (Memr[pat1], Memr[data], nc)
+ case GRID:
+ if (mod (line, size) == 1)
+ call amovr (Memr[pat2], Memr[data], nc)
+ else
+ call amovr (Memr[pat1], Memr[data], nc)
+ case CHECK:
+ if (mod (i, 2) == 0)
+ call amovr (Memr[pat1], Memr[data], nc)
+ else
+ call amovr (Memr[pat2], Memr[data], nc)
+ case COORD:
+ call amovr (Memr[pat1], Memr[data], nc)
+ call aaddkr (Memr[data], real(i*nc/size), Memr[data], nc)
+ case SLOPE:
+ call amovr (Memr[pat1], Memr[data], nc)
+ call aaddkr (Memr[data], i*Memr[pat2], Memr[data], nc)
+ case SQUARE:
+ if (mod (int (sqrt (real (i))), 2) == 0)
+ call amovr (Memr[pat1], Memr[data], nc)
+ else
+ call amovr (Memr[pat2], Memr[data], nc)
+ }
+end