aboutsummaryrefslogtreecommitdiff
path: root/sys/qpoe/qpiorpix.gx
blob: e766749c004d575018618c991a18cf4184369386 (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
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include <mach.h>
include <syserr.h>
include	"../qpio.h"

# QPIO_READPIX -- Sample the event list within the indicated rectangular
# region, using the given blocking factor, to produce a rectangular array
# of "pixels", where each pixel is a count of the number of events mapping
# to that location which pass the event attribute filter and region mask.
#
# NOTE -- It is left up to the caller to zero the output buffer before
# we are called.  (We merely increment the counts of the affected pixels).

int procedure qpio_readpix$t (io, obuf, vs, ve, ndim, xblock, yblock)

pointer	io			#I QPIO descriptor
PIXEL	obuf[ARB]		#O output pixel buffer
int	vs[ndim], ve[ndim]	#I vectors defining region to be extracted
int	ndim			#I should be 2 for QPOE
real	xblock, yblock		#I blocking factors

double	x, y
pointer	sp, evl, ev_p
int	evtype, maxpix, maskval, xoff, yoff, xw, yw, nev, totev, pix, i, j
errchk	qpio_getevents, qpio_setrange, syserr
int	qpio_getevents()

begin
	# Verify arguments.
	if (xblock <= 0 || xblock > (ve[1] - vs[1] + 1))
	    call syserr (SYS_QPBLOCKOOR)
	if (yblock <= 0 || yblock > (ve[2] - vs[2] + 1))
	    call syserr (SYS_QPBLOCKOOR)

	# Compute the size of the output matrix in integer pixels.  This
	# truncates the last partially filled pixel in each axis.

	xw = int ((ve[1] - vs[1] + 1) / xblock + (EPSILOND * 1000))
	yw = int ((ve[2] - vs[2] + 1) / yblock + (EPSILOND * 1000))
	if (xw <= 0 || yw <= 0)
	    return (0)

	call smark (sp)
	call salloc (evl, SZ_EVLIST, TY_POINTER)

	xoff = IO_EVXOFF(io)
	yoff = IO_EVYOFF(io)
	maxpix = xw * yw
	totev = 0

	evtype = IO_EVXTYPE(io)
	if (IO_EVXTYPE(io) != IO_EVYTYPE(io))
	    call syserr (SYS_QPINVEVT)

	# Define the region from which we wish to read events.
	call qpio_setrange (io, vs, ve, ndim)

	# Read the events.
	while (qpio_getevents (io, Memi[evl], maskval, SZ_EVLIST, nev) > 0) {
	    switch (evtype) {
	    $for (silrd)
	    case TY_PIXEL:
		# Process a sequence of neighbor events.
		do i = 1, nev {
		    ev_p = (Memi[evl+i-1] - 1) * SZ_SHORT / SZ_PIXEL + 1

		    x = Mem$t[ev_p+xoff]  
		    y = Mem$t[ev_p+yoff]

		    j = int ((y - vs[2]) / yblock + (EPSILOND * 1000))
		    if (j >= 0 && j < yw) {
			pix = j * xw + (x - vs[1]) / xblock + 1
			if (pix > 0 && pix <= maxpix)
			    obuf[pix] = obuf[pix] + 1
		    }
		}
	    $endfor
	    }

	    totev = totev + nev
	}

	call sfree (sp)
	return (totev)
end