tomwalters@0
|
1 /****************************************************************************
|
tomwalters@0
|
2 *
|
tomwalters@0
|
3 * compilation: cc -o xgram xgram.c -lX11
|
tomwalters@0
|
4 *
|
tomwalters@0
|
5 * "profile" is an array with an element for each pixel across the window.
|
tomwalters@0
|
6 *
|
tomwalters@0
|
7 ****************************************************************************/
|
tomwalters@0
|
8
|
tomwalters@0
|
9 #include <stdio.h>
|
tomwalters@0
|
10 #include <math.h>
|
tomwalters@0
|
11 #include "x11coord.h"
|
tomwalters@0
|
12
|
tomwalters@0
|
13 char DEFNAME[]= "stdin"; /* window name */
|
tomwalters@0
|
14 char *name = DEFNAME;
|
tomwalters@0
|
15
|
tomwalters@0
|
16 /****************************************************************************
|
tomwalters@0
|
17 * Defaults for plot
|
tomwalters@0
|
18 ****************************************************************************/
|
tomwalters@0
|
19 #define DEFn 128 /* number of data points on a plot line */
|
tomwalters@0
|
20 #define DEFln FULLWIDTH>>1 /* length of plot line in pixels */
|
tomwalters@0
|
21 #define DEFl 1000 /* max number of lines to plot */
|
tomwalters@0
|
22 #define DEFs 0 /* number of plot lines offset from start of file */
|
tomwalters@0
|
23 #define DEFf 0.2 /* scale factor for plot y-values */
|
tomwalters@0
|
24
|
tomwalters@0
|
25 #define DEFdx 2 /* origin increments for successive lines, in pixels */
|
tomwalters@0
|
26 #define DEFdy 2
|
tomwalters@0
|
27
|
tomwalters@0
|
28 /****************************************************************************
|
tomwalters@0
|
29 * Arguments
|
tomwalters@0
|
30 ****************************************************************************/
|
tomwalters@0
|
31 int s=DEFs; /* start position in file */
|
tomwalters@0
|
32 short n=DEFn; /* number of data points on a plot line */
|
tomwalters@0
|
33 short l=DEFl; /* max number of lines to plot */
|
tomwalters@0
|
34 short ln=DEFln; /* length of plot line in pixels */
|
tomwalters@0
|
35 short dx=DEFdx,dy=DEFdy; /* increments for successive lines, in pixels */
|
tomwalters@0
|
36 double f=DEFf; /* scale factor for each y-value */
|
tomwalters@0
|
37
|
tomwalters@0
|
38 /****************************************************************************
|
tomwalters@0
|
39 * main
|
tomwalters@0
|
40 ****************************************************************************/
|
tomwalters@0
|
41 main(argc, argv)
|
tomwalters@0
|
42 int argc ;
|
tomwalters@0
|
43 char *argv[] ;
|
tomwalters@0
|
44 {
|
tomwalters@0
|
45 FILE *fp, *fopen();
|
tomwalters@0
|
46 Window w;
|
tomwalters@0
|
47 short p;
|
tomwalters@0
|
48 int i;
|
tomwalters@0
|
49
|
tomwalters@0
|
50
|
tomwalters@0
|
51 while (--argc > 0 && **++argv == '-')
|
tomwalters@0
|
52 switch (*++*argv) {
|
tomwalters@0
|
53 case 'n': n = atoi(++*argv); break;
|
tomwalters@0
|
54 case 'l': l = atoi(++*argv); break;
|
tomwalters@0
|
55 case 's': s = atoi(++*argv); break;
|
tomwalters@0
|
56 case 'f': f *= atof(++*argv); break;
|
tomwalters@0
|
57 case 'x': dx = atoi(++*argv); break;
|
tomwalters@0
|
58 case 'y': dy = atoi(++*argv); break;
|
tomwalters@0
|
59 case 'h':
|
tomwalters@0
|
60 case 'H':
|
tomwalters@0
|
61 default: help();
|
tomwalters@0
|
62 }
|
tomwalters@0
|
63 /* Open data file */
|
tomwalters@0
|
64 if (argc) {
|
tomwalters@0
|
65 name = *argv;
|
tomwalters@0
|
66 if ((fp = fopen(name, "r")) == NULL) {
|
tomwalters@0
|
67 fprintf(stderr,"can't open %s\n", *argv);
|
tomwalters@0
|
68 exit(1);
|
tomwalters@0
|
69 }
|
tomwalters@0
|
70 }
|
tomwalters@0
|
71 else fp = stdin;
|
tomwalters@0
|
72 /* Seek start of data in file */
|
tomwalters@0
|
73 if (s > 0) {
|
tomwalters@0
|
74 s *= n; /* convert number of lines to number of points */
|
tomwalters@0
|
75 for (i=0 ; i<s && fread(&p, sizeof(short), 1, fp) ; i++)
|
tomwalters@0
|
76 ;
|
tomwalters@0
|
77 if (i<s) error("seek overshot end-of-file\n");
|
tomwalters@0
|
78 }
|
tomwalters@0
|
79
|
tomwalters@0
|
80 set_window_parameters(FULLXORG,FULLYORG, FULLWIDTH,FULLHEIGHT);
|
tomwalters@0
|
81 set_bordered_box(1);
|
tomwalters@0
|
82
|
tomwalters@0
|
83 /** set data so that points fill window ?? **/
|
tomwalters@0
|
84
|
tomwalters@0
|
85 xopen();
|
tomwalters@0
|
86 w = xcreate(name, ButtonPressMask | ExposureMask);
|
tomwalters@0
|
87 xevent_monitor(w,fp);
|
tomwalters@0
|
88 fclose(fp);
|
tomwalters@0
|
89 XDestroyWindow(theDisplay,w);
|
tomwalters@0
|
90 }
|
tomwalters@0
|
91
|
tomwalters@0
|
92
|
tomwalters@0
|
93 /****************************************************************************
|
tomwalters@0
|
94 * X11 Event Monitor.
|
tomwalters@0
|
95 ****************************************************************************/
|
tomwalters@0
|
96 xevent_monitor(w,fp)
|
tomwalters@0
|
97 Window w;
|
tomwalters@0
|
98 FILE *fp;
|
tomwalters@0
|
99 {
|
tomwalters@0
|
100 XEvent event;
|
tomwalters@0
|
101
|
tomwalters@0
|
102 for ( ; ; ) {
|
tomwalters@0
|
103 XNextEvent(theDisplay,&event);
|
tomwalters@0
|
104 switch (event.type) {
|
tomwalters@0
|
105 case ButtonPress:
|
tomwalters@0
|
106 switch(event.xbutton.button) {
|
tomwalters@0
|
107 case Button1: return; /* Left */
|
tomwalters@0
|
108 case Button2: return; /* Middle */
|
tomwalters@0
|
109 case Button3: return; /* Right */
|
tomwalters@0
|
110 default:
|
tomwalters@0
|
111 fprintf(stderr,"button %d not used\n", event.xbutton.button);
|
tomwalters@0
|
112 }
|
tomwalters@0
|
113 break;
|
tomwalters@0
|
114 case Expose:
|
tomwalters@0
|
115 if (event.xexpose.count == 0) {
|
tomwalters@0
|
116 draw_box(w);
|
tomwalters@0
|
117 draw_gram(w,FULLWIDTH,FULLHEIGHT,fp);
|
tomwalters@0
|
118 }
|
tomwalters@0
|
119 break;
|
tomwalters@0
|
120 default:
|
tomwalters@0
|
121 fprintf(stderr,"event type %d not found\n", event.type);
|
tomwalters@0
|
122 }
|
tomwalters@0
|
123 }
|
tomwalters@0
|
124 }
|
tomwalters@0
|
125
|
tomwalters@0
|
126
|
tomwalters@0
|
127
|
tomwalters@0
|
128 /****************************************************************************
|
tomwalters@0
|
129 * Draw line (spectro)-gram with hidden-line removal.
|
tomwalters@0
|
130 ****************************************************************************/
|
tomwalters@0
|
131 #define VISIBLE 0
|
tomwalters@0
|
132 #define HIDDEN 1
|
tomwalters@0
|
133 #define X0 10 /* origin of plot within window */
|
tomwalters@0
|
134 #define Y0 10
|
tomwalters@0
|
135 #define move(x,y) X=x;Y=y
|
tomwalters@0
|
136 #define cont(x,y) XDrawLine(theDisplay, w, theGC, X+X0,height-Y-Y0, x+X0,height-y-Y0);move(x,y)
|
tomwalters@0
|
137
|
tomwalters@0
|
138 draw_gram(w,width,height,fp)
|
tomwalters@0
|
139 Window w;
|
tomwalters@0
|
140 int width,height; /* window size, in pixels */
|
tomwalters@0
|
141 FILE *fp; /* i/p data file */
|
tomwalters@0
|
142 {
|
tomwalters@0
|
143 int i;
|
tomwalters@0
|
144 short p, *profile;
|
tomwalters@0
|
145 short X, Y; /* current active position */
|
tomwalters@0
|
146 short x, y, x0, y0, y1;
|
tomwalters@0
|
147 short xorg=0, yorg=0;
|
tomwalters@0
|
148 float index, res;
|
tomwalters@0
|
149 short rres;
|
tomwalters@0
|
150 char stat;
|
tomwalters@0
|
151
|
tomwalters@0
|
152 profile = (short*) malloc(width * sizeof(short));
|
tomwalters@0
|
153 for (i=0 ; i<width ; i++)
|
tomwalters@0
|
154 profile[i] = 0;
|
tomwalters@0
|
155
|
tomwalters@0
|
156 res = (float)ln/n;
|
tomwalters@0
|
157 rres = (int)(res+0.5); /* rounded resolution */
|
tomwalters@0
|
158 /* plot l lines, or until eof */
|
tomwalters@0
|
159 while (l-->0 && fread(&p, sizeof(short), 1, fp)) {
|
tomwalters@0
|
160 /* draw vertical to start of line */
|
tomwalters@0
|
161 x = xorg;
|
tomwalters@0
|
162 y = yorg + p*f;
|
tomwalters@0
|
163 if (y >= (y0=profile[x])) {
|
tomwalters@0
|
164 profile[x] = y;
|
tomwalters@0
|
165 move(x,y0);
|
tomwalters@0
|
166 cont(x,y);
|
tomwalters@0
|
167 stat = VISIBLE;
|
tomwalters@0
|
168 }
|
tomwalters@0
|
169 else stat = HIDDEN;
|
tomwalters@0
|
170 y0 = y;
|
tomwalters@0
|
171
|
tomwalters@0
|
172 /* draw rest of line */
|
tomwalters@0
|
173 index = xorg;
|
tomwalters@0
|
174 for (i=1 ; i<n && fread(&p, sizeof(short), 1, fp) ; i++) {
|
tomwalters@0
|
175 /* interpolate y-values for each pixel along line */
|
tomwalters@0
|
176 for (x0=1, y1=yorg+p*f ; x0<=rres && x0+x<width ; x0++) {
|
tomwalters@0
|
177 y = (short)( ((float)x0/res) * (y1-y0) + y0 );
|
tomwalters@0
|
178 /* a Hidden line becomes Visible */
|
tomwalters@0
|
179 if (y >= profile[x+x0]) {
|
tomwalters@0
|
180 profile[x+x0] = y;
|
tomwalters@0
|
181 if (stat == HIDDEN) {
|
tomwalters@0
|
182 move(x+x0,y);
|
tomwalters@0
|
183 stat = VISIBLE;
|
tomwalters@0
|
184 }
|
tomwalters@0
|
185 }
|
tomwalters@0
|
186 /* a Visible line becomes Hidden */
|
tomwalters@0
|
187 else {
|
tomwalters@0
|
188 if (stat == VISIBLE) {
|
tomwalters@0
|
189 cont(x+x0,y);
|
tomwalters@0
|
190 stat = HIDDEN;
|
tomwalters@0
|
191 }
|
tomwalters@0
|
192 }
|
tomwalters@0
|
193 }
|
tomwalters@0
|
194 y0 = y1;
|
tomwalters@0
|
195 index += res;
|
tomwalters@0
|
196 x = (int)(index+0.5); /* rounded index */
|
tomwalters@0
|
197 if (stat == VISIBLE)
|
tomwalters@0
|
198 cont(x,y);
|
tomwalters@0
|
199 }
|
tomwalters@0
|
200 cont(x,yorg);
|
tomwalters@0
|
201 xorg += dx;
|
tomwalters@0
|
202 yorg += dy;
|
tomwalters@0
|
203 }
|
tomwalters@0
|
204 }
|
tomwalters@0
|
205
|
tomwalters@0
|
206
|
tomwalters@0
|
207 /****************************************************************************
|
tomwalters@0
|
208 * Misc.
|
tomwalters@0
|
209 ****************************************************************************/
|
tomwalters@0
|
210 error(s)
|
tomwalters@0
|
211 {
|
tomwalters@0
|
212 fprintf(stderr,"%s",s);
|
tomwalters@0
|
213 exit(1);
|
tomwalters@0
|
214 }
|
tomwalters@0
|
215
|
tomwalters@0
|
216 help ()
|
tomwalters@0
|
217 {
|
tomwalters@0
|
218 printf ("\nUsage: a) xgram [options] filename\n");
|
tomwalters@0
|
219 printf (" b) cat filename | xgram [options]\n");
|
tomwalters@0
|
220 printf (" where filename is an input stream of 16-bit binary numbers\n");
|
tomwalters@0
|
221 printf ("Options:\n");
|
tomwalters@0
|
222 printf ("-n [int] = Number of points per plotted line (default=%d).\n", DEFn);
|
tomwalters@0
|
223 printf ("-l [int] = Max number of lines plotted (default=%d).\n", DEFl);
|
tomwalters@0
|
224 printf ("-s [int] = Offset lines (of n points) from start of file (default=%d).\n", DEFs);
|
tomwalters@0
|
225 printf ("-f [float] = Scale factor (default=1).\n");
|
tomwalters@0
|
226 printf ("-x-y[ints] = dx/dy changes for successive lines (defaults %d,%d)\n", DEFdx,DEFdy);
|
tomwalters@0
|
227 exit (0);
|
tomwalters@0
|
228 }
|