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