Mercurial > hg > aim92
diff stitch/draw.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/stitch/draw.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,233 @@ +/* + Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 + =========================================================================== + + Permission to use, copy, modify, and distribute this software without fee + is hereby granted for research purposes, provided that this copyright + notice appears in all copies and in all supporting documentation, and that + the software is not redistributed for any fee (except for a nominal shipping + charge). Anyone wanting to incorporate all or part of this software in a + commercial product must obtain a license from the Medical Research Council. + + The MRC makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or implied + warranty. + + THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE + A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + draw.c + ====== + + basic interface between file format and windows content + +*/ + +/* Added the field nwid in the '_draw_state' object. AJD 17-3-95 */ + +#include <math.h> + +#include "windows.h" +#include "stitch.h" +#include "source.h" +#include "draw.h" +#include "ops.h" + +#ifndef lint +static char *draw_sccs_id = "@(#)draw.c 1.15 John Holdsworth (MRC-APU) 6/6/91" ; +#endif + +/* maximum buffer size for segmentation of drawing */ + +#if defined( PC ) || defined( THINK_C ) +#define MAX_BUFFER (1l<<14) +#else +#define MAX_BUFFER (1l<<16) +#endif + +/* globale variable for display paramters */ + +double drawHeadroom = 0.0 ; +double drawTilt = 0.0 ; +double drawDepth = 0.0 ; +double drawDistance = 0.5 ; +double drawOverlap = 0.0 ; + +/* + + this mess is worth a comment + + I'd like to apologise for the moras of scaling parameters for display + .. the price of backward compatability. + + Originally you could tillt the diaply to give the sensation of depth, + then the display parameters where changed to min, max and overlap. + The result is the combination of the two. At least the new interface + is a bit cleaner from the outside. + + There is also the complication of segmented drawing across and down + the screen. All in all this needs to be rewritten! + + From the outside though it's interface is reasonably clean however. + + if framewidth > 1 then it's a 2d image per frame. If not then its + a multiplexed file. + +*/ + + +void draw_frame( state, frame ) +struct _draw_state *state ; +short *frame ; +{ + double sintheta = sin( drawTilt / 45. * atan( 1. ) ) ; + double scale = ( 100. - drawHeadroom ) / 100. / ( drawDistance / ( drawDistance + sintheta ) ) ; + double height = Height( state->window ) * ( 1. - drawHeadroom / 100. ) ; + double overscale, rowscale, origin ; + int row ; + + for( row=state->frameheight-1 ; row >= 0 ; row-- ) { + + rowscale = drawDistance / ( drawDistance + sintheta * ( row + 0.5 ) / state->frameheight ) ; + overscale = 1. / ( ( state->frameheight - 1. ) * ( 1. - drawOverlap ) + 1. ) ; + origin = row * height * overscale * ( 1. - drawOverlap ) + + ( 0. - state->min ) / ( state->max - state->min ) * Height( state->window ) * overscale ; + + if( state->framewidth > 1 ) + Function( state->window, frame+row*state->framewidth, state->framewidth, 1, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale ) ; + else + if( state->colnumber == 0 ) + Segment( state->window, frame+row, state->colsegment, state->frameheight, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale, state->colnumber, (int) state->frames ) ; + else + Segment( state->window, frame+row-state->frameheight, state->colsegment+1, state->frameheight, origin * rowscale * scale, ( state->max - state->min ) / overscale / rowscale, state->colnumber-1, (int) state->frames ) ; + } + + return ; +} + + +static void draw_callback( state, bytes, buffer ) +struct _draw_state *state ; +ByteCount *bytes ; +short *buffer ; +{ + int first = state->colnumber == 0 ; + + if( state->framewidth > 1 ) { + state->rowsegment = *bytes / sizeof ( short ) / state->framewidth ; + if( state->rowsegment > state->frameheight - state->rownumber ) + state->rowsegment = state->frameheight - state->rownumber ; + } + else { + state->colsegment = *bytes / sizeof ( short ) / state->frameheight ; + if( state->colsegment > state->frames - state->colnumber ) + state->colsegment = state->frames - state->colnumber ; + } + + if( first ) + ++state->framenumber ; + + if( *bytes != 0 ) + state->interceptor( state, buffer, first ) ; + + if( state->framewidth > 1 ) + state->rownumber = ( state->rownumber + state->rowsegment ) % state->frameheight ; + else + state->colnumber = ( state->colnumber + state->colsegment ) % state->frames ; + +} + +Source SourceDraw( source, min, max, window, framewidth, frameheight, nwid, frames, interceptor, drawer ) +Source source ; +int min, max ; +WindowObject window ; +int framewidth, frameheight ; +int nwid; +long frames ; +void (*interceptor)() ; +void (*drawer)() ; +{ + DeclareNew( struct _draw_state *, state ) ; + int segsize ; + + state->min = min ; + state->max = max ; + + state->source = source ; + state->window = window ; + + state->frameheight = frameheight ; + state->framewidth = framewidth ; + state->nwid = nwid ; + state->frames = frames ; + + state->framenumber = 0 ; + + state->colnumber = 0 ; + state->rownumber = 0 ; + + state->colsegment = framewidth ; + state->rowsegment = frameheight ; + + state->interceptor = interceptor ; + state->drawer = drawer ; + + source = NewTappingSource( state, draw_callback, stitch_free, source, "draw.c drawing" ) ; + + if( state->framewidth == 1 ) { + + segsize = MAX_BUFFER / frameheight / sizeof ( short ) - 1 ; + + if( segsize > frames ) + segsize = frames ; + else + source = NewRetainingSource( source, frameheight * sizeof ( short ) ) ; + + source = NewBlockingSource( source, frameheight * sizeof ( short ) * segsize ) ; + } + + return ( source ) ; +} + +static Source DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, row_flag ) +WindowObject window ; +Source source ; +int min, max ; +int framepoints, frames, nwid ; +int row_flag ; +void (*drawer)() ; +{ + void (*draw_routine)() = drawer ; + + if( draw_routine == (void ( * )()) 0 ) + draw_routine = draw_frame ; + + return ( SourceDraw( source, min, max, window, 1, framepoints, nwid, (long) frames, draw_routine, draw_routine ) ) ; +} + +Source drawAcross( window, source, min, max, framepoints, nwid, frames, drawer ) +WindowObject window ; +Source source ; +int min, max ; +int framepoints, frames ; +void (*drawer)() ; +{ + return ( DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, 0 ) ) ; +} + +Source drawDown( window, source, min, max, framepoints, nwid, frames, drawer ) +WindowObject window ; +Source source ; +int min, max ; +int framepoints, frames ; +void (*drawer)() ; +{ + return ( DrawEither( window, source, min, max, framepoints, nwid, frames, drawer, 1 ) ) ; +} +