home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Science
/
Science.zip
/
imdisp79.zip
/
PLOT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-15
|
41KB
|
1,324 lines
/*** IMDISP module PLOT.C
PLOT contains the routines for plotting spectra and lines from
images. It was originally written by Ed Esfandari to support the
International Halley Watch CD-ROM. This module was extensively
modified and moderately tested by:
A. Warnock
ST Systems Corp
Mail Code 681
NASA/Goddard Space Flight Center
Greenbelt, MD.
All bugs contained herein are mine and mine alone.
***/
#define __MSC
/* * * * INCLUDE files * * * */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "mshell.h"
#include "imdef.h"
#include "dispio.h"
#include "imdisp.h"
#include "imdutil.h"
#include "imageio.h"
#include "disputil.h"
#include "keywutil.h"
#include "textutil.h"
#include "refresh.h"
#include "plot.h"
#include "spectra.h"
/* * * * External functions * * * */
/* * * * Function declarations * * * */
void Plot32 (long *, long, long, int, int, char *, int, int, int, int, int,
int, char);
void Plot8 (unsigned char *, unsigned char, unsigned char, int, char *,
int, int, int, int, int, int, char);
void Plotpair (long *, long *, long, long, long, long, int, char *, int, int);
long min3arr (long *, int);
long max3arr (long *, int);
int DoPlot (void);
int DoPerspect (void);
void FramePlot (int, int, int, int, long, long, long, long);
void NewZoomEndpoints( int *, int *, int *, int *, int, int, int, int);
long screen_to_DN_y (int);
int DN_to_screen_y (long);
/* * * * Global Variables * * * */
extern Spectrum baseliner;
extern float slope, intercept;
extern Plot ThePlot;
float scale_ydata_to_screen;
long y_min;
int lowedge;
long screen_to_DN_y( int y_screen)
{
return( (long) ( (float) (lowedge - y_screen) / scale_ydata_to_screen) + y_min);
}
int DN_to_screen_y( long y_DN)
{
return( lowedge - (int) ((float)(y_DN - y_min) * scale_ydata_to_screen));
}
void Plot32( long * buf, long miny, long maxy, int start, int len, char * symbol,
int color_flag, int top, int bottom, int left, int right,
int zoom, char Overlay)
/*** Plot32 plots a single array of 32-bit y-values against a running
index on the x-axis. The code provides for zooming in on a region
of interest, plotting with dots or lines and plotting in different
colors.
Original version - 3/31/89 AEE
Modified version - 8/90 AW3
Parameter Type In/out Description
buf long ptr in The buffer containing the y data
miny long in The minimum y value to plot
maxy long in The maximum y value to plot
start int in The subscript of the first point in the array
len int in The number of points in the y array
symbol char in Plotting symbol flag: 'D' for dots
anything else for line
color_flag int in Plotting color (index into current pal
or -1 if variable colors)
zoom int in Zoom flag: 0 if no zooming this time
1 if zooming desired (i.e., ask)
Overlay char in Overlay flag - 'Y' to overlay plot,
'N' to redraw whole thing
***/
{
int i, j, yaxisrev;
int adjval, nextx, prevy, prevx;
int ycoord, leftedge;
int line1, samp1, line2, samp2, line, samp;
int wave_flag, string_len;
int height, width, end;
int tic, numbins;
int color;
long minx, maxx, hold_minx, hold_maxx;
char ch='N', dispstr[64];
float scale_color;
float pixperbin, yrange;
/* Find the actual starting and ending X values from the header, if
present */
if (xflag)
{
minx = (long) xstart;
maxx = (long)(xstart + (len * xinterval));
}
else
{
xstart = (float) start;
xinterval = 1.0 / len;
minx = (long) start;
maxx = (long)(len - 1);
}
end = len - start - 1;
hold_minx = minx;
hold_maxx = maxx;
ThePlot.X.start = xstart;
ThePlot.X.interval = xinterval;
/* Set display sizes in units of screen pixels */
height = bottom - top;
width = right - left;
right = left + width; /* reset right edge */
numbins = width;
pixperbin = (float)len / numbins;
tic = (numbins / 16) * pixperbin;
if (color_flag >= 0)
color = color_flag;
ThePlot.Y.parms.range_s = height;
ThePlot.Y.parms.low_s = bottom;
ThePlot.Y.parms.high_s = top;
ThePlot.Y.parms.low_DN = miny;
ThePlot.Y.parms.high_DN = maxy;
ThePlot.X.parms.range_s = width;
ThePlot.X.parms.low_s = left;
ThePlot.X.parms.high_s = right;
ThePlot.X.parms.range_DN = len - start;
ThePlot.X.parms.low_DN = start;
ThePlot.X.parms.high_DN = len;
y_min = miny;
/* Top of the plotting loop - do this until no more zooming */
while (zoom >= 0)
{
yrange = (float) (maxy - y_min) ;
ThePlot.Y.parms.range_DN = maxy - y_min;
if (ThePlot.Y.parms.range_DN != 0)
{
scale_ydata_to_screen = ( (float) height) / yrange;
ThePlot.Y.scale.DN_to_s = scale_ydata_to_screen;
scale_color = ( (float) numDN) / yrange ;
}
if (Overlay != 'Y')
{
FramePlot( top, bottom, left, right, minx, maxx, y_min, maxy);
}
/* Set the starting points for the plot */
lowedge = bottom;
leftedge= left;
prevy = max( buf[0], y_min);
prevy = DN_to_screen_y (prevy);
/*
prevy = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
*/
prevx = left;
/* Loop over the points in the y array */
for (i=start; i<start+len; i++)
{
if(buf[i] <= maxy && buf[i] >= y_min)
{
/* adjval to fall in plot range */
ycoord = DN_to_screen_y (buf[i]);
/*
adjval = (int) (((float) (buf[i]-miny)) * scale_ydata_to_screen);
*/
if (color_flag == -1)
color = (int) (((float) (buf[i]-y_min)) * scale_color);
/* make y-axis increase upward */
/* ycoord = lowedge - adjval; */
/* scales the length of X-axis (samples) correctly */
nextx = leftedge + (int) ((i-start) * ((float)width/len));
/* plot the next point */
if (strlen(symbol) == 0)
{
/* use lines; connect the points */
DrawLine(prevy, prevx, ycoord, nextx, color);
prevy = ycoord;
prevx = nextx;
}
else if (strstr(symbol, ".") != NULL)
WritePixel(ycoord, nextx, color);
else
DrawText(symbol, ycoord, nextx, 8, 0, color);
}
}
if (zoom == 2) /* We've already zoomed once */
{
DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,numDN-1);
ch = getch();
}
if (zoom == 1) /* We haven't zoomed, and we want to */
{
ch = 'Y';
zoom = 2;
}
/* Either way, find the new endpoints and redraw the plot */
if (ch == 'y' || ch == 'Y')
{
/* clears the prompt line */
DrawText("Would you like to zoom again (y/n)? ", 10, 1, 8, 0, 0);
NewZoomEndpoints(&line1, &samp1, &line2, &samp2, left, right,
width, bottom);
/* set the new starting points */
start = minx + (samp1-left) * ((float) len /(float)width);
start = max( start, minx);
end = minx + (samp2-left) * ((float) len /(float)width);
end = min( end, maxx);
len = end - start + 1;
/* find the array indexes for the new starting points */
if(len > 0)
{
/* X-axis range selected is > 0 */
minx = start;
maxx = end;
y_min = 0x7fffffff;
maxy = 0x80000000;
/* new min and max for the plot */
for (i= start; i<start+len; i++)
{
if (buf[i] < y_min)
y_min= buf[i];
if (buf[i] > maxy)
maxy= buf[i];
}
prevy = DN_to_screen_y (buf[start]);
/*
prevy= lowedge - ((int) (((float) (buf[start] - miny)) * scale_ydata_to_screen));
*/
prevx= leftedge;
}
else
{
/* selected X range is zero */
zoom = -1;
}
/*
minx= (long) (xstart + (float) (minx) * xinterval - xinterval);
maxx= (long) (xstart + (float) (maxx) * xinterval);
*/
}
else
zoom = -1;
}
if (baseliner.DoBaseline == 'Y')
{
DoSpect(start, len, left, right, buf);
}
} /* end plot32 */
void Plot8( unsigned char * buf, unsigned char miny, unsigned char maxy,
int len, char * symbol, int color_flag, int top, int bottom,
int left, int right, int zoom, char Overlay)
/*** Plot8 plots a single array of 8-bit y-values against a running
index on the x-axis. The code provides for zooming in on a region
of interest, plotting with dots or lines and plotting in different
colors.
Original version - 3/31/89 AEE
Modified version - 8/90 AW3
Parameter Type In/out Description
buf uns ch ptr in The buffer containing the y data
miny uns char in The minimum y value to plot
maxy uns char in The maximum y value to plot
len int in The number of points in the y array
symbol char in Plotting symbol flag: 'D' for dots
anything else for line
color_flag int in Plotting color (index into current pal
or -1 if variable colors)
zoom int in Zoom flag: 0 if no zooming this time
1 if zooming desired (i.e., ask)
Overlay char in Overlay flag - 'Y' to overlay plot,
'N' to redraw whole thing
***/
{
int i, j, yaxisrev;
int adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
int line1, samp1, line2, samp2, line, samp;
int start = 0, tmplen = len, tmpdn = numDN;
int wave_flag, string_len;
int height, width;
int num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
int tic, tic_height=5, numbins;
int color;
long minx, maxx;
long tmpminy = miny, tmpmaxy = maxy;
long tmpminx = minx, tmpmaxx = maxx;
char bufmin[15], bufmax[15], xbufmin[15], xbufmax[15];
char ch='N', dispstr[64];
int scale_ydata;
int scale_color;
int yrange;
float pixperbin;
/* Find the actual starting and ending X values from the header, if
present */
minx = (long) xstart;
maxx = minx + (long)(len * xinterval);
/* Set display sizes in units of screen pixels */
height = bottom - top;
width = right - left;
right = left + width; /* reset right edge */
numbins = width;
pixperbin = (float)len / numbins;
tic = (numbins / 16) * pixperbin;
tic_height = dispnl / 100;
if (color_flag >= 0)
color = color_flag;
/* Top of the plotting loop - do this until no more zooming */
while (zoom >= 0)
{
yrange = maxy - miny;
if (yrange != 0)
{
scale_ydata = (100 * height) / yrange;
scale_color = (100 * numDN) / yrange ;
}
else
{
scale_ydata = 1;
scale_color = 1;
}
if (Overlay != 'Y')
{
FramePlot( top, bottom, left, right, minx, maxx, miny, maxy);
}
/* Set the starting points for the plot */
lowedge = bottom;
leftedge= left;
prevy = max( buf[0], miny);
prevy = lowedge - ((prevy - miny) * scale_ydata)/100;
prevx = left;
/* Loop over the points in the y array */
for (i=start; i<start+len; i++)
{
if(buf[i] <= maxy && buf[i] >= miny)
{
/* adjval to fall in plot range */
adjval = (buf[i]-miny) * scale_ydata/100;
if (color_flag == -1)
color = (buf[i]-miny) * scale_color/100;
/* make y-axis increase upward */
ycord = lowedge - adjval;
/* scales the length of X-axis (samples) correctly */
nextx = leftedge + ( ((long)(i-start) * (long)width) / len);
/* plot the next point */
if (strlen(symbol) == 0)
{
/* use lines; connect the points */
DrawLine(prevy, prevx, ycord, nextx, color);
prevy = ycord;
prevx = nextx;
}
else if (strstr(symbol, ".") != NULL)
WritePixel(ycord, nextx, color);
else
DrawText(symbol, ycord, nextx, 8, 0, color);
}
}
if (zoom == 2) /* We've already zoomed once */
{
minx = tmpminx;
miny = tmpminy;
maxx = tmpmaxx;
maxy = tmpmaxy;
len = tmplen;
start = 0;
numDN = tmpdn;
DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,numDN-1);
ch = getch();
}
if (zoom == 1) /* We haven't zoomed, and we want to */
{
ch = 'Y';
zoom = 2;
}
/* Either way, find the new endpoints and redraw the plot */
if (ch == 'y' || ch == 'Y')
{
/* clears the prompt line */
DrawText("Would you like to zoom again (y/n)? ", 10, 1, 8, 0, 0);
/* select the endpoints of the zoom */
DrawText(" Arrow keys move + around. +,- (in/de)crements cursor steps.",
10, 1, 8, 0,numDN-1);
LengthText("Hit Return to Select End Points", 8, &string_len);
DrawText("Hit Return to Select End Points",
dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
PlaceCursor(bottom+6, right/2, numDN-1);
MoveCursor(&line1, &samp1);
DrawText("*", line1+4, samp1-4, 8, 0, numDN-1);
MoveCursor(&line2, &samp2);
DrawText("*", line2+4, samp2-4, 8, 0, numDN-1);
/* clean up the screen */
RemoveCursor();
ClearDisplay(0);
/* watch for reversed endpoints */
if (samp1 > samp2)
{
i = samp2;
samp2 = samp1;
samp1 = i;
}
/* watch for values off the plot */
if (samp1 < left)
samp1 = left;
if (samp2 > right)
samp2 = right;
if (samp2 < left)
samp2 = left; /* both end points < minx of plot */
if (samp1 > right)
samp1 = right; /* both end points > maxx of plot */
/* set the new starting points */
start = ((long)(samp1 - left) * (long)len) / width;
len = ((long)(samp2 -samp1) * (long)len) / width;
if(len > 0)
{
/* X-axis range selected is > 0 */
minx = start+1;
maxx = len+start;
miny = 0x7fffffff;
maxy = 0x80000000;
/* new min and max for the plot */
for (i= start; i<start+len; i++)
{
if (buf[i] < miny)
miny= buf[i];
if (buf[i] > maxy)
maxy= buf[i];
}
prevy= lowedge - ((buf[start] - miny) * scale_ydata)/100;
prevx= leftedge;
}
else
{
/* selected X range is zero */
zoom = -1;
}
minx= (long) (xstart + (float) (minx) * xinterval - xinterval);
maxx= (long) (xstart + (float) (maxx) * xinterval);
}
else
zoom = -1;
}
if (baseliner.DoBaseline == 'Y')
{
DoSpect(start, len, left, right, (long *) buf);
}
} /* end plot8 */
void Plotpair(long * xbuf, long * ybuf, long minx, long maxx, long miny,
long maxy, int len, char * symbol, int color, int zoom)
/*** PlotPair plots two arrays of 32-bit values against each other. The
code provides for zooming in on a region of interest, plotting
with dots or lines and plotting in different colors.
Original version - 3/31/89 AEE
Modified version - 8/90 AW3
Parameter Type In/out Description
xbuf long ptr in The buffer containing the x data
ybuf long ptr in The buffer containing the y data
miny long in The minimum y value to plot
maxy long in The maximum y value to plot
len int in The number of points in the y array
symbol char in Plotting symbol flag: 'D' for dots
anything else for line
color int in Plotting color (index into current pal)
zoom int in Zoom flag: 0 if no zooming this time
1 if zooming desired (i.e., ask)
***/
{
int i, j, yaxisrev;
int adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
int line1, samp1, line2, samp2, line, samp;
int start = 0, x_right, x_width;
int tmplen = len, tmpdn = numDN;
long tmpminy = miny, tmpmaxy = maxy;
long tmpminx = minx, tmpmaxx = maxx;
char ybufmin[15], ybufmax[15], xbufmin[15], xbufmax[15];
float scale_xdata_to_screen;
float yrange, xrange;
char ch='N', dispstr[64];
int wave_flag, string_len;
int top, bottom, left, right, height, width;
int num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
int tic, tic_height=5, numbins;
float pixperbin;
top = dispnl / 10;
bottom = dispnl - top;
left = dispns / 10;
right = dispns - (dispns / 32);
height = bottom - top;
width = right - left;
right = left + width; /* reset right edge */
numbins = width;
pixperbin = (float)len / numbins;
tic = (numbins / 16) * pixperbin;
tic_height = dispnl / 100;
while (zoom >= 0)
{
yrange = (float) (maxy - miny) ;
if (yrange != 0)
scale_ydata_to_screen = ( (float) height) / yrange;
xrange= (float) (maxx - minx);
if (xrange != 0)
scale_xdata_to_screen= ((float) width)/xrange;
FramePlot( top, bottom, left, right, minx, maxx, miny, maxy);
/* draw box outline */
/* FrameBox( top, left, bottom, right, numDN-1, TRUE); */
/* Put in the tic marks */
/* for (i = 0; i <= num_Xtics; i++)
{
j = left + width*i/num_Xtics;
DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
}
for (i = 0; i <= num_Ytics; i++)
{
j = bottom - height*i/num_Ytics;
DrawLine (j, left, j, left-tic_height, numDN-1);
}
*/
/* write coordinates */
/*
sprintf(ybufmin, "%10.2G", (float)miny);
LengthText(ybufmin, 6, &string_len);
string_len = string_len + tic_height + 2;
DrawText(ybufmin, bottom+5, left-string_len, 6, 0, numDN-1);
sprintf(ybufmax, "%10.2G", (float)maxy);
LengthText(ybufmax, 6, &string_len);
string_len = string_len + tic_height + 2;
DrawText(ybufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
sprintf(xbufmin, "%ld", minx);
LengthText(xbufmin, 10, &string_len);
DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
sprintf(xbufmax, "%ld", maxx);
LengthText(xbufmax, 10, &string_len);
DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
DrawText(xunit, bottom+30, left+(width/2)-75, 15, 0, numDN-1);
DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
*/
lowedge = bottom;
leftedge= left;
prevy = max( ybuf[start], miny);
prevy = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
prevx = left;
for (i=start; i<start+len; i++)
{
if(ybuf[i] <= maxy && ybuf[i] >= miny)
{
/* adjval to fall in plot range */
adjval= (int) (((float) (ybuf[i]-miny)) * scale_ydata_to_screen);
/* make y-axis increase upward */
ycord= lowedge - adjval;
/* scales the length of X-axis(samples) correctly */
nextx= leftedge + (int) ( ((float) (xbuf[i] - minx)) * scale_xdata_to_screen);
if (strlen(symbol) == 0)
{
/* use lines; connect the points */
DrawLine(prevy, prevx, ycord, nextx, color);
prevy = ycord;
prevx = nextx;
}
else
DrawText(symbol, ycord, nextx, 8, 0, color);
}
}
if (zoom == 2) /* We've already zoomed once */
{
minx = tmpminx;
miny = tmpminy;
maxx = tmpmaxx;
maxy = tmpmaxy;
len = tmplen;
start = 0;
numDN = tmpdn;
DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,numDN-1);
ch = getch();
}
if (zoom == 1) /* We haven't zoomed, and we want to */
{
ch= 'Y';
zoom = 2;
}
if (ch == 'y' || ch == 'Y')
{
/*clears this line*/
DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,0);
DrawText(" Arrow keys move + around. +,- (in/de)crements cursor steps.",
10, 1, 8, 0,numDN-1);
LengthText("Hit Return to Select End Points", 8, &string_len);
DrawText("Hit Return to Select End Points",
dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
PlaceCursor(bottom+6,right/2,numDN-1);
MoveCursor(&line1,&samp1);
DrawText("*",line1+4,samp1-4,8,0,numDN-1);
MoveCursor(&line2,&samp2);
DrawText("*",line2+4,samp2-4,8,0,numDN-1);
RemoveCursor();
ClearDisplay(0);
if (samp1 > samp2)
{
i= samp2;
samp2= samp1;
samp1= i;
}
if (samp1 < left)
samp1 = left;
if (samp2 > right)
samp2 = right;
if (samp2 < left)
samp2 = left; /* both end points < minx of plot */
if (samp1 > right)
samp1 = right; /* both end points > maxx of plot */
start = (samp1-left) * ((float) len /(float)width);
len = (samp2-samp1) * ((float) len /(float)width);
if(len > 0)
{
/* X-axis range selected is > 0 */
minx = 0x7fffffff;
maxx = 0x80000000;
miny = 0x7fffffff;
maxy = 0x80000000;
for (i= start; i<start+len; i++)
{
if (xbuf[i] < minx)
minx = xbuf[i];
if (xbuf[i] > maxx)
maxx = xbuf[i];
if (ybuf[i] < miny)
miny = ybuf[i];
if (ybuf[i] > maxy)
maxy = ybuf[i];
}
prevy = lowedge - ((int) (((float) (ybuf[start] - miny)) * scale_ydata_to_screen));
prevx = leftedge - ((int) (((float) (xbuf[start] - minx)) * scale_xdata_to_screen));
}
else
{
/* selected X range is zero */
zoom = -1;
}
}
else
zoom = -1;
}
if (baseliner.DoBaseline == 'Y')
{
StatusLine(1, "Option not implemented for this data type");
}
} /* end Plotpair */
long min3arr( long * buf, int nvals)
/*
Finds the third smallest value in a 32-bit integer array
*/
{
long min1 = 0x7fffffff, min2 = 0x7fffffff, min3 = 0x7fffffff;
int i;
for ( i=0; i<nvals; i++)
{
if (buf[i] < min1)
{
min3 = min2;
min2 = min1;
min1 = buf[i];
}
else if (buf[i] < min2)
{
min3 = min2;
min2 = buf[i];
}
else if (buf[i] < min3)
{
min3 = buf[i];
}
}
if (nvals > 2)
return(min3);
else
return(min1);
}
long max3arr( long * buf, int nvals)
/*
Finds the third largest value in a 32-bit integer array
*/
{
long max1 = 0x80000000, max2 = 0x80000000, max3 = 0x80000000;
int i;
for ( i=0; i<nvals; i++)
{
if (buf[i] > max1)
{
max3 = max2;
max2 = max1;
max1 = buf[i];
}
else if (buf[i] > max2)
{
max3 = max2;
max2 = buf[i];
}
else if (buf[i] > max3)
{
max3 = buf[i];
}
}
if (nvals > 2)
return(max3);
else
return(max1);
}
int DoPlot()
/*
DoPlot performs the plot command. First the parameters are scanned.
Then the image is read in and plotted. Ordered pairs are plotted by
Plotpair, other data by Plot32.
*/
{
int wordbits=16, longbits=32;
int line, i, k, zoom, color, symbolflag, spectraflag;
int lineflag, ovlflag, zoomflag, minflag, maxflag, flag;
int top, bottom, left, right, hss;
char status[128], Symbol[2], PlotOvly;
long miny=0x7FFFFFFF, maxy=0x80000000;
long minx=0x7FFFFFFF, maxx=0x80000000;
long *buf32, *xbuf, *ybuf;
unsigned char *buffer;
int *intbuf;
GetKeywordSubcommand (CommandString, "OVE", &ovlflag);
if (ovlflag == 1)
{
/* OVErlay specified, don't clear the screen */
PlotOvly = 'Y';
}
else
{
ClearDisplay(0);
PlotOvly = 'N';
}
GetKeywordSubcommand (CommandString, "ZOO", &zoomflag);
if (zoomflag == 1)
zoom = 1;
else
/* ZOOm not specified, don't ask to zoom plot */
zoom = 0;
GetKeywordInteger (CommandString, "LIN", 1, &line, &lineflag);
if (line > nl || line < 1)
line = 1;
GetKeywordInteger (CommandString, "COL", numDN-1, &color, &lineflag);
GetKeywordLong (CommandString, "MIN", miny, &miny, &minflag);
GetKeywordLong (CommandString, "MAX", maxy, &maxy, &maxflag);
GetKeywordString (CommandString, "SYM", "", Symbol, &symbolflag);
GetKeywordInteger (CommandString, "SS", 0, &hss, &flag);
GetKeywordSubcommand (CommandString, "SPE", &spectraflag);
if (spectraflag >0)
baseliner.DoBaseline = 'Y';
if (PDSused == 1 && switched == 1 && ns == 1 && nl > 1)
{
/*PDS label used */
i = nl;
nl = ns;
ns = i;
}
/* Allocate enough memory for the 32-bit buffers */
if ((buf32 = (long *)malloc(4*ns)) == NULL)
{
FatalError("Not enough memory to run program");
}
if ( (ns == 2 || ns == 3) && bitsperpix == 32)
{
if ((xbuf = (long *)malloc(4*nl)) == NULL)
{
free(buf32);
FatalError("Not enough memory to run program");
}
if ((ybuf = (long *)malloc(4*nl)) == NULL)
{
free(xbuf);
free(buf32);
FatalError("Not enough memory to run program");
}
/* 32 bit samples, ordered pairs */
k = 0;
for (i = 0; i < nl; i++)
{
ReadLine (0, buf32, line, 1, ns, status);
if (BadStatus(status))
{
free(ybuf);
free(xbuf);
free(buf32);
return(0);
}
xbuf[i] = buf32[0];
ybuf[i] = buf32[1];
line++;
k++;
}
for (i=0; i<nl; i++)
{
if (xbuf[i] < minx)
minx = xbuf[i];
if (xbuf[i] > maxx)
maxx = xbuf[i];
}
if (minflag < 1)
{
miny = min3arr( ybuf, nl);
miny = miny + miny/10;
}
if (maxflag < 1)
{
maxy = max3arr( ybuf, nl);
maxy = maxy + maxy/10;
}
Plotpair( xbuf, ybuf, minx, maxx, miny, maxy, k, Symbol, color, zoom);
TextLine = TextHeight + 5; TextSample = 1;
free(ybuf);
free(xbuf);
free(buf32);
return(0);
}
if (ns != 2) /* images (not pairs) */
{
if (bitsperpix == 8) /* 8 bit images */
{
if ((buffer = malloc(ns)) == NULL)
{
FatalError("Not enough memory to run program");
}
ReadLine( 0, buffer, line, 1, ns, status);
if (BadStatus(status))
{
free (buffer);
free (buf32);
return(0);
}
ConvertLine( buffer, buf32, bitsperpix, longbits, ns, status);
free (buffer);
}
else if (bitsperpix == 16) /* 16 bit images */
{
if ((intbuf = malloc(2*ns)) == NULL)
{
FatalError("Not enough memory to run program");
}
ReadLine( 0, intbuf, line, 1, ns, status);
if (BadStatus(status))
{
free (intbuf);
free (buf32);
return(0);
}
ConvertLine( intbuf, buf32, bitsperpix, longbits, ns, status);
free (intbuf);
}
else if (bitsperpix == 32) /* 32 bit images */
{
ReadLine (0, buf32, line, 1, ns, status);
if (BadStatus(status))
{
free(buf32);
return(0);
}
}
if (minflag < 1)
{
miny = min3arr( buf32, ns);
miny = miny + miny/10;
}
if (maxflag < 1)
{
maxy = max3arr( buf32, ns);
maxy = maxy + maxy/10;
}
top = dispnl / 10;
bottom = dispnl - top;
left = dispns / 10;
right = dispns - (dispns / 32);
Plot32( buf32, miny, maxy, hss, ns, Symbol, color, top, bottom, left,
right, zoom, PlotOvly);
TextLine = TextHeight + 5; TextSample = 1;
free(buf32);
return(0);
}
}
int DoPerspect()
/*
DoPerspect performs the plot command. First the parameters are scanned.
Then the image is read in and plotted by Plot32.
*/
{
int wordbits=16, longbits=32;
int line, i, k, zoom, color;
int minflag, maxflag, flag, displayflag;
int start_line, imgline, start_sample;
int top, bottom, left, right, height, width;
char status[128], PlotOvly, Symbol[2], ch;
long miny=0x7FFFFFFF, maxy=0x80000000;
long minx=0x7FFFFFFF, maxx=0x80000000;
unsigned char min8, max8;
long *buf32;
void *buffer;
ClearDisplay(0);
/* Have MAX or MIN been specified? */
GetKeywordLong (CommandString, "MIN", miny, &miny, &minflag);
GetKeywordLong (CommandString, "MAX", maxy, &maxy, &maxflag);
GetKeywordInteger (CommandString, "SL", 1, &start_line, &flag);
if (start_line > nl || start_line < 1)
start_line = 1;
GetKeywordSubcommand (CommandString, "SCR", &displayflag);
start_sample = 0;
if (PDSused == 1 && switched == 1 && ns == 1 && nl > 1)
{
/*PDS label used */
i = nl;
nl = ns;
ns = i;
}
/* Allocate enough memory for the 32-bit buffer */
if ((buf32 = (long *)malloc(4*ns)) == NULL)
{
StatusLine(0, "Not enough memory to run program");
return;
}
/* Now allocate an 8- or 16-bit buffer, if that's the way the image is */
if (bitsperpix == 8) /* 8 bit images */
{
if ((buffer = (unsigned char *) malloc(ns)) == NULL)
{
StatusLine(0, "Not enough memory to run program");
free( buf32 );
return(-1);
}
}
if (bitsperpix == 16) /* 16 bit images */
{
if ((buffer = (int *) malloc(2*ns)) == NULL)
{
StatusLine(0, "Not enough memory to run program");
free( buf32 );
return(-1);
}
}
/* Set some initial plot parameters */
height = dispnl / 8;
width = min( dispns, ns ) - (dispns / 10);
left = 1;
right = width - (dispns / 32);
color = -1;
PlotOvly = 'Y';
zoom = 0;
top = 1;
bottom = height+1;
strcpy(Symbol, ".");
line = 1;
imgline = start_line;
/* Now, loop over the entire image, one line at a time */
while ((line<dispnl) && (bottom<dispnl) && (imgline<nl))
{
if (displayflag != -1)
{
GetLine( buffer, line, 1, dispns);
min8 = 0;
max8 = 255;
Plot8( buffer, min8, max8, ns, Symbol, color, top, bottom, left,
right, zoom, PlotOvly);
}
else if (bitsperpix == 8)
{
ReadLine (0, buffer, imgline, 1, ns, status);
min8 = 0;
max8 = 255;
Plot8( buffer, min8, max8, ns, Symbol, color, top, bottom, left,
right, zoom, PlotOvly);
}
else if (bitsperpix == 32) /* 32 bit images */
{
ReadLine (0, buf32, imgline, 1, ns, status);
if (BadStatus(status))
{
free(buf32);
return(-1);
}
if (minflag < 1)
{
miny = min3arr( buf32, ns);
miny = miny + miny/10;
}
if (maxflag < 1)
{
maxy = max3arr( buf32, ns);
maxy = maxy + maxy/10;
}
Plot32( buf32, miny, maxy, start_sample, ns, Symbol, color,
top, bottom, left, right, zoom, PlotOvly);
}
else if (bitsperpix == 16)
{
ReadLine( 0, buffer, imgline, 1, ns, status);
if (BadStatus(status))
{
free (buffer);
free (buf32);
return(-1);
}
ConvertLine( buffer, buf32, bitsperpix, longbits, ns, status);
if (minflag < 1)
{
miny = min3arr( buf32, ns);
miny = miny + miny/10;
}
if (maxflag < 1)
{
maxy = max3arr( buf32, ns);
maxy = maxy + maxy/10;
}
Plot32( buf32, miny, maxy, start_sample, ns, Symbol, color,
top, bottom, left, right, zoom, PlotOvly);
}
/*
keyboard abort added
*/
if (kbhit()) /* abort disp if keypressed mdm 2/19/88*/
{
if ((ch = getch()) == 0) ch = 0x80 | getch();
if (ch != 17) /* don't abort if cntl q */
{
bottom = dispnl;
abort_disp = 1;
}
}
line++;
top++;
bottom++;
imgline++;
}
if (RefreshLines > 0) /* Save to refresh buffer */
Screen2Refresh(); /* Ron Baalke - 07/91 */
TextLine = TextHeight + 5; TextSample = 1;
free(buf32);
free(buffer);
return(0);
}
void FramePlot(int top, int bottom, int left, int right, long minx,
long maxx, long miny, long maxy)
/*** FramePlot draws a box around the plot, puts in the tic marks and
the axes labels
Original version - 8/92 AW3, adapted from Plot32() and Plot8()
Parameter Type In/out Description
top int in
bottom int in
left int in
right int in
minx long in
maxx long in
miny int in
maxy int in
***/
{
char bufmin[15], bufmax[15], xbufmin[15], xbufmax[15];
int tic_height, width, height, i, j, string_len;
int num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
/* Calculate some useful quantities */
tic_height = dispnl / 100;
width = right - left;
height = bottom - top;
/* Draw box around the plot */
FrameBox( top, left, bottom, right, numDN-1, TRUE);
/* Draw in the tic marks */
for (i = 0; i <= num_Xtics; i++)
{
j = left + width*i/num_Xtics;
DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
}
for (i = 0; i <= num_Ytics; i++)
{
j = bottom - height*i/num_Ytics;
DrawLine (j, left, j, left-tic_height, numDN-1);
}
/* Label the axes and draw in plot and axis titles */
sprintf(bufmin, "%10.2G", (float)miny);
LengthText(bufmin, 6, &string_len);
string_len = string_len + tic_height + 2;
DrawText(bufmin, bottom+5, left-string_len, 6, 0, numDN-1);
sprintf(bufmax, "%10.2G", (float)maxy);
LengthText(bufmax, 6, &string_len);
string_len = string_len + tic_height + 2;
DrawText(bufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
sprintf(xbufmin, "%ld", minx);
LengthText(xbufmin, 10, &string_len);
DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
sprintf(xbufmax, "%ld", maxx);
LengthText(xbufmax, 10, &string_len);
DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
LengthText(xunit, 15, &string_len);
DrawText(xunit, bottom+30, left+(width-string_len)/2, 15, 0, numDN-1);
DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
return;
}
void NewZoomEndpoints( int * p_line1, int * p_samp1, int * p_line2,
int * p_samp2, int left, int right, int width,
int bottom)
{
int string_len;
int i;
/* select the endpoints of the zoom */
DrawText(" Arrow keys move + around. +,- (in/de)crements cursor steps.",
10, 1, 8, 0,numDN-1);
LengthText("Hit Return to Select End Points", 8, &string_len);
DrawText("Hit Return to Select End Points",
dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
PlaceCursor(bottom+6, right/2, numDN-1);
MoveCursor(p_line1, p_samp1);
DrawText("*", *p_line1+4, *p_samp1-4, 8, 0, numDN-1);
MoveCursor(p_line2, p_samp2);
DrawText("*", *p_line2+4, *p_samp2-4, 8, 0, numDN-1);
/* clean up the screen */
RemoveCursor();
ClearDisplay(0);
/* watch for reversed endpoints */
if (*p_samp1 > *p_samp2)
{
i = *p_samp2;
*p_samp2 = *p_samp1;
*p_samp1 = i;
}
/* watch for values off the plot */
if (*p_samp1 < left)
*p_samp1 = left;
if (*p_samp2 > right)
*p_samp2 = right;
if (*p_samp2 < left)
*p_samp2 = left; /* both end points < minx of plot */
if (*p_samp1 > right)
*p_samp1 = right; /* both end points > maxx of plot */
}