aboutsummaryrefslogtreecommitdiff
path: root/noao/mtlocal/cyber/rrcopy/rcrimage.x
blob: dc7ebcfb115cb22afdf1e8189aef1c9cbd70b3df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
include	<mach.h>
include	<imhdr.h>
include	<error.h>
include	"rrcopy.h"

# RC_READ_IMAGE -- reads the rcopy image row by row from the tape and writes
# the output image.  At the completion of READ_IMAGE, the tape is positioned
# to the header record of the next tape raster.

procedure rc_read_image (rd, out_fname, data_type, rp)

int	rd, data_type
char	out_fname[SZ_FNAME]
pointer	rp

pointer	sp, im, cyber_buf, spp_buf
int	nchars_per_row, nbits_skip, nchars_to_skip, i
long	clktime()

int	rc_read_cyber()
pointer	immap(), impl2r()
errchk	rc_skip_chars, immap, rc_ipps_to_iraf

begin
	# Allocate buffer for rcopy image pixels
	call smark (sp)
	nchars_per_row = WRDS_PER_ROW(rp) * NBITS_CYBER_WORD / NBITS_CHAR
	call salloc (cyber_buf, nchars_per_row, TY_CHAR)
	call salloc (spp_buf, nchars_per_row, TY_CHAR)

	# Map new iraf image and set up image header
	im = immap (out_fname, NEW_IMAGE, 0)
	IM_LEN(im, 1) = NCOLS(rp)
	IM_LEN(im, 2) = NROWS(rp)
	call strcpy (IPPS_ID(rp), IM_TITLE(im), SZ_IMTITLE)
	IM_MIN(im) = DATA_MIN(rp)
	IM_MAX(im) = DATA_MAX(rp)

	# Set optimum image pixel type
	if (data_type == NOT_SET) {
	    switch (BITS_PIXEL(rp)) {
		case 12:
		    IM_PIXTYPE(im) = TY_SHORT
		case 20:
		    IM_PIXTYPE(im) = TY_REAL
		case 30:
		    IM_PIXTYPE(im) = TY_REAL
		case 60:
		    IM_PIXTYPE(im) = TY_REAL
		default:
		    call error (3, "IPPS BITS_PIXEL is incorrect")
	    }
	} else
	    IM_PIXTYPE(im) = data_type
	IM_LIMTIME(im) = clktime (long(0))

	# Loop over rows to read, reorder and convert pixels. 
	for (i=1; i <= NROWS(rp); i=i+1) {
	    if (rc_read_cyber (rd, Memc[cyber_buf], nchars_per_row) == EOF)
		call error (4, "Unexpected EOT when reading image")
	    call rc_order_cyber_bits (Memc[cyber_buf], 1, Memc[spp_buf], 
			   WRDS_PER_ROW(rp))
	    call rc_ipps_to_iraf (Memc[spp_buf], Memr[impl2r(im,i)], NCOLS(rp), 
				BITS_PIXEL(rp))
        }
	
	# Skip from present position to end of rcopy raster
	nbits_skip = ((PRU_EOR(rp) - PRU_ROW_ONE(rp)) * LEN_PRU -
	   (WRDS_PER_ROW(rp) * NROWS(rp))) * NBITS_CYBER_WORD + NBITS_EOR_MARK

	nchars_to_skip = nbits_skip / NBITS_CHAR
	call rc_skip_chars (rd, nchars_to_skip)

	call imunmap (im)
	call sfree (sp)
end


# RC_IPPS_TO_IRAF -- performs the conversion from Cyber pixels to IRAF pixels.  
# Each row of the rcopy image is required to occupy an integral of Cyber
# PRU's, so the input buffer contains pixels plus filler.  The entire
# buffer is converted and npix pixels are written to the output image.

procedure rc_ipps_to_iraf (in_buf, iraf_real, npix, nbits_pixel)

char	in_buf[ARB]
real	iraf_real[npix]
pointer	iraf_int, sp
int	nbits_pixel, npix, bit_offset, npix_unpk, npix_cyber_wrd
errchk	rc_up_12, rc_up_20

begin
	# Calculate and allocate (maximum) space needed on the stack. The
	# number of pixels unpacked will always fill an integral number
	# of Cyber words.  A maximum of 4 extraneous pixels will be unpacked.
	call smark (sp)
	call salloc (iraf_int, npix + 4, TY_INT)
	bit_offset = 1

	switch (nbits_pixel) {
	case 12: 
	    npix_cyber_wrd = 5
	    npix_unpk = ((npix + 4) / npix_cyber_wrd) * npix_cyber_wrd
	    call rc_up_12 (in_buf, bit_offset, Memi[iraf_int], npix_unpk)
	    call achtir (Memi[iraf_int], iraf_real, npix)

	case 20: 
	    npix_cyber_wrd = 3
	    npix_unpk = ((npix + 2) / npix_cyber_wrd) * npix_cyber_wrd
	    call rc_up_20 (in_buf, bit_offset, Memi[iraf_int], npix_unpk)
	    call achtir (Memi[iraf_int], iraf_real, npix)
	
	case 30: 
	    call rc_up_30 (in_buf, bit_offset, iraf_real, npix)
	
	case 60: 
	    call rc_up_60r (in_buf, bit_offset, iraf_real, npix)
	
	default:
	    call error (5, "Illegal IPPS #B/P")
	}

	call sfree (sp)
end


# RC_SKIP_IMAGE -- skips over an RCOPY raster once the header has been
# read.  When SKIP_IMAGE returns, the tape is positioned to the first
# record of the next tape image.

procedure rc_skip_image (rd, rp)

int	rd
pointer	rp
int	nchars_to_skip
errchk	rc_skip_chars

begin
        # Calculate number of chars in image
        nchars_to_skip = ((PRU_EOR(rp) - PRU_ROW_ONE(rp)) * 
	  LEN_PRU * NBITS_CYBER_WORD + NBITS_EOR_MARK ) / NBITS_CHAR
        call rc_skip_chars (rd, nchars_to_skip)
end

# RC_SKIP_CHARS -- positions the tape by skipping the requested number of chars.
 
procedure rc_skip_chars (rd, nchars_to_skip)

int	rd, nchars_to_skip
pointer	sp, dummy
int	nblks_read, nchars_remaining, i
int	rc_read_cyber()

begin
        call smark (sp)
        call salloc (dummy, SZ_TAPE_BLK, TY_CHAR)

        # Calculate the number of full blocks to skip
        nblks_read = nchars_to_skip / SZ_TAPE_BLK
        nchars_remaining = mod (nchars_to_skip, SZ_TAPE_BLK)

	# Read from tape, a block at a time
        for (i=1; i <= nblks_read; i=i+1) {
            if (rc_read_cyber (rd, Memc[dummy], SZ_TAPE_BLK) == EOF)
		call error (6, "Unexpected EOT when skipping image")
	}
    
        # Read partial block from tape
        if (rc_read_cyber (rd, Memc[dummy], nchars_remaining) == EOF)
	    call error (7, "Unexpected EOT when skipping image")

        call sfree (sp)
end