tomwalters@0
|
1 /*
|
tomwalters@0
|
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
|
tomwalters@0
|
3 ===========================================================================
|
tomwalters@0
|
4
|
tomwalters@0
|
5 Permission to use, copy, modify, and distribute this software without fee
|
tomwalters@0
|
6 is hereby granted for research purposes, provided that this copyright
|
tomwalters@0
|
7 notice appears in all copies and in all supporting documentation, and that
|
tomwalters@0
|
8 the software is not redistributed for any fee (except for a nominal shipping
|
tomwalters@0
|
9 charge). Anyone wanting to incorporate all or part of this software in a
|
tomwalters@0
|
10 commercial product must obtain a license from the Medical Research Council.
|
tomwalters@0
|
11
|
tomwalters@0
|
12 The MRC makes no representations about the suitability of this
|
tomwalters@0
|
13 software for any purpose. It is provided "as is" without express or implied
|
tomwalters@0
|
14 warranty.
|
tomwalters@0
|
15
|
tomwalters@0
|
16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
tomwalters@0
|
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
|
tomwalters@0
|
18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
tomwalters@0
|
19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
tomwalters@0
|
20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
tomwalters@0
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
tomwalters@0
|
22 */
|
tomwalters@0
|
23
|
tomwalters@0
|
24 /*
|
tomwalters@0
|
25 draw.c
|
tomwalters@0
|
26 ======
|
tomwalters@0
|
27
|
tomwalters@0
|
28 basic interface between file format and windows content
|
tomwalters@0
|
29
|
tomwalters@0
|
30 */
|
tomwalters@0
|
31
|
tomwalters@0
|
32 /* Added the field nwid in the '_draw_state' object. AJD 17-3-95 */
|
tomwalters@0
|
33
|
tomwalters@0
|
34 #include <math.h>
|
tomwalters@0
|
35
|
tomwalters@0
|
36 #include "windows.h"
|
tomwalters@0
|
37 #include "stitch.h"
|
tomwalters@0
|
38 #include "source.h"
|
tomwalters@0
|
39 #include "draw.h"
|
tomwalters@0
|
40 #include "ops.h"
|
tomwalters@0
|
41
|
tomwalters@0
|
42 #ifndef lint
|
tomwalters@0
|
43 static char *draw_sccs_id = "@(#)draw.c 1.15 John Holdsworth (MRC-APU) 6/6/91" ;
|
tomwalters@0
|
44 #endif
|
tomwalters@0
|
45
|
tomwalters@0
|
46 /* maximum buffer size for segmentation of drawing */
|
tomwalters@0
|
47
|
tomwalters@0
|
48 #if defined( PC ) || defined( THINK_C )
|
tomwalters@0
|
49 #define MAX_BUFFER (1l<<14)
|
tomwalters@0
|
50 #else
|
tomwalters@0
|
51 #define MAX_BUFFER (1l<<16)
|
tomwalters@0
|
52 #endif
|
tomwalters@0
|
53
|
tomwalters@0
|
54 /* globale variable for display paramters */
|
tomwalters@0
|
55
|
tomwalters@0
|
56 double drawHeadroom = 0.0 ;
|
tomwalters@0
|
57 double drawTilt = 0.0 ;
|
tomwalters@0
|
58 double drawDepth = 0.0 ;
|
tomwalters@0
|
59 double drawDistance = 0.5 ;
|
tomwalters@0
|
60 double drawOverlap = 0.0 ;
|
tomwalters@0
|
61
|
tomwalters@0
|
62 /*
|
tomwalters@0
|
63
|
tomwalters@0
|
64 this mess is worth a comment
|
tomwalters@0
|
65
|
tomwalters@0
|
66 I'd like to apologise for the moras of scaling parameters for display
|
tomwalters@0
|
67 .. the price of backward compatability.
|
tomwalters@0
|
68
|
tomwalters@0
|
69 Originally you could tillt the diaply to give the sensation of depth,
|
tomwalters@0
|
70 then the display parameters where changed to min, max and overlap.
|
tomwalters@0
|
71 The result is the combination of the two. At least the new interface
|
tomwalters@0
|
72 is a bit cleaner from the outside.
|
tomwalters@0
|
73
|
tomwalters@0
|
74 There is also the complication of segmented drawing across and down
|
tomwalters@0
|
75 the screen. All in all this needs to be rewritten!
|
tomwalters@0
|
76
|
tomwalters@0
|
77 From the outside though it's interface is reasonably clean however.
|
tomwalters@0
|
78
|
tomwalters@0
|
79 if framewidth > 1 then it's a 2d image per frame. If not then its
|
tomwalters@0
|
80 a multiplexed file.
|
tomwalters@0
|
81
|
tomwalters@0
|
82 */
|
tomwalters@0
|
83
|
tomwalters@0
|
84
|
tomwalters@0
|
85 void draw_frame( state, frame )
|
tomwalters@0
|
86 struct _draw_state *state ;
|
tomwalters@0
|
87 short *frame ;
|
tomwalters@0
|
88 {
|
tomwalters@0
|
89 double sintheta = sin( drawTilt / 45. * atan( 1. ) ) ;
|
tomwalters@0
|
90 double scale = ( 100. - drawHeadroom ) / 100. / ( drawDistance / ( drawDistance + sintheta ) ) ;
|
tomwalters@0
|
91 double height = Height( state->window ) * ( 1. - drawHeadroom / 100. ) ;
|
tomwalters@0
|
92 double overscale, rowscale, origin ;
|
tomwalters@0
|
93 int row ;
|
tomwalters@0
|
94
|
tomwalters@0
|
95 for( row=state->frameheight-1 ; row >= 0 ; row-- ) {
|
tomwalters@0
|
96
|
tomwalters@0
|
97 rowscale = drawDistance / ( drawDistance + sintheta * ( row + 0.5 ) / state->frameheight ) ;
|
tomwalters@0
|
98 overscale = 1. / ( ( state->frameheight - 1. ) * ( 1. - drawOverlap ) + 1. ) ;
|
tomwalters@0
|
99 origin = row * height * overscale * ( 1. - drawOverlap ) +
|
tomwalters@0
|
100 ( 0. - state->min ) / ( state->max - state->min ) * Height( state->window ) * overscale ;
|
tomwalters@0
|
101
|
tomwalters@0
|
102 if( state->framewidth > 1 )
|
tomwalters@0
|
103 Function( state->window, frame+row*state->framewidth, state->framewidth, 1, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale ) ;
|
tomwalters@0
|
104 else
|
tomwalters@0
|
105 if( state->colnumber == 0 )
|
tomwalters@0
|
106 Segment( state->window, frame+row, state->colsegment, state->frameheight, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale, state->colnumber, (int) state->frames ) ;
|
tomwalters@0
|
107 else
|
tomwalters@0
|
108 Segment( state->window, frame+row-state->frameheight, state->colsegment+1, state->frameheight, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale, state->colnumber-1, (int) state->frames ) ;
|
tomwalters@0
|
109 }
|
tomwalters@0
|
110
|
tomwalters@0
|
111 return ;
|
tomwalters@0
|
112 }
|
tomwalters@0
|
113
|
tomwalters@0
|
114
|
tomwalters@0
|
115 static void draw_callback( state, bytes, buffer )
|
tomwalters@0
|
116 struct _draw_state *state ;
|
tomwalters@0
|
117 ByteCount *bytes ;
|
tomwalters@0
|
118 short *buffer ;
|
tomwalters@0
|
119 {
|
tomwalters@0
|
120 int first = state->colnumber == 0 ;
|
tomwalters@0
|
121
|
tomwalters@0
|
122 if( state->framewidth > 1 ) {
|
tomwalters@0
|
123 state->rowsegment = *bytes / sizeof ( short ) / state->framewidth ;
|
tomwalters@0
|
124 if( state->rowsegment > state->frameheight - state->rownumber )
|
tomwalters@0
|
125 state->rowsegment = state->frameheight - state->rownumber ;
|
tomwalters@0
|
126 }
|
tomwalters@0
|
127 else {
|
tomwalters@0
|
128 state->colsegment = *bytes / sizeof ( short ) / state->frameheight ;
|
tomwalters@0
|
129 if( state->colsegment > state->frames - state->colnumber )
|
tomwalters@0
|
130 state->colsegment = state->frames - state->colnumber ;
|
tomwalters@0
|
131 }
|
tomwalters@0
|
132
|
tomwalters@0
|
133 if( first )
|
tomwalters@0
|
134 ++state->framenumber ;
|
tomwalters@0
|
135
|
tomwalters@0
|
136 if( *bytes != 0 )
|
tomwalters@0
|
137 state->interceptor( state, buffer, first ) ;
|
tomwalters@0
|
138
|
tomwalters@0
|
139 if( state->framewidth > 1 )
|
tomwalters@0
|
140 state->rownumber = ( state->rownumber + state->rowsegment ) % state->frameheight ;
|
tomwalters@0
|
141 else
|
tomwalters@0
|
142 state->colnumber = ( state->colnumber + state->colsegment ) % state->frames ;
|
tomwalters@0
|
143
|
tomwalters@0
|
144 }
|
tomwalters@0
|
145
|
tomwalters@0
|
146 Source SourceDraw( source, min, max, window, framewidth, frameheight, nwid, frames, interceptor, drawer )
|
tomwalters@0
|
147 Source source ;
|
tomwalters@0
|
148 int min, max ;
|
tomwalters@0
|
149 WindowObject window ;
|
tomwalters@0
|
150 int framewidth, frameheight ;
|
tomwalters@0
|
151 int nwid;
|
tomwalters@0
|
152 long frames ;
|
tomwalters@0
|
153 void (*interceptor)() ;
|
tomwalters@0
|
154 void (*drawer)() ;
|
tomwalters@0
|
155 {
|
tomwalters@0
|
156 DeclareNew( struct _draw_state *, state ) ;
|
tomwalters@0
|
157 int segsize ;
|
tomwalters@0
|
158
|
tomwalters@0
|
159 state->min = min ;
|
tomwalters@0
|
160 state->max = max ;
|
tomwalters@0
|
161
|
tomwalters@0
|
162 state->source = source ;
|
tomwalters@0
|
163 state->window = window ;
|
tomwalters@0
|
164
|
tomwalters@0
|
165 state->frameheight = frameheight ;
|
tomwalters@0
|
166 state->framewidth = framewidth ;
|
tomwalters@0
|
167 state->nwid = nwid ;
|
tomwalters@0
|
168 state->frames = frames ;
|
tomwalters@0
|
169
|
tomwalters@0
|
170 state->framenumber = 0 ;
|
tomwalters@0
|
171
|
tomwalters@0
|
172 state->colnumber = 0 ;
|
tomwalters@0
|
173 state->rownumber = 0 ;
|
tomwalters@0
|
174
|
tomwalters@0
|
175 state->colsegment = framewidth ;
|
tomwalters@0
|
176 state->rowsegment = frameheight ;
|
tomwalters@0
|
177
|
tomwalters@0
|
178 state->interceptor = interceptor ;
|
tomwalters@0
|
179 state->drawer = drawer ;
|
tomwalters@0
|
180
|
tomwalters@0
|
181 source = NewTappingSource( state, draw_callback, stitch_free, source, "draw.c drawing" ) ;
|
tomwalters@0
|
182
|
tomwalters@0
|
183 if( state->framewidth == 1 ) {
|
tomwalters@0
|
184
|
tomwalters@0
|
185 segsize = MAX_BUFFER / frameheight / sizeof ( short ) - 1 ;
|
tomwalters@0
|
186
|
tomwalters@0
|
187 if( segsize > frames )
|
tomwalters@0
|
188 segsize = frames ;
|
tomwalters@0
|
189 else
|
tomwalters@0
|
190 source = NewRetainingSource( source, frameheight * sizeof ( short ) ) ;
|
tomwalters@0
|
191
|
tomwalters@0
|
192 source = NewBlockingSource( source, frameheight * sizeof ( short ) * segsize ) ;
|
tomwalters@0
|
193 }
|
tomwalters@0
|
194
|
tomwalters@0
|
195 return ( source ) ;
|
tomwalters@0
|
196 }
|
tomwalters@0
|
197
|
tomwalters@0
|
198 static Source DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, row_flag )
|
tomwalters@0
|
199 WindowObject window ;
|
tomwalters@0
|
200 Source source ;
|
tomwalters@0
|
201 int min, max ;
|
tomwalters@0
|
202 int framepoints, frames, nwid ;
|
tomwalters@0
|
203 int row_flag ;
|
tomwalters@0
|
204 void (*drawer)() ;
|
tomwalters@0
|
205 {
|
tomwalters@0
|
206 void (*draw_routine)() = drawer ;
|
tomwalters@0
|
207
|
tomwalters@0
|
208 if( draw_routine == (void ( * )()) 0 )
|
tomwalters@0
|
209 draw_routine = draw_frame ;
|
tomwalters@0
|
210
|
tomwalters@0
|
211 return ( SourceDraw( source, min, max, window, 1, framepoints, nwid, (long) frames, draw_routine, draw_routine ) ) ;
|
tomwalters@0
|
212 }
|
tomwalters@0
|
213
|
tomwalters@0
|
214 Source drawAcross( window, source, min, max, framepoints, nwid, frames, drawer )
|
tomwalters@0
|
215 WindowObject window ;
|
tomwalters@0
|
216 Source source ;
|
tomwalters@0
|
217 int min, max ;
|
tomwalters@0
|
218 int framepoints, frames ;
|
tomwalters@0
|
219 void (*drawer)() ;
|
tomwalters@0
|
220 {
|
tomwalters@0
|
221 return ( DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, 0 ) ) ;
|
tomwalters@0
|
222 }
|
tomwalters@0
|
223
|
tomwalters@0
|
224 Source drawDown( window, source, min, max, framepoints, nwid, frames, drawer )
|
tomwalters@0
|
225 WindowObject window ;
|
tomwalters@0
|
226 Source source ;
|
tomwalters@0
|
227 int min, max ;
|
tomwalters@0
|
228 int framepoints, frames ;
|
tomwalters@0
|
229 void (*drawer)() ;
|
tomwalters@0
|
230 {
|
tomwalters@0
|
231 return ( DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, 1 ) ) ;
|
tomwalters@0
|
232 }
|
tomwalters@0
|
233
|