view 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 source
/*
    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