aboutsummaryrefslogtreecommitdiff
path: root/pkg/plot/crtpict/xformimage.x
blob: 0400cc914e21d51763ad23949d3801cd7aae0039 (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
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<imhdr.h>
include	<mach.h>
include	<gset.h>
include	"wdes.h"
include	"crtpict.h"

# CRT_TRANSFORM_IMAGE -- Map an image into the output device.  In general this
# involves independent linear transformations in the X, Y, and Z (greyscale)
# dimensions.  If a spatial dimension is larger than the display window then
# the image is block averaged.  If a spatial dimension or a block averaged
# dimension is smaller than the display window then linear interpolation is
# used to expand the image.  The input image is accessed via IMIO; the 
# transformed image is output to a greyscale device via GIO.    

procedure crt_transform_image (gp, im, wdes, cl)

pointer	gp			# graphics descriptor for output
pointer	im			# input image
pointer	wdes			# graphics window descriptor
pointer	cl

real	ndc_xs,ndc_xe,ndc_ys,ndc_ye	# NDC of output device window
real	px1, px2, py1, py2	# image coords in fractional image pixels
real	pxsize, pysize		# size of image section in fractional pixels
real	wxcenter, wycenter	# center of device window in frac device pixels
real	xmag, ymag		# x,y magnification ratios
pointer	w0, w1			# world coord systems 0 (NDC) and 1 (pixel)
int	ndev_cols, ndev_rows, nx_output, ny_output
int	ggeti()
errchk	ggeti, gseti, gsview, gswind, draw_perimeter
errchk	crt_map_image, crt_replicate_image

begin
	# Compute pointers to WCS 0 and 1.
	w0 = W_WC(wdes,0)
	w1 = W_WC(wdes,1)

	call printf ("%s: %s\n")
	    call pargstr (W_IMSECT(wdes))
	    call pargstr (IM_TITLE(im))

	ndev_cols = ggeti (gp, "xr")
	ndev_rows = ggeti (gp, "yr")

	# Compute X and Y magnification ratios required to map image into
	# the device window.

	xmag = ((W_XE(w0) - W_XS(w0)) * ndev_cols) / (W_XE(w1) - W_XS(w1))
	ymag = ((W_YE(w0) - W_YS(w0)) * ndev_rows) / (W_YE(w1) - W_YS(w1))

	# Compute the coordinates of the image section to be displayed.
	# This is not necessarily the same as WCS 1 since the WCS coords
	# need not be inbounds, but they are integral pixels.

	px1 = max (1.0,		        real (int (W_XS(w1) + 0.5)))
	px2 = min (real (IM_LEN(im,1)), real (int (W_XE(w1) + 0.5)))
	py1 = max (1.0,		        real (int (W_YS(w1) + 0.5)))
	py2 = min (real (IM_LEN(im,2)), real (int (W_YE(w1) + 0.5)))

	# The extent of the output image in NDC coords
	pxsize = ((px2 - px1) + 1.0) / ndev_cols
	pysize = ((py2 - py1) + 1.0) / ndev_rows

	# The NDC coordinates that map to the central image pixel output
	wxcenter = (W_XE(w0) + W_XS(w0)) / 2.0
	wycenter = (W_YE(w0) + W_YS(w0)) / 2.0

	# Now compute the NDC coordinates of the output device that the
	# image will occupy.  
	ndc_xs = max (W_XS(w0), wxcenter - (pxsize / 2.0 * xmag))
	ndc_xe = max (ndc_xs, min (W_XE(w0), ndc_xs + (pxsize * xmag)))
	ndc_ys = max (W_YS(w0), wycenter - (pysize / 2.0 * ymag))
	ndc_ye = max (ndc_ys, min (W_YE(w0), ndc_ys + (pysize * ymag)))

	# To avoid possible truncation errors down the line, make sure
	# the ndc coordinates passed to the output procedures represent
	# integer pixels.
	ndc_xs = real (int (ndc_xs * ndev_cols)) / ndev_cols
	ndc_xe = real (int (ndc_xe * ndev_cols)) / ndev_cols
	ndc_ys = real (int (ndc_ys * ndev_rows)) / ndev_rows
	ndc_ye = real (int (ndc_ye * ndev_rows)) / ndev_rows

	# Output the image data in WCS 0.  The number of image pixels that
	# will be put out across the device is calculated first.  

	call gseti (gp, G_WCS, 0)
	if (REPLICATE(cl) == YES) {
	    nx_output = (int(px2) - int(px1)) + 1
	    ny_output = (int(py2) - int(py1)) + 1
	} else {
	    # Image pixels will be scaled to number of device pixels 
	    nx_output = ((ndc_xe * ndev_cols) - (ndc_xs * ndev_cols)) + 1
	    ny_output = ((ndc_ye * ndev_rows) - (ndc_ys * ndev_rows)) + 1
	    nx_output = nx_output / X_BA(cl)
	    ny_output = ny_output / Y_BA(cl)
	}

	# Tweak the ndc coordinates to insure integer replication factors.
	# This may change the ndc coordinates.
	call crt_tweak_ndc (nx_output, ndc_xs, ndc_xe, ndev_cols)
	call crt_tweak_ndc (ny_output, ndc_ys, ndc_ye, ndev_rows)

	# Call routine that actually puts out the pixels row by row
	call crt_map_image (im, gp, px1,px2,py1,py2, ndc_xs,ndc_xe,
	       ndc_ys,ndc_ye, nx_output, ny_output, W_ZS(w1),W_ZE(w1),W_ZT(w1),
	           cl)

	# Change to pixel coordinates and draw perimeter axes if requested
	call gseti  (gp, G_WCS, 2)
	call gsview (gp, ndc_xs, ndc_xe, ndc_ys, ndc_ye)
	call gswind (gp, px1, px2, py1, py2)

	if (PERIM(cl) == YES)
	    call draw_perimeter (gp)
end