Mercurial > hg > aim92
comparison model/faster.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 faster.c | |
3 ======== | |
4 | |
5 pretty cludgy hack to do fast raster image generation from | |
6 stabilised image frames. | |
7 | |
8 */ | |
9 | |
10 #include <stdio.h> | |
11 #include <math.h> | |
12 | |
13 | |
14 #include "windows.h" | |
15 #include "stitch.h" | |
16 #include "source.h" | |
17 #include "draw.h" | |
18 #include "calc.h" | |
19 | |
20 #define NEAR_PTR * | |
21 | |
22 struct _generator_state { WindowObject window ; int width, height, framewidth ; long colinc, colmax, NEAR_PTR origins, NEAR_PTR scales, NEAR_PTR end_scales ; int times, hidden, colskip, NEAR_PTR offsets ; } ; | |
23 | |
24 void generate( this, frame ) | |
25 struct _generator_state *this ; | |
26 DataType *frame ; | |
27 { | |
28 register long NEAR_PTR origins, NEAR_PTR scales, NEAR_PTR end_scales = this->end_scales ; | |
29 register int fromtop, bit, colskip = this->colskip ; | |
30 register int NEAR_PTR offsets = this->offsets ; | |
31 register long column ; | |
32 register DataType *colptr ; | |
33 register int time, times = abs( this->times ) ; | |
34 WindowImage image_data = window__current_image( this->window ) ; | |
35 register char *ptr, *min_ptr, *base = image_data->data ; | |
36 register int bytes_per_line = image_data->bytes_per_line ; | |
37 register int height = image_data->height ; | |
38 | |
39 /* clear image */ | |
40 | |
41 ptr = base ; | |
42 min_ptr = base + height * bytes_per_line / sizeof ( *base ) ; | |
43 | |
44 while( ptr < min_ptr ) | |
45 *ptr++ = 0 ; | |
46 | |
47 bit = image_data->start_bit ; | |
48 | |
49 time = times ; | |
50 | |
51 *offsets++ = 0 ; | |
52 | |
53 for( ; offsets < this->offsets + height ; offsets++ ) | |
54 *offsets = offsets[-1] + bytes_per_line / sizeof ( *base ) ; | |
55 | |
56 offsets = this->offsets ; | |
57 | |
58 for( column=0 ; DESCALE( column ) < this->framewidth ; column+=this->colinc ) { | |
59 | |
60 colptr = frame + DESCALE( column ) ; | |
61 origins = this->origins ; | |
62 scales = this->scales ; | |
63 | |
64 if( this->hidden ) { | |
65 | |
66 min_ptr = base + offsets[ height-1 ] ; | |
67 | |
68 while( scales < end_scales ) { | |
69 | |
70 if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) | |
71 fromtop = 0 ; | |
72 | |
73 ptr = base + offsets[ fromtop ] ; | |
74 | |
75 if( ptr < min_ptr ) { | |
76 *ptr |= bit ; | |
77 min_ptr = ptr ; | |
78 } | |
79 | |
80 colptr += colskip ; | |
81 } | |
82 } | |
83 else | |
84 while( scales < end_scales ) { | |
85 | |
86 if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) | |
87 fromtop = 0 ; | |
88 | |
89 *( base + offsets[ fromtop ] ) |= bit ; | |
90 | |
91 colptr += colskip ; | |
92 } | |
93 | |
94 if( --time <= 0 ) { | |
95 | |
96 if( bit == image_data->right_bit ) { | |
97 bit = image_data->left_bit ; | |
98 base++ ; | |
99 } | |
100 else | |
101 if( image_data->right_bit < image_data->left_bit ) | |
102 bit >>= 1 ; | |
103 else | |
104 bit <<= 1 ; | |
105 | |
106 time = times ; | |
107 } | |
108 } | |
109 | |
110 return ; | |
111 } | |
112 | |
113 | |
114 struct _generator_state *genstate( window, min, max, framewidth, frameheight, frames, times ) | |
115 WindowObject window ; | |
116 int min, max, framewidth, frameheight ; | |
117 long frames ; | |
118 int times ; | |
119 { | |
120 DeclareNew( struct _generator_state *, this ) ; | |
121 double sintheta, scale, rowscale ; | |
122 int row ; | |
123 | |
124 this->window = window ; | |
125 | |
126 this->times = abs( times ) ; | |
127 this->hidden = times < 0 ; | |
128 | |
129 this->width = Width( window ) ; | |
130 this->height = Height( window ) ; | |
131 | |
132 this->origins = NewArray( long, frameheight, "faster.c for origins" ) ; | |
133 this->scales = NewArray( long, frameheight, "faster.c for scales" ) ; | |
134 | |
135 this->offsets = NewArray( int, this->height, "faster.c for offsets" ) ; | |
136 | |
137 this->end_scales = this->scales + frameheight ; | |
138 | |
139 this->colskip = framewidth /* sizeof ( DataType ) */ ; | |
140 | |
141 this->framewidth = framewidth ; | |
142 this->colinc = SCALAR( framewidth-1. ) / ( this->width-1 ) / this->times ; | |
143 | |
144 sintheta = sin( drawTilt / 45. * atan( 1. ) ) ; | |
145 scale = ( 100. - drawHeadroom ) / 100. / ( drawDistance / ( drawDistance + sintheta ) ) ; | |
146 | |
147 for( row=0 ; row<frameheight ; row++ ) { | |
148 | |
149 rowscale = drawDistance / ( drawDistance + sintheta * ( row + 0.5 ) / frameheight ) ; | |
150 | |
151 this->origins[row] = this->height - ( row + 0.5 ) / frameheight * this->height * rowscale * scale ; | |
152 this->scales[ row] = SCALAR( this->height / ( max * frameheight / rowscale ) ) ; | |
153 } | |
154 | |
155 return ( this ) ; | |
156 } | |
157 | |
158 #if 0 | |
159 | |
160 #define FWIDTH 200 | |
161 #define CHANS 50 | |
162 | |
163 double drawHeadroom=10, drawTilt=40, drawDistance=0.5 ; | |
164 | |
165 int main() | |
166 { | |
167 DeclareNewArray( DataType, buffer, FWIDTH*CHANS, "for buffer" ) ; | |
168 WindowObject window = NewDisplayWindow( "rol", -1, -1, 300, 300, 1 ) ; | |
169 char *state = ( char * ) genstate( window, 0, 100, FWIDTH, CHANS, 1l, 1 ) ; | |
170 int x, chan ; | |
171 | |
172 for( chan=0 ; chan<CHANS ; chan++ ) | |
173 for( x=0 ; x<FWIDTH ; x++ ) | |
174 buffer[chan*FWIDTH+x]= x%150 ; | |
175 | |
176 Clear( window ) ; | |
177 | |
178 x = Store( window ) ; | |
179 | |
180 generate( state, buffer ) ; | |
181 | |
182 Recall( window, 1 ) ; | |
183 Recall( window, 1 ) ; | |
184 Recall( window, 1 ) ; | |
185 Recall( window, 1 ) ; | |
186 Recall( window, 1 ) ; | |
187 Recall( window, 1 ) ; | |
188 Recall( window, 1 ) ; | |
189 Recall( window, 1 ) ; | |
190 Recall( window, 1 ) ; | |
191 Recall( window, 1 ) ; | |
192 Recall( window, 1 ) ; | |
193 | |
194 Pause( window ) ; | |
195 | |
196 exit( 0 ) ; | |
197 } | |
198 | |
199 #endif |