Mercurial > hg > aim92
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/model/faster.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,199 @@ +/* + faster.c + ======== + + pretty cludgy hack to do fast raster image generation from + stabilised image frames. + +*/ + +#include <stdio.h> +#include <math.h> + + +#include "windows.h" +#include "stitch.h" +#include "source.h" +#include "draw.h" +#include "calc.h" + +#define NEAR_PTR * + +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 ; } ; + +void generate( this, frame ) +struct _generator_state *this ; +DataType *frame ; +{ + register long NEAR_PTR origins, NEAR_PTR scales, NEAR_PTR end_scales = this->end_scales ; + register int fromtop, bit, colskip = this->colskip ; + register int NEAR_PTR offsets = this->offsets ; + register long column ; + register DataType *colptr ; + register int time, times = abs( this->times ) ; + WindowImage image_data = window__current_image( this->window ) ; + register char *ptr, *min_ptr, *base = image_data->data ; + register int bytes_per_line = image_data->bytes_per_line ; + register int height = image_data->height ; + + /* clear image */ + + ptr = base ; + min_ptr = base + height * bytes_per_line / sizeof ( *base ) ; + + while( ptr < min_ptr ) + *ptr++ = 0 ; + + bit = image_data->start_bit ; + + time = times ; + + *offsets++ = 0 ; + + for( ; offsets < this->offsets + height ; offsets++ ) + *offsets = offsets[-1] + bytes_per_line / sizeof ( *base ) ; + + offsets = this->offsets ; + + for( column=0 ; DESCALE( column ) < this->framewidth ; column+=this->colinc ) { + + colptr = frame + DESCALE( column ) ; + origins = this->origins ; + scales = this->scales ; + + if( this->hidden ) { + + min_ptr = base + offsets[ height-1 ] ; + + while( scales < end_scales ) { + + if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) + fromtop = 0 ; + + ptr = base + offsets[ fromtop ] ; + + if( ptr < min_ptr ) { + *ptr |= bit ; + min_ptr = ptr ; + } + + colptr += colskip ; + } + } + else + while( scales < end_scales ) { + + if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) + fromtop = 0 ; + + *( base + offsets[ fromtop ] ) |= bit ; + + colptr += colskip ; + } + + if( --time <= 0 ) { + + if( bit == image_data->right_bit ) { + bit = image_data->left_bit ; + base++ ; + } + else + if( image_data->right_bit < image_data->left_bit ) + bit >>= 1 ; + else + bit <<= 1 ; + + time = times ; + } + } + + return ; +} + + +struct _generator_state *genstate( window, min, max, framewidth, frameheight, frames, times ) +WindowObject window ; +int min, max, framewidth, frameheight ; +long frames ; +int times ; +{ + DeclareNew( struct _generator_state *, this ) ; + double sintheta, scale, rowscale ; + int row ; + + this->window = window ; + + this->times = abs( times ) ; + this->hidden = times < 0 ; + + this->width = Width( window ) ; + this->height = Height( window ) ; + + this->origins = NewArray( long, frameheight, "faster.c for origins" ) ; + this->scales = NewArray( long, frameheight, "faster.c for scales" ) ; + + this->offsets = NewArray( int, this->height, "faster.c for offsets" ) ; + + this->end_scales = this->scales + frameheight ; + + this->colskip = framewidth /* sizeof ( DataType ) */ ; + + this->framewidth = framewidth ; + this->colinc = SCALAR( framewidth-1. ) / ( this->width-1 ) / this->times ; + + sintheta = sin( drawTilt / 45. * atan( 1. ) ) ; + scale = ( 100. - drawHeadroom ) / 100. / ( drawDistance / ( drawDistance + sintheta ) ) ; + + for( row=0 ; row<frameheight ; row++ ) { + + rowscale = drawDistance / ( drawDistance + sintheta * ( row + 0.5 ) / frameheight ) ; + + this->origins[row] = this->height - ( row + 0.5 ) / frameheight * this->height * rowscale * scale ; + this->scales[ row] = SCALAR( this->height / ( max * frameheight / rowscale ) ) ; + } + + return ( this ) ; +} + +#if 0 + +#define FWIDTH 200 +#define CHANS 50 + +double drawHeadroom=10, drawTilt=40, drawDistance=0.5 ; + +int main() +{ + DeclareNewArray( DataType, buffer, FWIDTH*CHANS, "for buffer" ) ; + WindowObject window = NewDisplayWindow( "rol", -1, -1, 300, 300, 1 ) ; + char *state = ( char * ) genstate( window, 0, 100, FWIDTH, CHANS, 1l, 1 ) ; + int x, chan ; + + for( chan=0 ; chan<CHANS ; chan++ ) + for( x=0 ; x<FWIDTH ; x++ ) + buffer[chan*FWIDTH+x]= x%150 ; + + Clear( window ) ; + + x = Store( window ) ; + + generate( state, buffer ) ; + + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + Recall( window, 1 ) ; + + Pause( window ) ; + + exit( 0 ) ; +} + +#endif