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