tomwalters@0: /* tomwalters@0: faster.c tomwalters@0: ======== tomwalters@0: tomwalters@0: pretty cludgy hack to do fast raster image generation from tomwalters@0: stabilised image frames. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: tomwalters@0: tomwalters@0: #include "windows.h" tomwalters@0: #include "stitch.h" tomwalters@0: #include "source.h" tomwalters@0: #include "draw.h" tomwalters@0: #include "calc.h" tomwalters@0: tomwalters@0: #define NEAR_PTR * tomwalters@0: tomwalters@0: 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: tomwalters@0: void generate( this, frame ) tomwalters@0: struct _generator_state *this ; tomwalters@0: DataType *frame ; tomwalters@0: { tomwalters@0: register long NEAR_PTR origins, NEAR_PTR scales, NEAR_PTR end_scales = this->end_scales ; tomwalters@0: register int fromtop, bit, colskip = this->colskip ; tomwalters@0: register int NEAR_PTR offsets = this->offsets ; tomwalters@0: register long column ; tomwalters@0: register DataType *colptr ; tomwalters@0: register int time, times = abs( this->times ) ; tomwalters@0: WindowImage image_data = window__current_image( this->window ) ; tomwalters@0: register char *ptr, *min_ptr, *base = image_data->data ; tomwalters@0: register int bytes_per_line = image_data->bytes_per_line ; tomwalters@0: register int height = image_data->height ; tomwalters@0: tomwalters@0: /* clear image */ tomwalters@0: tomwalters@0: ptr = base ; tomwalters@0: min_ptr = base + height * bytes_per_line / sizeof ( *base ) ; tomwalters@0: tomwalters@0: while( ptr < min_ptr ) tomwalters@0: *ptr++ = 0 ; tomwalters@0: tomwalters@0: bit = image_data->start_bit ; tomwalters@0: tomwalters@0: time = times ; tomwalters@0: tomwalters@0: *offsets++ = 0 ; tomwalters@0: tomwalters@0: for( ; offsets < this->offsets + height ; offsets++ ) tomwalters@0: *offsets = offsets[-1] + bytes_per_line / sizeof ( *base ) ; tomwalters@0: tomwalters@0: offsets = this->offsets ; tomwalters@0: tomwalters@0: for( column=0 ; DESCALE( column ) < this->framewidth ; column+=this->colinc ) { tomwalters@0: tomwalters@0: colptr = frame + DESCALE( column ) ; tomwalters@0: origins = this->origins ; tomwalters@0: scales = this->scales ; tomwalters@0: tomwalters@0: if( this->hidden ) { tomwalters@0: tomwalters@0: min_ptr = base + offsets[ height-1 ] ; tomwalters@0: tomwalters@0: while( scales < end_scales ) { tomwalters@0: tomwalters@0: if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) tomwalters@0: fromtop = 0 ; tomwalters@0: tomwalters@0: ptr = base + offsets[ fromtop ] ; tomwalters@0: tomwalters@0: if( ptr < min_ptr ) { tomwalters@0: *ptr |= bit ; tomwalters@0: min_ptr = ptr ; tomwalters@0: } tomwalters@0: tomwalters@0: colptr += colskip ; tomwalters@0: } tomwalters@0: } tomwalters@0: else tomwalters@0: while( scales < end_scales ) { tomwalters@0: tomwalters@0: if( ( fromtop = *origins++ - DESCALE( *colptr * *scales++ ) ) < 0 ) tomwalters@0: fromtop = 0 ; tomwalters@0: tomwalters@0: *( base + offsets[ fromtop ] ) |= bit ; tomwalters@0: tomwalters@0: colptr += colskip ; tomwalters@0: } tomwalters@0: tomwalters@0: if( --time <= 0 ) { tomwalters@0: tomwalters@0: if( bit == image_data->right_bit ) { tomwalters@0: bit = image_data->left_bit ; tomwalters@0: base++ ; tomwalters@0: } tomwalters@0: else tomwalters@0: if( image_data->right_bit < image_data->left_bit ) tomwalters@0: bit >>= 1 ; tomwalters@0: else tomwalters@0: bit <<= 1 ; tomwalters@0: tomwalters@0: time = times ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: struct _generator_state *genstate( window, min, max, framewidth, frameheight, frames, times ) tomwalters@0: WindowObject window ; tomwalters@0: int min, max, framewidth, frameheight ; tomwalters@0: long frames ; tomwalters@0: int times ; tomwalters@0: { tomwalters@0: DeclareNew( struct _generator_state *, this ) ; tomwalters@0: double sintheta, scale, rowscale ; tomwalters@0: int row ; tomwalters@0: tomwalters@0: this->window = window ; tomwalters@0: tomwalters@0: this->times = abs( times ) ; tomwalters@0: this->hidden = times < 0 ; tomwalters@0: tomwalters@0: this->width = Width( window ) ; tomwalters@0: this->height = Height( window ) ; tomwalters@0: tomwalters@0: this->origins = NewArray( long, frameheight, "faster.c for origins" ) ; tomwalters@0: this->scales = NewArray( long, frameheight, "faster.c for scales" ) ; tomwalters@0: tomwalters@0: this->offsets = NewArray( int, this->height, "faster.c for offsets" ) ; tomwalters@0: tomwalters@0: this->end_scales = this->scales + frameheight ; tomwalters@0: tomwalters@0: this->colskip = framewidth /* sizeof ( DataType ) */ ; tomwalters@0: tomwalters@0: this->framewidth = framewidth ; tomwalters@0: this->colinc = SCALAR( framewidth-1. ) / ( this->width-1 ) / this->times ; tomwalters@0: tomwalters@0: sintheta = sin( drawTilt / 45. * atan( 1. ) ) ; tomwalters@0: scale = ( 100. - drawHeadroom ) / 100. / ( drawDistance / ( drawDistance + sintheta ) ) ; tomwalters@0: tomwalters@0: for( row=0 ; roworigins[row] = this->height - ( row + 0.5 ) / frameheight * this->height * rowscale * scale ; tomwalters@0: this->scales[ row] = SCALAR( this->height / ( max * frameheight / rowscale ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( this ) ; tomwalters@0: } tomwalters@0: tomwalters@0: #if 0 tomwalters@0: tomwalters@0: #define FWIDTH 200 tomwalters@0: #define CHANS 50 tomwalters@0: tomwalters@0: double drawHeadroom=10, drawTilt=40, drawDistance=0.5 ; tomwalters@0: tomwalters@0: int main() tomwalters@0: { tomwalters@0: DeclareNewArray( DataType, buffer, FWIDTH*CHANS, "for buffer" ) ; tomwalters@0: WindowObject window = NewDisplayWindow( "rol", -1, -1, 300, 300, 1 ) ; tomwalters@0: char *state = ( char * ) genstate( window, 0, 100, FWIDTH, CHANS, 1l, 1 ) ; tomwalters@0: int x, chan ; tomwalters@0: tomwalters@0: for( chan=0 ; chan