From decwrl!lll-winken!uunet!clyde.concordia.ca!jarvis.csri.toronto.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew Thu Dec 14 08:26:33 PST 1989 Article 92 of comp.sources.sun: Path: decwrl!lll-winken!uunet!clyde.concordia.ca!jarvis.csri.toronto.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) Newsgroups: comp.sources.sun Subject: v01i089: ALV - An Image Processing Toolkit, Part05/10 Message-ID: Date: 11 Dec 89 19:26:53 GMT Organization: Rutgers Univ., New Brunswick, N.J. Lines: 1639 Approved: mcgrew@aramis.rutgers.edu Submitted-by: everson@compsci.bristol.ac.uk Posting-number: Volume 1, Issue 89 Archive-name: alv/part05 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'doc/man/man1/dsp.1' <<'END_OF_FILE' X.TH DSP 1 "29th May 1989" X.SH NAME dsp \- display raster on SUN screen X.SH SYNOPSIS X.B dsp X[ X.B -c X] X[ X.B -b X] X[ X.BI -8 programname X] X[ X.B "infile" X] X.SH DESCRIPTION X.I Dsp displays an raster in a window on a SUN screen running X.I sunview (1). The filename of the image is displayed in the window's frame label. X.PP XFirstly, the program checks to see whether the raster has a colourmap associated with it. If it does the program uses it to display the raster, if not then X.I dsp assumes it is working with a greylevel image in which 0 represents white and the largest greylevel represents black. X.PP If the raster is a greylevel image, then program determines whether the workstation supports colour (so that it can simulate a greyscale display). If it does and the depth of the raster is greater than that of the screen's frame buffer then the raster is displayed together with window and level sliders. If the workstation is black & white and the image to be displayed is 8 bits deep, then the program simulates the 8 bits of greylevel intensity by using a user specified dithering technique to convert the raster to 1 bit deep before displaying it. See X.I "Using ALV on a Black and White Workstation" for further details. X.PP The window and level sliders displayed above a greylevel raster on a colour workstation are used to map the N bits of input raster onto the 8 bits of screen frame buffer. The X.I window setting is the number of greylevels of the input raster which are mapped into the 256 greylevels of the frame buffer and the X.I level setting is the position of the midpoint of this window in the input raster greylevels. Greylevels outside this window are mapped to be maximum or minimum greylevel of the screen frame buffer as appropriate. The initial setting of the level slider is equal to the mean greylevel of the input raster and the initial window is set to X512. X.PP Two scrollbars are associated with the raster, one vertical and the other horizontal. These can be used to scroll an undisplayed portion of the image onto the window display. If the window is resized, then the appropriate extra portions of the raster are also displayed. Thus, rasters of sizes larger than screen size can be usefully displayed. X.PP On a colour workstation, when the X.I dsp window is iconized a small sub-sampled copy of the displayed raster is used as its icon, provinding the displayed raster is more than 1 bit deep. X.PP Interactive thresholding of 8 bit deep rasters is available by combining the use of this program with X.I winlev8 (1) X.PP If any of the mouse buttons are pressed over the raster, then the coordinates of the mouse point together with the greylevel intensity of the original raster at that point is displayed in the frame label repeatedly, until the mouse is moved out of the X.I dsp window. X.SH OPTIONS X.PP The X.B -c and X.B -b options force the program to treat the workstation as being colour or black & white respectively. X.PP The X.BI -8 programname option specifies which program X.I dsp should invoke to convert rasters for display on a black & white workstation. The default program is X.I ras8to1 (1). Currently, other alternatives are X.I dither (1) , X.I rasfilter8to1 (1) X(see BUGS section below) and X.I halftone (1). Any program in the invoker's path which reads an 8 bit deep raster on its standard input and writes a 1 bit raster to its standard output can be used. X.PP X.I Dsp takes standard X.I sunview (1) options for positioning the window etc. X.PP The global option X.I "mono-override | mono-overwrite" allows the full 256 colourmap entries of an image to be used in the display of an image. In X.I dsp the 0, 254 and 255 entries of the colourmap are by default set to a monochrome colourmap so that the remainder of the screen is not obviously affected by displaying the raster. Pixels with these values in the colour map are set equal to the displayable value nearest them. Setting this option overrides this and allows the 0 and 255 colourmap entries to be set to the values intended for display of the image. X.SH FILES X.IP ~/.alv_profile Global switches and standard command line arguments for each tool. X.SH "ENVIROMENT VARIABLES" X.IP ALV If set, the pathname of an alternative profile. X.SH "SEE ALSO" X.BI alv (1) , X.BI sunview (1) , X.BI ras8to1 (1) , X.BI rasfilter8to1 (1) , X.BI dither (1) , X.BI halftone (1) , X.BI winlev8 (1) , X.BI winlev (1) , X.BI alv_profile (5) , X.BI rasterfile (5) , X.B "Using ALV on a Black and White Workstation". X.SH DIAGNOSTICS X.IP "Input depth not supported on this workstation" X.I Dsp can only display rasters of less than or equal to 8 bits deep on a black X& white workstation. X.IP "mem_create returned NULL" There was insufficient memory available to allocate space for an raster in memory. X.IP "Can't open file" The file does not have the correct access permissions to the file, or it does not exist. X.IP "Can't get file descriptor to write to child" You have too many windows open under X.I sunview (1). X.IP "Displaying Colour raster on black and white workstation" X.I dsp will attempt display the raster; however, only the 0 and 1 entries in the image will be displayed. X.SH BUGS There is a bug in the Sun program X.I rasfilter8to1 (1). On large (720x480x8 pixel) images it hangs. Suggested work-round is to use the X.I -8 option to specify some other program, such as X.I ras8to1 (1). END_OF_FILE if test 5380 -ne `wc -c <'doc/man/man1/dsp.1'`; then echo shar: \"'doc/man/man1/dsp.1'\" unpacked with wrong size! fi # end of 'doc/man/man1/dsp.1' fi if test -f 'doc/tutorial.ms' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'doc/tutorial.ms'\" else echo shar: Extracting \"'doc/tutorial.ms'\" \(3655 characters\) sed "s/^X//" >'doc/tutorial.ms' <<'END_OF_FILE' X.SH Tutorial X.LP This is a short simple tutorial to (hopefully) show you how to use the ALV toolkit commands and also how to interface to the toolkit when writing your own programs. A sample image is included in the distribution and this will be used to demonstrate a few of the toolkit's facilities. X.LP XFirst of all, decode the sample image, which has been encoded to permit its transfer via email. X.DS L In the images directory type "make" X.DE You should now have a file named "sample_image" in the directory. This image is a picture of University Walk in Bristol University, UK showing part of The Queen's Building (Engineering Faculty and home of the Computer Science Dept.) in the background. X.LP The screen display facilities of the toolkit only work in X.I Sunview at present, so X.DS L type "suntools" X.DE to enter X.I Sunview if you are not already in the windowing enviroment. X.LP To display the image on the screen of your workstation X.DS L type "dsp sample_image" X.DE and the image will be displayed on your screen. THe program dsp checks to see whether you are running the toolkit on a colour or on a black & white Sun Workstation and displays using 256 Greylevels or a dithering technique as appropriate. To exit the display program it will have to be killed by pressing the right mouse button on the top black frame bar of the image and selecting the "Quit" menu entry. X.LP To show a histogram of the greylevels present in an image use the "hist" command. For example, X.DS L type "hist sample_image" X.DE to show the histogram plot of the sample image. Some additional data is written to the invoking window (via the standard error stream). X.LP To convolve the sample image with a linear filter, say a Laplacian filter, and then to display the results X.DS L type "convolve -flap1 -e sample_image | dsp" X.DE The "-f" option states which filter to use and the "-e" option tells the convolve program to use enhanced scaling on the output. (Basically this involves another pass over the image to stretch the Greylevel range in the output to the maximum available). X.LP This command line also demonstrates one of the main design features of the X.I ALV toolkit - communication between processes via Unix pipes. The X"|" symbol above connects the ouput of the "convolve" command (the convolved image) with the input of the "dsp" command with the net result of dislaying the convolved image on the screen. Most of the toolkit's commands can be joined together like this and there is no X(theoretical) limit to the number of commands that can be linked in this way. For example, typing X.DS L X"convolve -fxdiff1 -e sample_image | rasrange -l64 -h192 | rasscale -s0.5 | dsp" X.DE causes the sample image to be convolved with a 5*5 X-differentiating linear filter with enhanced scaling, then ranged so that what was greylevel 64 becomes greylevel 0 and what was greylevel 192 becomes greylevel 255, scaled to half size and then displayed on the screen. Far more complex piplines than this can be constructed! For further information about using the commands consult the X.I ALV command manual pages. X.LP If you wish to construct your own tools, the file X.I src/generic.c may be usefully used as a template. This contains all the code necessary for accessing the X.I ~/.alv_profile , for parsing the command-line arguments and for reading the raster into memory. To compile this requires the files X.I src/defs.h and X.I src/support.h together with the X.I pixrect library X.I lpixrect . If you do write any other filters which you find useful, please consider mailing them to me so that I can redistribute them to other users of the toolkit. END_OF_FILE if test 3655 -ne `wc -c <'doc/tutorial.ms'`; then echo shar: \"'doc/tutorial.ms'\" unpacked with wrong size! fi # end of 'doc/tutorial.ms' fi if test -f 'src/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/Makefile'\" else echo shar: Extracting \"'src/Makefile'\" \(5249 characters\) sed "s/^X//" >'src/Makefile' <<'END_OF_FILE' X#Modify the following to point to your desired installation points BINDIR=/usr/local/alv/bin MANDIR=/usr/local/alv/doc/man XFILDIR=/usr/local/alv/filters X X#You might want to change this to rasfilter8to1, but ras8to1 is better! XFILTER8TO1=$(BINDIR)/ras8to1 X X#Sensible values of COMPILE_FLAGS are -g or -O X#NB It must be called COMPILE_FLAGS here and not CFLAGS! X#COMPILE_FLAGS=-g COMPILE_FLAGS=-O X X########################################################## X# You shouldn't need to modify anything below this point # X# Type: # X# 'make' to make tools standalone in place # X# 'make install' to make tools standalone and install # X########################################################## X WLIBS = support.o -lsuntool -lsunwindow -lpixrect -lm LIBS = support.o -lpixrect -lm X PROGS = convert dither rasthresh winlev dsp rasregion equalise ffill hist im2ras \ X ras2im ras2lw invert rasval blend rasrange halftone box rasinfo scr2ras \ X winlev8 rasscale transform convolve ras2array array2ras hough palettetool \ X cst rasremap scrload ras8to1 fconvolve glass X CFLAGS=$(COMPILE_FLAGS) -DSTANDALONE X all: $(PROGS) X glass: glass.o X cc $(CFLAGS) -o glass glass.o -lsuntool -lsunwindow -lpixrect -lm X ras8to1: ras8to1.o support.o X cc $(CFLAGS) -o ras8to1 ras8to1.o $(LIBS) X scrload: scrload.o support.o X cc $(CFLAGS) -o scrload scrload.o $(LIBS) X cst: cst.o support.o X cc $(CFLAGS) -o cst cst.o $(WLIBS) X rasremap: rasremap.o support.o X cc $(CFLAGS) -o rasremap rasremap.o $(LIBS) X palettetool: palettetool.o p_confirm.o p_init.o p_notif.o p_panel.o p_event.o support.o X cc $(CFLAGS) -o palettetool palettetool.o p_confirm.o p_init.o \ X p_notif.o p_panel.o p_event.o $(WLIBS) X hough: hough.o support.o X cc $(CFLAGS) -o hough hough.o $(LIBS) X array2ras: array2ras.o support.o X cc $(CFLAGS) -o array2ras array2ras.o $(LIBS) X convert: convert.o support.o X cc $(CFLAGS) -o convert convert.o $(LIBS) X fconvolve.o: fconvolve.c defs.h support.c X cc $(CFLAGS) -DFILTERS_DIR=\"$(FILDIR)\" -c fconvolve.c X fconvolve: fconvolve.o support.o dynamem.o X cc $(CFLAGS) fconvolve.o dynamem.o -o fconvolve $(LIBS) X convolve.o: convolve.c defs.h support.c X cc $(CFLAGS) -DFILTERS_DIR=\"$(FILDIR)\" -c convolve.c X convolve: convolve.o support.o dynamem.o X cc $(CFLAGS) convolve.o dynamem.o -o convolve $(LIBS) X dither: dither.o support.o X cc $(CFLAGS) -o dither dither.o $(LIBS) X transform: transform.o matrix.o dynamem.o support.o X cc $(CFLAGS) -o transform transform.o dynamem.o matrix.o $(LIBS) X rasthresh: rasthresh.o support.o X cc $(CFLAGS) -o rasthresh rasthresh.o $(LIBS) X winlev: winlev.o support.o X cc $(CFLAGS) -o winlev winlev.o $(LIBS) X dsp: dsp.o support.o X cc $(CFLAGS) -o dsp dsp.o $(WLIBS) X dsp.o: dsp.c defs.h X cc $(CFLAGS) -DFILTER8TO1=\"$(FILTER8TO1)\" -c dsp.c X rasregion: rasregion.o support.o X cc $(CFLAGS) -o rasregion rasregion.o $(LIBS) X equalise: equalise.o support.o X cc $(CFLAGS) -o equalise equalise.o $(LIBS) X ffill: ffill.o support.o X cc $(CFLAGS) -o ffill ffill.o $(LIBS) X hist: hist.o support.o X cc $(CFLAGS) -o hist hist.o $(WLIBS) X im2ras: im2ras.o support.o X cc $(CFLAGS) -o im2ras im2ras.o $(LIBS) X ras2im: ras2im.o support.o X cc $(CFLAGS) -o ras2im ras2im.o $(LIBS) X ras2lw: ras2lw.o support.o X cc $(CFLAGS) -o ras2lw ras2lw.o $(LIBS) X invert: invert.o support.o X cc $(CFLAGS) -o invert invert.o $(LIBS) X rasval: rasval.o support.o X cc $(CFLAGS) -o rasval rasval.o $(LIBS) X blend: blend.o support.o X cc $(CFLAGS) -o blend blend.o $(LIBS) X rasrange: rasrange.o support.o X cc $(CFLAGS) -o rasrange rasrange.o $(LIBS) X halftone: halftone.o support.o X cc $(CFLAGS) -o halftone halftone.o $(LIBS) X box: box.o support.o X cc $(CFLAGS) -o box box.o $(LIBS) X rasinfo: rasinfo.o support.o X cc $(CFLAGS) -o rasinfo rasinfo.o $(LIBS) X scr2ras: scr2ras.o X cc $(CFLAGS) -o scr2ras scr2ras.o $(WLIBS) X ras2array: ras2array.o X cc $(CFLAGS) -o ras2array ras2array.o $(LIBS) X winlev8: winlev8.o X cc $(CFLAGS) -o winlev8 winlev8.o $(WLIBS) X rasscale double half quarter third triple quad: rasscale.o support.o X cc $(CFLAGS) -o rasscale rasscale.o $(LIBS) X clean: X rm -f *.o *~ core X spotless: clean X rm -f $(PROGS) double half quarter third triple quad MANIFEST alvtools X install: all X @for i in ${PROGS}; do \ X (install -s $$i $(BINDIR)); \ X done X @rm -f $(BINDIR)/double; ln -s $(BINDIR)/rasscale $(BINDIR)/double X @rm -f $(BINDIR)/half; ln -s $(BINDIR)/rasscale $(BINDIR)/half X @rm -f $(BINDIR)/quarter; ln -s $(BINDIR)/rasscale $(BINDIR)/quarter X @rm -f $(BINDIR)/third; ln -s $(BINDIR)/rasscale $(BINDIR)/third X @rm -f $(BINDIR)/triple; ln -s $(BINDIR)/rasscale $(BINDIR)/triple X @rm -f $(BINDIR)/quad; ln -s $(BINDIR)/rasscale $(BINDIR)/quad X @if test ! -d $(MANDIR)/man1; then mkdir $(MANDIR)/man1;fi X @for i in ../doc/man/man1/*; do \ X (cp $$i $(MANDIR)/man1); \ X done X @if test ! -d $(MANDIR)/man3; then mkdir $(MANDIR)/man3;fi X @for i in ../doc/man/man3/*; do \ X (cp $$i $(MANDIR)/man3); \ X done X @if test ! -d $(MANDIR)/man5; then mkdir $(MANDIR)/man5;fi X @for i in ../doc/man/man5/*; do \ X (cp $$i $(MANDIR)/man5); \ X done X @if test ! -d $(FILDIR); then mkdir $(FILDIR);fi X @for i in ../filters/*; do \ X (cp $$i $(FILDIR)); \ X done X @echo 'Programs, manual pages and filters installed' X END_OF_FILE if test 5249 -ne `wc -c <'src/Makefile'`; then echo shar: \"'src/Makefile'\" unpacked with wrong size! fi # end of 'src/Makefile' fi if test -f 'src/convolve.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/convolve.c'\" else echo shar: Extracting \"'src/convolve.c'\" \(5296 characters\) sed "s/^X//" >'src/convolve.c' <<'END_OF_FILE' X#include X#include "defs.h" X X#define DEFAULT 0 X#define ENHANCED 1 X#define MANUAL 2 X#define SYMMETRIC 3 X typedef struct { X int **image; X short xsize, ysize; X int nflag, spos, sneg; X} FILTER; X char *progname; char *filename; Pixrect *pr1, *pr2; int scale_method; float scale; int offset; char *filtername; short max_enhanced = -32768, min_enhanced = 32767; int mfx, mfy; int levels; XFILTER *filter; X X#ifdef STANDALONE main(argc, argv, envp) X#else convolve_main(argc, argv, envp) X#endif X int argc; X char **argv; X char **envp; X{ X register int i, j; X FILTER *loadfilter(); X X scale_method = DEFAULT; X scale = 1.; X offset = 0; X filtername = strsave("non-specified"); X progname = strsave(argv[0]); X parse_profile(&argc, argv, envp); X X while ((gc = getopt(argc, argv, "sef:lm:M:")) != EOF) X switch (gc) { X case 's': X scale_method = SYMMETRIC; X break; X case 'e': X scale_method = ENHANCED; X break; X case 'f': X filtername = strsave(optarg); X break; X case 'l': X execlp("ls", "ls", "-C", FILTERS_DIR, 0); X exit(); X break; X case 'm': X scale_method = MANUAL; X scale = atof(optarg); X break; X case 'M': X scale_method = MANUAL; X offset = (int) atof(optarg); X break; X case '?': X errflag++; X break; X } X X if (errflag) X error((char *) 0, "Usage: %s: [-e] [-s] [-f filter] [-l] [-m manual_scale] [-M manual_offset] [infile] [outfile]", progname); X X for (stream = 0; optind < argc; stream++, optind++) X if (stream < 2 && strcmp(argv[optind], "-") != 0) X if (freopen(argv[optind], mode[stream], f[stream]) == NULL) X error("%s %s", PR_IO_ERR_INFILE, argv[optind]); X X filter = loadfilter(filtername); X X if ((pr1 = pr_load(stdin, NULL)) == NULL) X error(PR_IO_ERR_RASREAD); X X if (bitrestrict) X levels = calc_max(pr1)+1; X else X levels = MAXLEVEL(pr1->pr_depth); X X if ((pr2 = mem_create(pr1->pr_size.x, pr1->pr_size.y, pr1->pr_depth)) == NULL) X error("mem_create returned NULL"); X X mfx = filter->xsize / 2; X mfy = filter->ysize / 2; X X switch (scale_method) { X case DEFAULT: X calc_default_scale(); X one_pass(); X break; X case ENHANCED: X case SYMMETRIC: X two_pass(); X break; X case MANUAL: X one_pass(); X break; X } X X pr_dump(pr2, stdout, NULL, RT_STANDARD, 0); X} X XFILTER * loadfilter(name) X char *name; X{ X char buf[BUFSIZ]; X FILE *fp; X char *ep; X FILTER *filter; X int xsize, ysize, ival; X register int i, j; X char *getenv(); X X if ((ep = getenv("FILTERS")) == NULL) X strcpy(buf, FILTERS_DIR); X else X strcpy(buf, ep); X X strcat(buf, "/"); X strcat(buf, name); X X if (!(fp = fopen(buf, "r"))) X error("Couldn't open filter %s", name); X X fscanf(fp, "%d %d", &xsize, &ysize); X filter = (FILTER *) malloc(sizeof(FILTER)); X filter->image = (int **) dynamem(&(filter->image), sizeof(int), 2, ysize, xsize); X X filter->nflag = FALSE; X filter->xsize = xsize; X filter->ysize = ysize; X X for (j = 0; j < ysize; j++) X for (i = 0; i < xsize; i++) { X fscanf(fp, "%d", &ival); X filter->image[j][i] = ival; X if (ival < 0) { X filter->nflag = TRUE; X filter->sneg += ival; X } else X filter->spos += ival; X } X filter->sneg = abs(filter->sneg); X X return filter; X} calc_default_scale() X{ X if (filter->nflag) { X scale = (float) levels / (float) (MAX(filter->spos, filter->sneg) * 2); X offset = levels / 2; X } else { X scale = (float) levels / (float) (MAX(filter->spos, filter->sneg)); X offset = 0; X } X} one_pass() X{ X register int total; X register int fj, fi; X register int i, j; X X warning("scale = %g on input, offset = %d on output", scale, offset); X X for (j = 0; j < pr1->pr_size.y - filter->ysize; j++) X for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) { X total = 0; X for (fj = 0; fj < filter->ysize; fj++) X for (fi = 0; fi < filter->xsize; fi++) X total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]); X pr_put(pr2, i + mfx, j + mfy, truncate((int) ((float) total * scale) + offset, levels, 0)); X } X} two_pass() X{ X register int total; X register int least, most; X register int fj, fi; X register int i, j; X int tmppix; X Pixrect *tmp; X X if ((tmp = mem_create(pr1->pr_size.x, pr1->pr_size.y, 32)) == NULL) X error("mem_create returned NULL"); X X /* first pass */ X least = 32768; X most -= 32767; X for (j = 0; j < pr1->pr_size.y - filter->ysize; j++) X for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) { X total = 0; X for (fj = 0; fj < filter->ysize; fj++) X for (fi = 0; fi < filter->xsize; fi++) X total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]); X pr_put(tmp, i + mfx, j + mfy, total); X least = MIN(total, least); X most = MAX(total, most); X } X least = abs(least); X X /* calculate scale and offset */ X if (scale_method == SYMMETRIC) { X scale = (float) levels / (float) (MAX(least, most) * 2); X scale /= (filter->nflag) ? 2. : 1.; X offset = (filter->nflag) ? levels / 2 : 0; X } else { /* enhanced */ X scale = (float) levels / (float) (least + most); X offset = (filter->nflag) ? least * scale : 0; X } X X warning("scale = %g on filter, output offset = %d on output", scale, offset); X X /* second pass */ X for (j = 0; j < pr1->pr_size.y - filter->ysize; j++) X for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) { X tmppix = truncate((int) ((float) pr_get(tmp, i, j) * scale + offset), levels, 0); X pr_put(pr2, i, j, tmppix); X } X} END_OF_FILE if test 5296 -ne `wc -c <'src/convolve.c'`; then echo shar: \"'src/convolve.c'\" unpacked with wrong size! fi # end of 'src/convolve.c' fi if test -f 'src/dynamem.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/dynamem.c'\" else echo shar: Extracting \"'src/dynamem.c'\" \(4401 characters\) sed "s/^X//" >'src/dynamem.c' <<'END_OF_FILE' X#include X#include X X/* X * dynamem(p, s, d, dn, dn ....) allocates a d dimensional array, whose X * dimensions are stored in a list starting at d1. Each array element is X * of size s. p is a pointer with d levels of indirection to the memory area X */ X char *malloc(); X char * dynamem(va_alist) va_dcl X{ X va_list ap; /* varargs list traverser */ X int max, /* size of array to be declared */ X *q; /* pointer to dimension list */ X char **r, /* pointer to begining of the array of the X * pointers for a dimension */ X **s1, *t, *tree; /* base pointer to begining of first array */ X int i, /* loop counters */ X j; X char **p; /* pointer to memory area with d levels of indirection */ X int s, /* individual array element size */ X d; /* number of dimensions */ X int *d1; /* dimension list */ X X va_start(ap); X p = va_arg(ap, char**); X s = va_arg(ap,int); X d = va_arg(ap,int); X if ((d1 = (int *) malloc (sizeof(int) * d)) == NULL) X error("malloc returned NULL"); X X for(i=0;i'src/hist.c' <<'END_OF_FILE' X#include X#include X#include "defs.h" X static short histicon[] = X{ X#include "../images/icons/hist.icon" X}; DEFINE_ICON_FROM_IMAGE(icon, histicon); X X#define HSIZE 128 X#define HEADER 10 X#define BOTTOM 30 X#define BOXSIZE 3 X XFrame frame; Canvas canvas; Menu menu; Pixwin *pw; char *filename; double lhist[90000]; int hist[90000], n = 0; int greylevels; char *progname; int max_val, min_val; int winxsiz, winysiz; Pixrect *pr, *dpr; int vertical, logarithmic; int maxh; double lmaxh; X X#ifdef STANDALONE main(argc, argv, envp) X#else hist_main(argc, argv, envp) X#endif X int argc; X char **argv; X char **envp; X{ X register int i, j; X int len, dummy; X char *itoa(); X char message[BUFSIZ]; X char buf1[BUFSIZ]; X int c; X colormap_t colormap; X X filename = strsave("stdin"); X vertical = FALSE; X logarithmic = FALSE; X progname = strsave(argv[0]); X parse_profile(&argc, argv, envp); X X while ((gc = getopt(argc, argv, "W:lvb")) != EOF) X switch (gc) { X case 'l': X logarithmic = TRUE; X break; X case 'v': X vertical = TRUE; X break; X case 'b': X bitrestrict = TRUE; X break; X case '?': X errflag++; X break; X } X if (errflag) X error((char *) 0, "Usage: %s: [-l] [-v] [-b] [infile]\n", progname); X X for (stream = 0; optind < argc; stream++, optind++) X if (stream == 0 && strcmp(argv[optind], "-") != 0) { X filename = strsave(argv[optind]); X if (freopen(argv[optind], mode[stream], f[stream]) == NULL) X error("%s %s", PR_IO_ERR_INFILE, argv[optind]); X } X X if ((pr = pr_load(stdin, &colormap)) == NULL) X error(PR_IO_ERR_RASREAD); X X if (bitrestrict) X greylevels = calc_max(pr)+1; X else X greylevels = MAXLEVEL(pr->pr_depth); X X statistics(); X X calc_winsize(); X X sprintf(message, "%s: %s", (logarithmic) ? "logarithmic histogram" : "histogram", filename); X frame = window_create(NULL, FRAME, X FRAME_LABEL, message, X WIN_HEIGHT, winxsiz, X WIN_WIDTH, winysiz, X FRAME_ICON, &icon, X FRAME_ARGS, argc, argv, X 0); X canvas = window_create(frame, CANVAS, X CANVAS_HEIGHT, HSIZE + HEADER + BOTTOM, X CANVAS_WIDTH, greylevels * BOXSIZE + 10, X CANVAS_AUTO_SHRINK, FALSE, X WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0), X 0); X X dpr = mem_create(window_get(canvas, CANVAS_HEIGHT), X window_get(canvas, CANVAS_WIDTH), X 8); X X pw = canvas_pixwin(canvas); X X draw_histogram(pw); X X pw_vector(pw, 0, HSIZE + HEADER, greylevels * BOXSIZE, HSIZE + HEADER, PIX_SET, 1); X for (i = 0; i < greylevels; i++) { X len = (i % 100 == 0) ? 10 : X (i % 50 == 0) ? 10 : X (i % 10 == 0) ? 6 : X (i % 2 == 0) ? 2 : 0; X if (len) X pw_vector(pw, i * BOXSIZE, HSIZE + HEADER, i * BOXSIZE, HSIZE + HEADER + len, PIX_SET, 1); X if (i % 10 == 0) X pw_text(pw, i * BOXSIZE, HSIZE + HEADER + 17, PIX_SRC, smallfont, itoa(i)); X } X X window_main_loop(frame); X X exit(0); X} X calc_winsize() X{ X winxsiz = HSIZE + 28 + HEADER + BOTTOM; X if ((greylevels * BOXSIZE + 10) > 500) X winysiz = 500; X else X winysiz = greylevels * BOXSIZE + 10; X} X statistics() X{ X register int i, j; X double sumsq, stddev, mean; X int cumulate, count, val, sum, median, mode; X X sumsq = 0.; X sum = 0; X max_val = 0; X min_val = 10000; X X for (j = 0; j < pr->pr_size.y; j++) X for (i = 0; i < pr->pr_size.x; i++) { X val = pr_get(pr, i, j); X max_val = MAX(max_val, val); X min_val = MIN(min_val, val); X hist[val]++; X sumsq += (val * val); X sum += val; X } X n = pr->pr_size.y * pr->pr_size.x; X mean = (double) sum / (double) n; X stddev = sqrt(sumsq / (double) n - mean * mean); X X maxh = 0; X for (i = 0; i < greylevels; i++) X maxh = MAX(maxh, hist[i]); X X i = count = 0; X while (count < n / 2) X count += hist[i++]; X median = i - 1; X X X i = mode = cumulate = 0; X X for (i = 0; i < greylevels; i++) X if (hist[i] > cumulate) { X cumulate = hist[i]; X mode = i; X } X fprintf(stderr, "mean = %3g\n", mean); X fprintf(stderr, "median = %d\n", median); X fprintf(stderr, "mode = %d\n", mode); X fprintf(stderr, "std. dev. = %3g\n", stddev); X fprintf(stderr, "max pixel = %d\n", max_val); X fprintf(stderr, "min pixel = %d\n", min_val); X} X draw_histogram(pw) X Pixwin *pw; X{ X int temp, count, i, npts, dx, dy; X X npts = greylevels * 2 + 4; X dx = 0; X dy = HSIZE + HEADER; X X pw_batch_on(pw); X pw_vector(pw, dx, dy, i * BOXSIZE, dy - hist[0] * HSIZE / maxh, PIX_SRC, 1); X X if (logarithmic) X for (i = 0; i < greylevels; i++) { X lhist[i] = log((double) hist[i] + 1.0); /* add 1 to avoid log(0) */ X if (lmaxh < lhist[i]) X lmaxh = lhist[i]; X } X X for (i = 0; i < greylevels; i++) { X if (logarithmic) X temp = (int) (lhist[i] * HSIZE / lmaxh); X else X temp = hist[i] * HSIZE / maxh; X pw_vector(pw, i * BOXSIZE, dy - temp, (i + 1) * BOXSIZE, dy - temp, PIX_SRC, 1); X if (vertical) { X pw_vector(pw, i * BOXSIZE, dy - temp, i * BOXSIZE, dy, PIX_SET, 1); X pw_vector(pw, (i + 1) * BOXSIZE, dy - temp, (i + 1) * BOXSIZE, dy, PIX_SET, 1); X } X } X pw_batch_off(pw); X} END_OF_FILE if test 5232 -ne `wc -c <'src/hist.c'`; then echo shar: \"'src/hist.c'\" unpacked with wrong size! fi # end of 'src/hist.c' fi if test -f 'src/rasremap.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/rasremap.c'\" else echo shar: Extracting \"'src/rasremap.c'\" \(3647 characters\) sed "s/^X//" >'src/rasremap.c' <<'END_OF_FILE' X/**************************************************************************/ X/* Based on the program blend.c by Phill Everson, from the ALV version */ X/* 2.1 suite of public-domain image processing programs. */ X/* Program to read a rasterfile and (optionally) a lookup table (LUT) */ X/* file produced by the program cst. Using the values from either the */ X/* rasterfile's LUTs (=default) or the input LUTs, map pixel values to */ X/* their LUT equivalents, then substitute a 1:1 mapping LUT and write */ X/* out the file. This allows interactively thresholded and contrast */ X/* stretched images to be used in programs which ignore LUTs. */ X/* */ X/* ras_remap.c */ X/* */ X/* Bryan Dawson, Keele University Geography Dept. */ X/* 30/3/89 */ X/**************************************************************************/ X X#include X#include "defs.h" X char * progname; char * malloc(); int header[8]; unsigned char red[256],green[256],blue[256]; long filelen; unsigned char * image; X X#ifdef STANDALONE main(argc, argv, envp) X#else rasremap_main(argc, argv, envp) X#endif X int argc; X char **argv; X char **envp; X{ X register int x,y; X int lutfile = 0; X FILE *f1, *f2; X X f1 = stdin; X f2 = stdin; X progname = strsave(argv[0]); X parse_profile(&argc, argv, envp); X X while ((gc = getopt(argc, argv, "f:l:")) != EOF) X switch (gc) X { X case 'f': X if ((f1 = fopen(optarg, "r")) == NULL) X error("Can't open %s\n", optarg); X break; X case 'l': X if ((f2 = fopen(optarg, "r")) == NULL) lutfile = 0 ; X else lutfile = 1; X break; X case '?': X errflag++; X break; X } /* end switch */ X if (errflag) X error((char *) 0, "Usage: %s: [-f imgfile] [-l LUTfile] [outfile] \n", progname); X X/* read rasterfile header */ x = fread(header,sizeof(int),8,f1);; if (header[0] != 0x59a66a95) error("This isn't a Sun rasterfile !"); filelen = (long)header[4]; image = (u_char *)malloc(filelen); /* allocate space for image data */ X X/* if there is a LUT on the file, and it's needed, read it, else skip it */ if ((lutfile == 0) && (header[7] == 768)) X { X x = fread(red,1,256,f1); X x = fread(green,1,256,f1); X x = fread(blue,1,256,f1); X } else x = fseek(f1,header[7],1); X X/* read image data */ x = fread(image,1,filelen,f1); X X/* if external LUTs are to be used, read them */ if (lutfile == 1) X { X x = fread(red,1,256,f2); X x = fread(green,1,256,f2); X x = fread(blue,1,256,f2); X } X X/* if there is still no LUT, create a dummy one */ if ((lutfile == 0) && (header[6] == RMT_NONE)) X for (x=0;x<256;x++) red[x]=green[x]=blue[x] = x; X remap(); for (x=0;x<256;x++) red[x]=green[x]=blue[x] = x; writeit(); free(image); exit(); X} X X/* routine to map pixel values to their LUT equivalents */ remap() X{ register int temp; register long p; X for (p = 0L ; p < filelen ; p++) X { X temp = red[(int)*(image+p)]; X *(image+p) = temp; X } X} X X/* routine to write out the three components of a rasterfile */ writeit() X{ header[6] = 1;/* RMT_EQUAL_RGB */ header[7] = 768; fwrite(header,4,8,stdout); fwrite(red,1,256,stdout);/* greyscale image */ fwrite(red,1,256,stdout); fwrite(red,1,256,stdout); fwrite(image,1,filelen,stdout); X} X X END_OF_FILE if test 3647 -ne `wc -c <'src/rasremap.c'`; then echo shar: \"'src/rasremap.c'\" unpacked with wrong size! fi # end of 'src/rasremap.c' fi if test -f 'src/scr2ras.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/scr2ras.c'\" else echo shar: Extracting \"'src/scr2ras.c'\" \(3964 characters\) sed "s/^X//" >'src/scr2ras.c' <<'END_OF_FILE' X/* X * Modified and renamed src2ras, 1988 by Phill Everson for inclusion into ALV X * toolkit. X * X * dumpregion - dump a region of a sun screen in rasterfile format. Copyright X * Richard Tobin 1987. You may freely copy, modify and distribute this X * program in source form provided this comment remains intact. X * X * Richard Tobin, JANET: R.Tobin@uk.ac.ed AI X * Applications Institute, ARPA: R.Tobin%uk.ac.ed@nss.cs.ucl.ac.uk X * Edinburgh University. UUCP: ...!ukc!ed.ac.uk!R.Tobin X */ X X#include "defs.h" X#include X#include X char *progname; X short nwdata[] = { X#include "../images/cursors/stretchNW.cursor" X}; mpr_static(nwpixrect, 16, 16, 1, nwdata); X short sedata[] = { X#include "../images/cursors/stretchSE.cursor" X}; mpr_static(sepixrect, 16, 16, 1, sedata); X Rect rect = {0, 0, 0, 0}; X colormap_t *colormap = NULL; X X#ifdef STANDALONE main(argc, argv, envp) X#else scr2ras_main(argc, argv, envp) X#endif X int argc; X char **argv; X char **envp; X{ X int wfd; X struct fullscreen *fs; X Event event; X Pixwin *pw; X int left, right, top, bottom, temp; X Window win; X double w; X X progname = strsave(argv[0]); X parse_profile(&argc, argv, envp); X X while ((gc = getopt(argc, argv, " ")) != EOF) X switch (gc) { X case '?': X errflag++; X break; X } X X if (errflag) X error((char *) 0, "Usage: %s: [outfile]\n", progname); X X for (stream = 0; optind < argc; stream++, optind++) X if (stream ==0 && strcmp(argv[optind], "-") != 0) X if (freopen(argv[optind],"w" ,stdout) == NULL) X error("%s %s", PR_IO_ERR_INFILE, argv[optind]); X X win = window_create(0, FRAME, X FRAME_OPEN_RECT, &rect, X WIN_CONSUME_PICK_EVENTS, X LOC_MOVE, WIN_MOUSE_BUTTONS, 0, X 0); X X wfd = (int) window_get(win, WIN_FD); X fs = fullscreen_init(wfd); X pw = fs->fs_pixwin; X X window_set(win, X WIN_CURSOR, cursor_create(CURSOR_IMAGE, &nwpixrect, X CURSOR_XHOT, 0, CURSOR_YHOT, 0, X 0), X 0); X X while (window_read_event(win, &event) == -1 || X !event_is_down(&event) || X !event_is_button(&event)); X X right = left = event_x(&event); X bottom = top = event_y(&event); X X window_set(win, X WIN_CURSOR, cursor_create(CURSOR_IMAGE, &sepixrect, X CURSOR_XHOT, 15, CURSOR_YHOT, 15, X 0), X 0); X X drawbox(pw, left, top, right, bottom); X X while (window_read_event(win, &event) == -1 || X !event_is_up(&event) || X !event_is_button(&event)) { X drawbox(pw, left, top, right, bottom); X right = event_x(&event); X bottom = event_y(&event); X drawbox(pw, left, top, right, bottom); X } X X drawbox(pw, left, top, right, bottom); X fullscreen_destroy(fs); X X window_set(win, FRAME_NO_CONFIRM, TRUE, 0); X window_destroy(win); X X if (right < left) { X temp = right; X right = left; X left = temp; X } X if (bottom < top) { X temp = bottom; X bottom = top; X top = temp; X } X dumpregion(left, top, right, bottom); X X return 0; X} X drawbox(pw, left, top, right, bottom) X Pixwin *pw; X int left, top, right, bottom; X{ X fullscreen_pw_vector(pw, left, top, right, top, PIX_NOT(PIX_DST), 0); X fullscreen_pw_vector(pw, right, top, right, bottom, PIX_NOT(PIX_DST), 0); X fullscreen_pw_vector(pw, right, bottom, left, bottom, PIX_NOT(PIX_DST), 0); X fullscreen_pw_vector(pw, left, bottom, left, top, PIX_NOT(PIX_DST), 0); X} X dumpregion(left, top, right, bottom) X int left, top, right, bottom; X{ X Pixrect *pr, *pr2, *pr3; X int width, height; X X X pr = pr_open("/dev/fb"); X if (pr == 0) X error("Can't open /dev/fb"); X X width = (((right - left + 1) / 8) * 8); X height = (((bottom - top + 1) / 4) * 4); X pr2 = pr_region(pr, left, top, width, height); X pr3 = pr_region(pr2, 0, 0, width, height); X X if (pr_dump(pr3, stdout, colormap, RT_STANDARD, 1) != 0) { X perror("pr_dump"); X exit(1); X } X} END_OF_FILE if test 3964 -ne `wc -c <'src/scr2ras.c'`; then echo shar: \"'src/scr2ras.c'\" unpacked with wrong size! fi # end of 'src/scr2ras.c' fi if test -f 'src/transform.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/transform.c'\" else echo shar: Extracting \"'src/transform.c'\" \(5625 characters\) sed "s/^X//" >'src/transform.c' <<'END_OF_FILE' X#include X#include "defs.h" X#include "matrix.h" X char *progname; char *filename; Pixrect *pr1, *pr2; X X#ifdef STANDALONE main(argc, argv, envp) X#else transform_main(argc, argv, envp) X#endif X int argc; X char **argv; X char **envp; X{ X register int i, j; X float a, xs, ys; X int x, y; X int rotation, shearing; X int levels; X int max_xsize, min_xsize, max_ysize, min_ysize, tr_xsize, tr_ysize; X VECTOR start, stop; X VECTOR tr_start, tr_stop; X VECTOR top_left, top_right, bottom_left, bottom_right; X VECTOR tr_top_left, tr_top_right, tr_bottom_left, tr_bottom_right; X MATRIX transform; X colormap_t colormap; X X warning("THIS CODE STILL UNDER DEVELOPMENT\nDO NOT TRUST"); X a = M_PI / 2.; X xs = ys = 0.; X x = y = 0; X rotation = shearing = FALSE; X progname = strsave(argv[0]); X parse_profile(&argc, argv, envp); X X while ((gc = getopt(argc, argv, "X:Y:a:x:y:")) != EOF) X switch (gc) { X case 'x': X if (!shearing) { X rotation = TRUE; X x = atoi(optarg); X } else X error("Cannot rotate and shear in same invocation"); X break; X case 'y': X if (!shearing) { X rotation = TRUE; X y = atoi(optarg); X } else X error("Cannot rotate and shear in same invocation"); X break; X case 'a': X if (!shearing) { X rotation = TRUE; X a = atof(optarg); X } else X error("Cannot rotate and shear in same invocation"); X break; X case 'X': X if (!rotation) { X shearing = TRUE; X xs = atof(optarg); X } else X error("Cannot rotate and shear in same invocation"); X break; X case 'Y': X if (!rotation) { X shearing = TRUE; X ys = atof(optarg); X } else X error("Cannot rotate and shear in same invocation"); X break; X case '?': X errflag++; X break; X } X X if (errflag) X error((char *) 0, "Usage: %s: [[-x xcoord] [-y ycoord] [-a angle]] | [[-X xshear] [-Y yshear]] [infile] [outfile]\n", progname); X X for (stream = 0; optind < argc; stream++, optind++) X if (stream < 2 && strcmp(argv[optind], "-") != 0) X if (freopen(argv[optind], mode[stream], f[stream]) == NULL) X error("%s %s", PR_IO_ERR_INFILE, argv[optind]); X X if ((pr1 = pr_load(stdin, &colormap)) == NULL) X error(PR_IO_ERR_RASREAD); X X top_left = vinit(0., 0., 0., 1.); X top_right = vinit((double) pr1->pr_size.x, 0., 0., 1.); X bottom_right = vinit((double) pr1->pr_size.x, (double) pr1->pr_size.y, 0., 1.); X bottom_left = vinit(0., (double) pr1->pr_size.y, 0., 1.); X X warning("top_left = "); X dbgvprint(top_left); X warning("top_right = "); X dbgvprint(top_right); X warning("bottom_right = "); X dbgvprint(bottom_right); X warning("bottom_left = "); X dbgvprint(bottom_left); X X if (rotation) X transform = minit(cos(a), sin(a), 0., 0., -sin(a), cos(a), 0., 0., (1 - cos(a)) * x + y * sin(a), (1 - cos(a)) * y - x * sin(a), 1., 0., 0., 0., 0., 1.); X else X transform = minit(1., ys, 0., 0., xs, 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.); X X dbgmprint(transform); X tr_top_left = vnil(); X tr_top_right = vnil(); X tr_bottom_left = vnil(); X tr_bottom_right = vnil(); X X vmult(top_left, transform, tr_top_left); X vmult(top_right, transform, tr_top_right); X vmult(bottom_left, transform, tr_bottom_left); X vmult(bottom_right, transform, tr_bottom_right); X X warning("tr_top_left = "); X dbgvprint(tr_top_left); X X warning("tr_top_right = "); X dbgvprint(tr_top_right); X X warning("tr_bottom_right = "); X dbgvprint(tr_bottom_right); X X warning("tr_bottom_left = "); X dbgvprint(tr_bottom_left); X X max_xsize = (int) MAX(tr_top_left[0], tr_top_right[0]); X max_xsize = (int) MAX(max_xsize, tr_bottom_left[0]); X max_xsize = (int) MAX(max_xsize, tr_bottom_right[0]); X X min_xsize = (int) MIN(tr_top_left[0], tr_top_right[0]); X min_xsize = (int) MIN(min_xsize, tr_bottom_left[0]); X min_xsize = (int) MIN(min_xsize, tr_bottom_right[0]); X X max_ysize = (int) MAX(tr_top_left[1], tr_top_right[1]); X max_ysize = (int) MAX(max_ysize, tr_bottom_left[1]); X max_ysize = (int) MAX(max_ysize, tr_bottom_right[1]); X X min_ysize = (int) MIN(tr_top_left[1], tr_top_right[1]); X min_ysize = (int) MIN(min_ysize, tr_bottom_left[1]); X min_ysize = (int) MIN(min_ysize, tr_bottom_right[1]); X X tr_xsize = abs(max_xsize - min_xsize); X tr_ysize = abs(max_ysize - min_xsize); X X warning("xsize = %d, ysize = %d", tr_xsize, tr_ysize); X warning("minxsize = %d, min_ysize = %d", min_xsize, min_ysize); X X if ((pr2 = mem_create(tr_xsize, tr_ysize, pr1->pr_depth)) == NULL) X error("mem_create returned NULL"); X X tr_start = vnil(); X tr_stop = vnil(); X for (j = 0; j < pr1->pr_size.y; j++) { X start = vinit(0., (double) j, 0., 1.); X stop = vinit((double) (pr1->pr_size.x), (double) j, 0., 1.); X vmult(start, transform, tr_start); X tr_start[0] += abs(min_xsize); X tr_start[1] += abs(min_ysize); X vmult(stop, transform, tr_stop); X tr_stop[0] += abs(min_xsize); X tr_stop[1] += abs(min_ysize); X bres_line((int) tr_start[0], (int) tr_start[1], (int) tr_stop[0], (int) tr_stop[1], j); X } X X pr_dump(pr2, stdout, &colormap, RT_STANDARD, 0); X} X#define SIGN(a) ((a<0)?-1:((a>0)?1:0)) X X/* line end pts are (x1, y1) & (x2, y2). Assumed not equal */ bres_line(x1, y1, x2, y2, iny) X int x1, y1, x2, y2, iny; X{ X register int i; X int temp; X int x, y; X int dx, dy, s1, s2, e, interchange; X X x = x1; X y = y1; X dx = abs(x2 - x1); X dy = abs(y2 - y1); X s1 = SIGN(x2 - x1); X s2 = SIGN(y2 - y1); X X if (dy > dx) { X temp = dx; X dx = dy; X dy = temp; X interchange = FALSE; X } else X interchange = TRUE; X X e = 2 * dy - dx; X X for (i = 0; i < dx; i++) { X pr_put(pr2, x, y, pr_get(pr1, i, iny)); X while (e >= 0) { X if (interchange) X x += s1; X else X y += s2; X e -= 2 * dx; X } X if (interchange) X y += s2; X else X x += s1; X e += 2 * dy; X } X} END_OF_FILE if test 5625 -ne `wc -c <'src/transform.c'`; then echo shar: \"'src/transform.c'\" unpacked with wrong size! fi # end of 'src/transform.c' fi echo shar: End of archive 5 \(of 10\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 10 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0