diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/x11gram.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,228 @@
+/****************************************************************************
+*
+*   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);
+}