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