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