view tools/x11gram.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
/****************************************************************************
*
*   compilation:    cc -o xgram xgram.c -lX11
*
*   "profile" is an array with an element for each pixel across the window.
*
****************************************************************************/

#include <stdio.h>
#include <math.h>
#include "x11coord.h"

char   DEFNAME[]=     "stdin";          /* window name */
char   *name =        DEFNAME;

/****************************************************************************
*   Defaults for plot
****************************************************************************/
#define DEFn            128             /* number of data points on a plot line */
#define DEFln           FULLWIDTH>>1    /* length of plot line in pixels */
#define DEFl            1000            /* max number of lines to plot */
#define DEFs            0               /* number of plot lines offset from start of file */
#define DEFf            0.2             /* scale factor for plot y-values */

#define DEFdx           2               /* origin increments for successive lines, in pixels */
#define DEFdy           2

/****************************************************************************
*   Arguments
****************************************************************************/
int    s=DEFs;              /* start position in file */
short  n=DEFn;              /* number of data points on a plot line */
short  l=DEFl;              /* max number of lines to plot */
short  ln=DEFln;            /* length of plot line in pixels */
short  dx=DEFdx,dy=DEFdy;   /* increments for successive lines, in pixels */
double f=DEFf;              /* scale factor for each y-value */

/****************************************************************************
*       main
****************************************************************************/
main(argc, argv)
int   argc ;
char *argv[] ;
{
    FILE   *fp, *fopen();
    Window  w;
    short   p;
    int     i;


    while (--argc > 0 && **++argv == '-')
	switch (*++*argv) {
	    case 'n':   n       = atoi(++*argv); break;
	    case 'l':   l       = atoi(++*argv); break;
	    case 's':   s       = atoi(++*argv); break;
	    case 'f':   f      *= atof(++*argv); break;
	    case 'x':   dx      = atoi(++*argv); break;
	    case 'y':   dy      = atoi(++*argv); break;
	    case 'h':
	    case 'H':
	    default:    help();
	}
    /* Open data file */
    if (argc) {
	name = *argv;
	if ((fp = fopen(name, "r")) == NULL) {
	    fprintf(stderr,"can't open %s\n", *argv);
	    exit(1);
	}
    }
    else fp = stdin;
    /* Seek start of data in file */
    if (s > 0) {
	s *= n;         /* convert number of lines to number of points */
	for (i=0 ; i<s && fread(&p, sizeof(short), 1, fp) ; i++)
	    ;
	if (i<s) error("seek overshot end-of-file\n");
    }

    set_window_parameters(FULLXORG,FULLYORG, FULLWIDTH,FULLHEIGHT);
    set_bordered_box(1);

    /** set data so that points fill window ?? **/

    xopen();
    w = xcreate(name, ButtonPressMask | ExposureMask);
    xevent_monitor(w,fp);
    fclose(fp);
    XDestroyWindow(theDisplay,w);
}


/****************************************************************************
*       X11 Event Monitor.
****************************************************************************/
xevent_monitor(w,fp)
Window w;
FILE *fp;
{
    XEvent event;

    for ( ; ; ) {
	XNextEvent(theDisplay,&event);
	switch (event.type) {
	    case ButtonPress:
		switch(event.xbutton.button) {
		    case Button1:   return;     /* Left   */
		    case Button2:   return;     /* Middle */
		    case Button3:   return;     /* Right  */
		    default:
			fprintf(stderr,"button %d not used\n", event.xbutton.button);
		}
		break;
	    case Expose:
		if (event.xexpose.count == 0) {
		    draw_box(w);
		    draw_gram(w,FULLWIDTH,FULLHEIGHT,fp);
		}
		break;
	    default:
		fprintf(stderr,"event type %d not found\n", event.type);
	}
    }
}



/****************************************************************************
*       Draw line (spectro)-gram with hidden-line removal.
****************************************************************************/
#define     VISIBLE     0
#define     HIDDEN      1
#define     X0          10              /* origin of plot within window */
#define     Y0          10
#define     move(x,y)   X=x;Y=y
#define     cont(x,y)   XDrawLine(theDisplay, w, theGC, X+X0,height-Y-Y0, x+X0,height-y-Y0);move(x,y)

draw_gram(w,width,height,fp)
Window w;
int    width,height;    /* window size, in pixels */
FILE   *fp;             /* i/p data file */
{
    int    i;
    short  p, *profile;
    short  X, Y;        /* current active position */
    short  x, y, x0, y0, y1;
    short  xorg=0, yorg=0;
    float  index, res;
    short  rres;
    char   stat;

    profile = (short*) malloc(width * sizeof(short));
    for (i=0 ; i<width ; i++)
	profile[i] = 0;

    res = (float)ln/n;
    rres = (int)(res+0.5);      /* rounded resolution */
    /* plot l lines, or until eof */
    while (l-->0 && fread(&p, sizeof(short), 1, fp)) {
	/* draw vertical to start of line */
	x = xorg;
	y = yorg + p*f;
	if (y >= (y0=profile[x])) {
	    profile[x] = y;
	    move(x,y0);
	    cont(x,y);
	    stat = VISIBLE;
	}
	else stat = HIDDEN;
	y0 = y;

	/* draw rest of line */
	index = xorg;
	for (i=1 ; i<n && fread(&p, sizeof(short), 1, fp) ; i++) {
	    /* interpolate y-values for each pixel along line */
	    for (x0=1, y1=yorg+p*f ; x0<=rres && x0+x<width ; x0++) {
		y = (short)( ((float)x0/res) * (y1-y0) + y0 );
		/* a Hidden line becomes Visible */
		if (y >= profile[x+x0]) {
		    profile[x+x0] = y;
		    if (stat == HIDDEN) {
			move(x+x0,y);
			stat = VISIBLE;
		    }
		}
		/* a Visible line becomes Hidden */
		else {
		    if (stat == VISIBLE) {
			cont(x+x0,y);
			stat = HIDDEN;
		    }
		}
	    }
	    y0 = y1;
	    index += res;
	    x = (int)(index+0.5);       /* rounded index */
	    if (stat == VISIBLE)
		cont(x,y);
	}
	cont(x,yorg);
	xorg += dx;
	yorg += dy;
    }
}


/****************************************************************************
*       Misc.
****************************************************************************/
error(s)
{
    fprintf(stderr,"%s",s);
    exit(1);
}

help ()
{
    printf ("\nUsage: a) xgram  [options]  filename\n");
    printf ("       b) cat filename  |  xgram  [options]\n");
    printf ("    where filename is an input stream of 16-bit binary numbers\n");
    printf ("Options:\n");
    printf ("-n [int]      = Number of points per plotted line (default=%d).\n", DEFn);
    printf ("-l [int]      = Max number of lines plotted (default=%d).\n", DEFl);
    printf ("-s [int]      = Offset lines (of n points) from start of file (default=%d).\n", DEFs);
    printf ("-f [float]    = Scale factor (default=1).\n");
    printf ("-x-y[ints]    = dx/dy changes for successive lines (defaults %d,%d)\n", DEFdx,DEFdy);
    exit (0);
}