aboutsummaryrefslogtreecommitdiff
path: root/pkg/proto/vol/src/i2sun/t_i2sun.x
blob: ab8119b7cb5ca378c7fc612e7f241b20dde8cdf3 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
include <imhdr.h>
include <ctype.h>
include <mach.h>
include "i2sun.h"


# I2SUN -- IRAF to Sun Rasterfile:  convert either a list of IRAF images 
# or all slices from a specified axis of a dimension>2 image into a series
# of Sun rasterfiles.  This format-specific task is primarily used to make
# movies in the absence of a portable movie/filmloop utility, if a
# Sun-specific movie task is available.
# ** The format of the output Sun rasterfiles is hard-coded into this task,
# ** and thus could diverge from a future Sun format; we do not want to link
# ** with Sun libraries, as this task should be runnable on other machines.

procedure t_i2sun

pointer	sp, tr, input, im, rfnames, clutfile, transform, cur_rf
pointer	ulutfile, ulut, colormap, pk_colormap, lut
int	list, lfd, rfd, nslices, stat, nimages
int	rheader[RAS_HDR_INTS], ras_maptype, ras_maplength, frame, slice, i, j
short	lut1, lut2
bool	use_clut, make_map

pointer immap()
int	open(), access(), clgeti(), imtopenp(), imtlen(), imtgetim(), read()
real	clgetr()
bool	streq(), clgetb()

errchk	open()

begin
	call smark (sp)
	call salloc (tr, LEN_TR, TY_STRUCT)
	call salloc (input, SZ_FNAME, TY_CHAR)
	call salloc (rfnames, SZ_FNAME, TY_CHAR)
	call salloc (clutfile, SZ_FNAME, TY_CHAR)
	call salloc (cur_rf, SZ_FNAME, TY_CHAR)
	call salloc (transform, SZ_LINE, TY_CHAR)
	call salloc (pk_colormap, NGREY*3, TY_CHAR)
	call salloc (colormap, NGREY*3, TY_SHORT)
	lut = NULL
	im = NULL

	# Input parameters.
	list = imtopenp ("input")
	call clgstr ("output", Memc[rfnames], SZ_FNAME)
	call clgstr ("clutfile", Memc[clutfile], SZ_FNAME)
	call clgstr ("ztrans", Memc[transform], SZ_LINE)
	TR_Z1(tr) = clgetr ("z1")
	TR_Z2(tr) = clgetr ("z2")
	TR_ZTRANS(tr) = Z_LINEAR
	if (streq (Memc[transform], "log"))
	    TR_ZTRANS(tr) = Z_LOG
	else if (streq (Memc[transform], "none"))
	    TR_ZTRANS(tr) = Z_UNITARY
	else if (streq (Memc[transform], "user")) {

	    # Get user-specified transfer lookup table.
	    TR_ZTRANS(tr) = Z_USER
	    call salloc (ulutfile, SZ_FNAME, TY_CHAR)
	    call clgstr ("ulutfile", Memc[ulutfile], SZ_FNAME)

	    # Borrowed from DISPLAY; mallocs storage for ulut:
	    call tr_ulut (Memc[ulutfile], TR_Z1(tr), TR_Z2(tr), ulut)
	}
	TR_XSIZE(tr) = clgeti ("xsize")
	TR_YSIZE(tr) = clgeti ("ysize")
	TR_ORDER(tr) = clgeti ("order")
	TR_XMAG(tr)  = clgetr ("xmag")
	TR_YMAG(tr)  = clgetr ("ymag")

	# Get input image axes to map to output frames.  At present we
	# can only traverse one slice axis.
	TR_SLICEAXIS(tr) = clgeti ("sliceaxis")

	# Swap bytes in output rasterfile?  (useful when I2SUN run on VAX etc.)
	TR_SWAPBYTES(tr) = clgetb ("swap")

	# Check if there are no images.
	nimages = imtlen (list)
	if (nimages == 0) {
	    call eprintf (0, "No input images to convert")
	    goto wrapup_
	}

	# Open color lookup table file (an existing Sun rasterfile at present)
	if (access (Memc[clutfile], READ_ONLY, BINARY_FILE) == YES) {
	    lfd = open (Memc[clutfile], READ_ONLY, BINARY_FILE)
	    use_clut = true
	} else
	    use_clut = false

	# Read color lookup table.
	make_map = false
	if (use_clut) {
	    # Only the color table is used from the rasterfile; ignore all else.
	    stat = read (lfd, rheader, RAS_HDR_INTS * SZB_CHAR)
	    if (stat != RAS_HDR_INTS * SZB_CHAR) {
		call eprintf ("Error reading header from file `%s'\n")
		    call pargstr (Memc[clutfile])
		goto wrapup_
	    }
	    if (rheader[1] != RAS_MAGIC) {
		call eprintf ("File `%s' not a valid Sun rasterfile\n")
		    call pargstr (Memc[clutfile])
		goto wrapup_
	    }
	    ras_maptype = rheader[7]
	    ras_maplength = rheader[8]
	    if (ras_maptype != RMT_NONE && ras_maplength > 0) {
		stat = read (lfd, Memc[colormap], ras_maplength / SZB_CHAR)
		if (stat != ras_maplength / SZB_CHAR) {
		    call eprintf ("Error reading colormap from %s\n")
			call pargstr (Memc[clutfile])
		    goto wrapup_
		}
		# Colormap was already packed on disk.
		call achtsc (Mems[colormap], Memc[pk_colormap], ras_maplength)
	    } else {
		make_map = true
		call eprintf ("Invalid colormap in %s; using greyscale\n")
		    call pargstr (Memc[clutfile])
	    }
	} else
	    make_map = true

	if (make_map) {
	    # Construct a greyscale colormap of same range as IMTOOL.
	    ras_maptype = RMT_EQUAL_RGB
	    ras_maplength = NGREY * 3
	    do i = 1, 3 {
		Mems[colormap+(i-1)*NGREY] = WHITE
		do j = COLORSTART+1, COLOREND
		    Mems[colormap+j-1+(i-1)*NGREY] = j * (WHITE+1) /
			NGREY
		Mems[colormap+COLOREND-1+1+(i-1)*NGREY] = WHITE
		do j = COLOREND+2, NGREY
		    Mems[colormap+j-1+(i-1)*NGREY] = BLACK
	    }
	    call achtsc (Mems[colormap], Memc[pk_colormap], ras_maplength)

	    # Pack to byte stream.
	    call chrpak (Memc[pk_colormap], 1, Memc[pk_colormap], 1,
		ras_maplength)
	}

	# For each IRAF image or band, construct and dispose of a rasterfile.
	frame = 0
	while (imtgetim (list, Memc[input], SZ_FNAME) != EOF) {
	    im = immap (Memc[input], READ_ONLY, 0)
	    if (IM_NDIM(im) > 2 && TR_SLICEAXIS(tr) > IM_NDIM(im)) {
		call eprintf ("Specified slice axis invalid for image %s\n")
		    call pargstr (Memc[input])
		goto wrapup_
	    }
	    nslices = IM_LEN(im, TR_SLICEAXIS(tr))
	    if (nslices < 1)
		nslices = 1

	    # Set up spatial transformation (technically, could be different
	    # for each input image).
	    call tr_setup (im, tr)

	    # We assume that if any n>2 images are present, the user wants
	    # all bands dumped out.
	    do slice = 1, nslices {

		# Construct next rasterfile name and open file; works in
		# 'append' mode, next higher available frame number.
		call sprintf (Memc[cur_rf], SZ_FNAME, Memc[rfnames])
		    call pargi (frame)
		while (access (Memc[cur_rf], READ_ONLY, BINARY_FILE) == YES) {
		    frame = frame + 1
		    call sprintf (Memc[cur_rf], SZ_FNAME, Memc[rfnames])
			call pargi (frame)
		}
		iferr (rfd = open (Memc[cur_rf], NEW_FILE, BINARY_FILE)) {
		    call eprintf ("Cannot open output rasterfile `%s'\n")
			call pargstr (Memc[cur_rf])
		    goto wrapup_
		}
		frame = frame + 1

		# Write header to rasterfile:
		rheader[1] = RAS_MAGIC
		rheader[2] = TR_XE(tr) - TR_XS(tr) + 1
		rheader[3] = TR_YE(tr) - TR_YS(tr) + 1
		rheader[4] = NBITS_FB
		rheader[5] = rheader[2] * rheader[3]
		rheader[6] = RMT_STANDARD
		rheader[7] = ras_maptype
		rheader[8] = ras_maplength
		if (TR_SWAPBYTES(tr))
		    call bswap4 (rheader, 1, rheader, 1, RAS_HDR_INTS*4)
		call write (rfd, rheader, RAS_HDR_INTS * SZB_CHAR)

		# Write colormap to rasterfile.
		call write (rfd, Memc[pk_colormap], ras_maplength / SZB_CHAR)

		# Verify user-specified transfer function parameters.
		if (TR_ZTRANS(tr) == Z_USER) {
		    call alims (Mems[ulut], U_MAXPTS, lut1, lut2)
		    if (lut2 < short(DSP_MIN) || lut1 > short(DSP_MAX)) {
			call eprintf ("User specified greyscales <> range\n")
			call eprintf ("ulut1=%D, dmin=%D; ulut2=%D, dmax=%D\n")
			    call pargi (lut1)
			    call pargi (DSP_MIN)
			    call pargi (lut2)
			    call pargi (DSP_MAX)
		    }
		    if (!IS_INDEF(TR_Z1(tr)) && !IS_INDEF(TR_Z2(tr)) &&
			TR_Z2(tr) < IM_MIN(im) || TR_Z1(tr) > IM_MAX(im)) {
			call eprintf ("User specified intensities <> range\n")
			call eprintf ("z1=%g, im_min=%g; z2=%g, im_max=%g\n")
			    call pargr (TR_Z1(tr))
			    call pargr (IM_MIN(im))
			    call pargr (TR_Z2(tr))
			    call pargr (IM_MAX(im))
			call eprintf ("continuing anyway.\n")
		    }
		}

		# Read image pixels and write to rasterfile.
		call cnv_image (im, slice, tr, ulut, rfd)

		call close (rfd)
	    }
	    call imunmap (im)
	}

wrapup_
	if (im != NULL)
	    call imunmap(im)
	call imtclose (list)
	call close (rfd)
	call sfree (sp)
	if (ulut != NULL)
	    call mfree (ulut, TY_SHORT)
end