tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE tomwalters@0: A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY tomwalters@0: DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN tomwalters@0: AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF tomwalters@0: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: fill.c tomwalters@0: ====== tomwalters@0: tomwalters@0: tomwalters@0: window filling source tomwalters@0: tomwalters@0: tomwalters@0: Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. tomwalters@0: tomwalters@0: tomwalters@0: Author : John Holdsworth tomwalters@0: Written : 11th May, 1989. tomwalters@0: tomwalters@0: Edited : tomwalters@0: tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include "windows.h" tomwalters@0: #include "stitch.h" tomwalters@0: #include "source.h" tomwalters@0: #include "fill.h" tomwalters@0: tomwalters@0: #ifndef lint tomwalters@0: static char *sccs_id = "@(#)fill.c 1.9 J. Holdsworth (MRC-APU) 11/8/90" ; tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: static int *Match( n1, n2 ) tomwalters@0: int n1, n2 ; tomwalters@0: { tomwalters@0: DeclareNewArray( int, array, n2+16, "for match" ) ; tomwalters@0: float scale ; tomwalters@0: int i ; tomwalters@0: tomwalters@0: if( n2 > 1 ) tomwalters@0: { tomwalters@0: scale = ( abs( n1 ) - 1. ) / ( n2 - 1. ) ; tomwalters@0: tomwalters@0: if( n1 > 0 ) tomwalters@0: for( i=0 ; i < n2 ; i++ ) tomwalters@0: array[ i ] = i * scale + .5 ; tomwalters@0: else tomwalters@0: for( i=0 ; i < n2 ; i++ ) tomwalters@0: array[ i ] = abs( n1 ) - 1 - (int) ( i * scale + .5 ) ; tomwalters@0: tomwalters@0: for( i=n2 ; i < n2 + 16 ; i++ ) tomwalters@0: array[ i ] = 0 ; tomwalters@0: } tomwalters@0: else tomwalters@0: array[ 0 ] = 0 ; tomwalters@0: tomwalters@0: return( array ) ; tomwalters@0: } tomwalters@0: tomwalters@0: struct _fill_state { WindowObject window ; int row_flag, frame, framepoints, frames, major_count, *major, *minor ; short black, white ; } ; tomwalters@0: tomwalters@0: static void fill_callback( state, bytes, buffer ) tomwalters@0: struct _fill_state *state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: short *buffer ; tomwalters@0: { tomwalters@0: short *bptr = buffer ; tomwalters@0: tomwalters@0: while( (char *) bptr < (char *) buffer + *bytes ) { tomwalters@0: tomwalters@0: if( state->frames != 0 && state->frame % state->frames == 0 ) { tomwalters@0: state->frame = 0 ; tomwalters@0: state->major_count=0 ; tomwalters@0: } tomwalters@0: tomwalters@0: while( state->major[ state->major_count ] == state->frame ) { tomwalters@0: state->major_count++ ; tomwalters@0: if( state->row_flag ) tomwalters@0: FillRow( state->window, state->major_count, bptr, state->black, state->white, state->minor, Width( state->window ) ) ; tomwalters@0: else tomwalters@0: FillCol( state->window, state->major_count, bptr, state->black, state->white, state->minor, Height( state->window ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: state->frame++ ; tomwalters@0: tomwalters@0: bptr += state->framepoints ; tomwalters@0: } tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: static void excite_callback( state, bytes, buffer ) tomwalters@0: struct _fill_state *state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: short *buffer ; tomwalters@0: { tomwalters@0: double origin = 1. + ( Height( state->window ) - 1. ) * ( 0. - state->black ) / ( state->white - state->black ) ; tomwalters@0: tomwalters@0: Clear( state->window ) ; tomwalters@0: tomwalters@0: Function( state->window, buffer, ToPoints( short, *bytes ), 1, origin, (double) ( state->white - state->black ) ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: static void smear_callback( state, bytes, buffer ) tomwalters@0: struct _fill_state *state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: short *buffer ; tomwalters@0: { tomwalters@0: double origin = 1. + ( Height( state->window ) - 1. ) * ( 0. - state->black ) / ( state->white - state->black ) ; tomwalters@0: tomwalters@0: Function( state->window, buffer, ToPoints( short, *bytes ), 1, origin, (double) ( state->white - state->black ) ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: static void fill_close( state ) tomwalters@0: struct _fill_state *state ; tomwalters@0: { tomwalters@0: Delete( state->major ) ; tomwalters@0: Delete( state->minor ) ; tomwalters@0: tomwalters@0: Delete( state ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: Source SourceFill( source, black, white, window, framewidth, frameheight, frames, cfs ) tomwalters@0: Source source ; tomwalters@0: int black, white ; tomwalters@0: WindowObject window ; tomwalters@0: int framewidth, frameheight ; tomwalters@0: long frames ; tomwalters@0: double *cfs ; tomwalters@0: { tomwalters@0: DeclareNew( struct _fill_state *, state ) ; tomwalters@0: double mincf, spancf, pixcf ; tomwalters@0: int row, chan ; tomwalters@0: tomwalters@0: state->window = window ; tomwalters@0: tomwalters@0: state->black = black ; tomwalters@0: state->white = white ; tomwalters@0: tomwalters@0: state->major = Match( (int) frames, Width( window ) ) ; tomwalters@0: state->minor = Match( frameheight, Height( window ) ) ; tomwalters@0: tomwalters@0: if( cfs != (double *) 0 ) { tomwalters@0: chan = 0 ; tomwalters@0: mincf = cfs[0] ; tomwalters@0: spancf = cfs[frameheight-1]-mincf ; tomwalters@0: tomwalters@0: for( row=0 ; rowminor[row] = chan ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: state->major_count = 0 ; tomwalters@0: state->frame = 0 ; tomwalters@0: state->frames = 0 ; tomwalters@0: state->framepoints = 0 ; tomwalters@0: tomwalters@0: state->row_flag = 0 ; tomwalters@0: tomwalters@0: switch( abs( framewidth ) ) { tomwalters@0: case 1 : tomwalters@0: return ( NewTappingSource( (Pointer) state, fill_callback, fill_close, source, "fill.c filling" ) ) ; tomwalters@0: case 2 : tomwalters@0: return ( NewTappingSource( (Pointer) state, excite_callback, fill_close, source, "fill.c filling" ) ) ; tomwalters@0: case 3 : tomwalters@0: return ( NewTappingSource( (Pointer) state, smear_callback, fill_close, source, "fill.c filling" ) ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: */ tomwalters@0: tomwalters@0: static Source FillEither( window, source, black, white, framepoints, frames, scale, row_flag ) tomwalters@0: WindowObject window ; tomwalters@0: Source source ; tomwalters@0: int black, white ; tomwalters@0: int framepoints, frames ; tomwalters@0: double *scale ; tomwalters@0: int row_flag ; tomwalters@0: { tomwalters@0: DeclareNew( struct _fill_state *, state ) ; tomwalters@0: int minor_pixels, major_pixels ; tomwalters@0: double min, span, value ; tomwalters@0: int row, chan ; tomwalters@0: tomwalters@0: if( row_flag ) { tomwalters@0: minor_pixels = Width( window ) ; tomwalters@0: major_pixels = Height( window ) ; tomwalters@0: } tomwalters@0: else { tomwalters@0: minor_pixels = Height( window ) ; tomwalters@0: major_pixels = Width( window ) ; tomwalters@0: } tomwalters@0: tomwalters@0: state->window = window ; tomwalters@0: tomwalters@0: state->black = black ; tomwalters@0: state->white = white ; tomwalters@0: tomwalters@0: state->major = Match( frames, major_pixels ) ; tomwalters@0: state->minor = Match( framepoints, minor_pixels ) ; tomwalters@0: tomwalters@0: if( !row_flag ) /* reverse match array for columns for now */ tomwalters@0: for( chan=0 ; chanminor[minor_pixels-1-chan] ; tomwalters@0: state->minor[minor_pixels-1-chan] = state->minor[chan] ; tomwalters@0: state->minor[chan]= row ; tomwalters@0: } tomwalters@0: tomwalters@0: if( scale != (double *) 0 ) { tomwalters@0: tomwalters@0: chan = 0 ; tomwalters@0: min = scale[0] ; tomwalters@0: span = scale[framepoints-1]-min ; tomwalters@0: tomwalters@0: for( row=0 ; row < minor_pixels ; row++ ) { tomwalters@0: tomwalters@0: value = min + ( row + 0.5 ) / minor_pixels * span ; tomwalters@0: tomwalters@0: while( scale[chan] < value ) tomwalters@0: chan++ ; tomwalters@0: tomwalters@0: state->minor[row] = chan ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: state->framepoints = framepoints ; tomwalters@0: state->frames = frames ; tomwalters@0: state->frame = 0 ; tomwalters@0: state->major_count = 0 ; tomwalters@0: tomwalters@0: state->row_flag = row_flag ; tomwalters@0: tomwalters@0: return ( NewTappingSource( (Pointer) state, fill_callback, fill_close, source, "fill.c filling" ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Source fillAcross( window, source, black, white, framepoints, frames, scale ) tomwalters@0: WindowObject window ; tomwalters@0: Source source ; tomwalters@0: int black, white ; tomwalters@0: int framepoints, frames ; tomwalters@0: double *scale ; tomwalters@0: { tomwalters@0: return ( FillEither( window, source, black, white, framepoints, frames, scale, 0 ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: Source fillDown( window, source, black, white, framepoints, frames, scale ) tomwalters@0: WindowObject window ; tomwalters@0: Source source ; tomwalters@0: int black, white ; tomwalters@0: int framepoints, frames ; tomwalters@0: double *scale ; tomwalters@0: { tomwalters@0: return ( FillEither( window, source, black, white, framepoints, frames, scale, 1 ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: