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 ) ) ;
+}
+