[comp.sources.sun] v01i088: ALV - An Image Processing Toolkit, Part04/10

mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (12/12/89)

Submitted-by: everson@compsci.bristol.ac.uk
Posting-number: Volume 1, Issue 88
Archive-name: alv/part04



#! /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 <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 10)."
# Contents:  doc/introduction.ms doc/man/man1/alv.1
#   doc/man/man1/convolve.1 doc/man/man1/palettetool.1
#   doc/man/man3/dynamem.3 doc/man/man3/matrix.3 src/Makefile-merge
#   src/matrix.c src/p_main.c src/palettetool.c src/ras2lw.c
#   src/support.c src/winlev.c
# Wrapped by everson@kukini on Tue Oct 17 07:45:09 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'doc/introduction.ms' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/introduction.ms'\"
else
echo shar: Extracting \"'doc/introduction.ms'\" \(2945 characters\)
sed "s/^X//" >'doc/introduction.ms' <<'END_OF_FILE'
X.SH 
Introduction
X.SH 1
Overview
X.PP
This is to introduce a toolkit of image processing programs,
collectively called the 
X.B ALV 
toolkit for historical reasons, written by 
X.I "Phill Everson"
X<everson@uk.ac.bris.cs>
in the Computer Science Dept. of Bristol University, United Kingdom.
X.PP
The toolkit is designed to aid image processing work on Sun
workstations.  It is intended to be easy to use, though not restrictive
to experienced users, user-configurable, extensible and flexible.  For
example the toolkit will work on both black and white and colour
workstations and in either case will transparently, to the user,
display an image to the best of its ability on the screen.
X.PP
The toolkit is made up of a number of tools. These include
programs to display an image on the screen, to display a histogram, to
perform histogram equalisation, to threshold, to print an image on an
Apple Laserwriter, to invert an image and to convolve an image with a
user-supplied linear filter. Currently, there are about 30 such programs.
X.PP
The toolkit uses the standard Sun rasterfile format to store its images
allowing multiple depth images to be processed by the same toolkit and
easy migration of data between packages.
X.PP
The toolkit was initially written to fulfill a need at Bristol
University for a single coherent set of tools to support basic image
processing research on a variety of projects. We had found that each
user or group of users was writing their own copy of programs to do
similar things, like displaying an image on the screen, and more
importantly, in an enviroment were disk space is always at a premium,
was each keeping separate copies of these often large programs.  
X.PP
Using a coherent set of tools with a consistent file format has
substantially increased cross-project communication and in addition has
provided a higher starting point on the learning curve for novice
Sun-Users/Imagers. We have found that users generally use the core
tools as a basis and are then able to concentrate their work in their
own area of interest.
X.SH 1
History
X.PP
The first version of the toolkit was written in June-September, 1987 by
Phill Everson at the suggestion of Barry Thomas. The kit was rewritten
and substantially expanded in October-November, 1987 with help from
Gareth Waddell (notably for the dynamic array library) and version
X1.0.0 was released to the comp.sources.misc newsgroup of USENET in
XFebruary, 1988. Approximately 30 groups of users actively used the
system during 1988 and in December, 1988 another rewrite was begun
producing version 2.0.0 ready for its release to comp.sources.unix,
Sun-Spots, CVNET and Vision-Digest in mid-January, 1989.
X.SH 1
Uses at Bristol
X.PP
To date, the toolkit has been used at Bristol for Autonomous Land
Vehicle research (ALV, obviously), Aeronautical Fluid Flow measurement,
Medical Image Processing, Sign Language Decoding, Number Plate
Recognition and document preparation.
END_OF_FILE
if test 2945 -ne `wc -c <'doc/introduction.ms'`; then
    echo shar: \"'doc/introduction.ms'\" unpacked with wrong size!
fi
# end of 'doc/introduction.ms'
fi
if test -f 'doc/man/man1/alv.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/man/man1/alv.1'\"
else
echo shar: Extracting \"'doc/man/man1/alv.1'\" \(3463 characters\)
sed "s/^X//" >'doc/man/man1/alv.1' <<'END_OF_FILE'
X.TH ALV 1 "29th May 1989"
X.SH NAME
alv \- ALV image procesing toolkit
X.SH INTRODUCTION
The 
X.I ALV
toolkit is designed to aid image processing work on Sun
workstations.  It is intended to be easy to use, though not restrictive
to experienced users, user-configurable, extensible and flexible.  For
example the toolkit will work on both black and white and colour
workstations and in either case will transparently, to the user,
display an image to the best of its ability on the screen.
X.PP
The toolkit is made up of a number of tools. These include programs to
display an image on the screen, to display a histogram, to perform
histogram equalisation, to threshold, to print an image on an Apple
Laserwriter, to invert an image and to convolve an image with a
user-supplied linear filter. Currently, there are 32 such programs.
X.PP
The toolkit uses the standard Sun rasterfile format to store its images
allowing multiple depth images to be processed by the same toolkit and
easy migration of data between packages.
X.SH DESCRIPTION
X.LP
array2ras \- convert array to raster
X.LP 
blend \- blend two rasters together
X.LP
box \- box a raster
X.LP
convert \- convert textual raster to raster
X.LP
convolve \- convolve a raster with a linear integer filter
X.LP  
cst \- interactive contrast stretching of a raster
X.LP
dither \- convert 8 bit raster to 1 bit using dither matrix
X.LP
dsp	\- display a raster on screen
X.LP 
equalise \- equalise a raster
X.LP
fconvolve \- convolve a raster with a linear non-integer filter
X.LP
ffill \- flood fill a raster
X.LP
glass \- interactive onscreen zoooming
X.LP
halftone \- convert an 8 bit raster to 1 bit using bitmap font
X.LP
hist \- display histogram of raster
X.LP
hough \- perform hough transform
X.LP
im2ras \- convert old 
X.I ALV
format to raster
X.LP
invert \- invert the pixels in a raster
X.LP
palettetool \- interactive colourmap editor
X.LP
ras2array \- convert raster to array
X.LP
ras2im \- convert raster to old
X.I ALV 
format
X.LP
ras2lw \- output a raster on a Laserwriter
X.LP
ras8to1 \- perform various diffusion/dither algorithms
X.LP
rasinfo \- print raster udimensions and depth
X.LP
rasrange \- range a raster's greylevels
X.LP
rasregion \- clip a raster to a region
X.LP
rasremap \- LUT modification of a raster
X.LP
rasscale \- scale a raster's size by a scaling-factor
X.LP
rasthresh \- threshold raster
X.LP
rasval \- print pixel values of raster   
X.LP
scr2ras \- interactive screendump to raster
X.LP
scrload \- screenload, but more entertaining
X.LP
transform \- shear or rotate a raster
X.LP
winlev \- convert N bit deep raster to 8 bits deep
X.LP
winlev8 \- interactively change window and level of a displayed raster
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 array2ras (1) ,
X.BI blend (1) ,
X.BI box (1) ,
X.BI convert (1) ,
X.BI cst (1) ,
X.BI dither (1) ,
X.BI dsp (1) ,
X.BI equalise (1) ,
X.BI ffill (1) ,
X.BI glass (1) ,
X.BI halftone (1) ,
X.BI hist (1) ,
X.BI hough (1) ,
X.BI im2ras (1) ,
X.BI invert (1) ,
X.BI palettetool (1) ,
X.BI ras2array (1) ,
X.BI ras2im (1) ,
X.BI ras2lw (1) ,
X.BI ras8to1 (1) ,
X.BI rasinfo (1) ,
X.BI rasrange (1) ,
X.BI rasregion (1) ,
X.BI rasremap (1) ,
X.BI rasscale (1) ,
X.BI rasthresh (1) ,
X.BI rasval (1) ,
X.BI scr2ras (1) ,
X.BI scrload (1) ,
X.BI transform (1) ,
X.BI winlev (1) ,
X.BI winlev8 (1) ,
X.BI alv_profile (5) , 
X.BI rasterfile (5)
END_OF_FILE
if test 3463 -ne `wc -c <'doc/man/man1/alv.1'`; then
    echo shar: \"'doc/man/man1/alv.1'\" unpacked with wrong size!
fi
# end of 'doc/man/man1/alv.1'
fi
if test -f 'doc/man/man1/convolve.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/man/man1/convolve.1'\"
else
echo shar: Extracting \"'doc/man/man1/convolve.1'\" \(3018 characters\)
sed "s/^X//" >'doc/man/man1/convolve.1' <<'END_OF_FILE'
X.TH CONVOLVE 1 "15th January 1989"
X.SH NAME
convolve \- convolve raster with linear filter
X.SH SYNOPSIS
X.B convolve
X[ 
X.B -s 
X]
X[
X.B -e
X]
X[
X.B -f filter-name
X]
X[
X.B -l
X]
X[
X.B -m manual_scale 
X]
X[
X.B -M manual_offset
X]
X[
X.B "infile | -"
X]
X[
X.B "outfile | -"
X] 
X.br
X.B fconvolve
X[ 
X.B -s 
X]
X[
X.B -e
X]
X[
X.B -f filter-name
X]
X[
X.B -l
X]
X[
X.B -m manual_scale 
X]
X[
X.B -M manual_offset
X]
X[
X.B "infile | -"
X]
X[
X.B "outfile | -"
X] 
X.SH DESCRIPTION
X.I Convolve
performs a convolution of a raster with a spcified linear integer filter.
X.PP
The standard scaling method never causes the greylevels to overflow; however,
for most uses it restricts the output greylevels to too small a region.
X.PP
The greylevel scaling factor and offset used are printed out on the standard error stream.
X.PP
The filters are each specified by a file in a filters directory, which is
fixed at compile-time (see 
X.I FILTERS
envoroment variable below).
X.PP
the filter format is identical to that used for images by
X.I convert (1)
with the addition of 2 extra positive integers at the begining (the x-size and the y-size
respectively) and that either positive or negative integers are allowed. The following
is  a valid filter:
X.sp
X.br
X3 3
X.br
X 0 -1  0
X.br
X-1  4 -1
X.br
X 0 -1  0
X.br
X.PP
X.I Fconvolve 
is similar except that floating point filters are allowed and the
output image does not have a border area where the filter was not
applied.
X.SH OPTIONS
The
X.I -e
option forces the program to execute two passes over the data, the first to do
the convolution and the second to scale the output so that the maximum value in
the convoluted image is scaled to be the maximum output value, the minimum
value the minimum output value and all intermediary values linearly ranged
between the two extremes.
X.PP
The
X.I -s
option forces a two pass execution as for the
X.I -e 
option; however, the output is restricted so that the 0 greylevel is mapped to either
X0 or half the maximum output greylevel.
X.PP
The 
X.I -m
option manually sets the greylevel scaling factor. The default is 1. Note that
the scaling factor is a multiplying factor rather than a divisor.
X.PP
The
X.I -M 
option manually sets the greylevel offset. The default is 0.
X.PP
The 
X.I -f
option specifies the filter to run over the image.
X.PP
The
X.I -l 
option lists the available filters.
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.IP FILTERS
If set, the pathname of an alternative filters directory.
X.SH "SEE ALSO"
X.BI alv (1) ,
X.BI alv_profile (5) ,
X.BI rasterfile (5)
X.SH DIAGNOSTICS
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 "mem_create returned NULL"
There was insufficient memory available to allocate space for an raster
in memory.
X.SH AUTHOR
X.I Convolve 
was written by Phill Everson, University of Bristol, UK.
X.I Fconvolve 
was written by Scott Shaw, SRI, USA based on Convolve.
END_OF_FILE
if test 3018 -ne `wc -c <'doc/man/man1/convolve.1'`; then
    echo shar: \"'doc/man/man1/convolve.1'\" unpacked with wrong size!
fi
# end of 'doc/man/man1/convolve.1'
fi
if test -f 'doc/man/man1/palettetool.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/man/man1/palettetool.1'\"
else
echo shar: Extracting \"'doc/man/man1/palettetool.1'\" \(3604 characters\)
sed "s/^X//" >'doc/man/man1/palettetool.1' <<'END_OF_FILE'
X.TH PALETTETOOL 1 "11th April, 1989"
X.SH NAME
palettetool \--- a colourmap manipulator
X.SH SYNOPSIS
X.B palettetool
X.SH DESCRIPTION
X.I Palettetool
provides users with an interactive colourmap modification
environment.  It consists of a control panel, a colour palette, a raster display and
a colourmap display, all in one window.
X.SH CONTROL PANEL
There are three types of entities in the control panel:
X.I File
input,
X.I Color Sliders,
and buttons.
X.TP 13
X.B File input:
this is where the user specifies the colourmap file name.
X.TP 13
X.B Sliders:
the three sliders are used to modify the selected colour.  Initially, when
a colour is selected, the sliders are set to that colour's value.  Pressing
the left mouse button within a slider will change the value of that slider.
The colourmap manipulations will be reflected in the displayed raster.
To undo, select the
X.I Reset
button.
X.TP 13
X.B Load
this button is used to load in a raster and place the colourmap onto the
colour palette as well as the colourmap display.
X.TP 13
X.B Save
this button is used to save a raster and its associated colourmap as displayed in the "colourmap
display" into a raster file named by the
X.I File
field.  If the file already exists, the user is asked to confirm overwriting.
The user is prompt with messages as to how to proceed.
X.TP 13
X.B Reset
this button resets the modification applied on the selected colour.
X.TP 13
X.B Quit
this button terminates the environment.
X
X
X.SH COLOUR PALETTE
There are 256 coloured boxes reflecting 256 colour entries for the colourmap.
The layout is organized such that the first colour box represents the colour
stored at colourmap entry 0, and the row major is followed.  Pressing the
left mouse button will designate the colour intended to change.
X
There is a moving box tracing the mouse within the colour palette.  When a
colour is selected to change, the box is locked up on that colour.  Any
mouse press will unlock the moving box.
X
While the left mouse button selects a colour to change, the right mouse button
is designed to "paint" the selected colour to all the colours from the selected
colour through to the colour
under the right mouse button where it is pressed; and the middle mouse button
press will reverse (undo) this operation.
Holding the Control key down while clicking the right mouse button will result
copying the selected colour to the colour pointed by the mouse.
X
The change of colours are reflected instantly on the "colourmap display" and "raster display".  See the
following sections for details.
X
X.SH COLOURMAP DISPLAY
This subwindow has three entities: a colourmap stripe,
a "current entry" number, and
an arrow pointing at the entry.
X
The colourmap stripe represents the current colourmap setting. The "current entry"
corresponds to the colour of the brush when the mouse is within the colour
palette, or the colourmap entry when the mouse is within the colourmap display.
The left mouse button designed to work as if the mouse is within the colour
palette, with the added convenience that users may select colourmap entries by
directly pointing the cursor on the desired colours via the stripe.
X
X.SH RASTER DISPLAY
This subwindow displays the raster. Pressing the left mouse button over this window causes
the "current entry" of the colourmap to be set to the pixel pointed to by
the mouse.
X
X.SH OPTIONS
none as of this version.
X.SH ORIGINAL AUTHOR
Hsuan Chang (hsc@vuse.vanderbilt.edu or ..!uunet!vuse!hsc)
X(based on the version provided by Sun Microsystems, Inc.)
Modified by Phill Everson (everson@cs.bris.ac.uk) for inclusion 
into the ALV toolkit.
END_OF_FILE
if test 3604 -ne `wc -c <'doc/man/man1/palettetool.1'`; then
    echo shar: \"'doc/man/man1/palettetool.1'\" unpacked with wrong size!
fi
# end of 'doc/man/man1/palettetool.1'
fi
if test -f 'doc/man/man3/dynamem.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/man/man3/dynamem.3'\"
else
echo shar: Extracting \"'doc/man/man3/dynamem.3'\" \(2967 characters\)
sed "s/^X//" >'doc/man/man3/dynamem.3' <<'END_OF_FILE'
X.\" .TH name section cent-foot left-foot cent-head
X.TH DYNAMEM 3 "28 August 1987"
X.SH NAME
X.\" name \- function
dynamem, freeup \- multidimensional dynamic array handling
X.SH SYNOPSIS
X.\" Bold keywords, Italic variables, [] options, | alternatives.
X.br
X.B char *dynamem(pointer, element_size, number_dimensions, dimensions ...)
X.br
X.B char **pointer;
X
X.br
X.B freeup(pointer, number_dimensions)
X.br
X.B char *pointer;
X.br
X.B int number_dimensions;
X
X.SH DESCRIPTION
X.\" Italic files, commands, IR manual-entry (manual-section)
X.I dynamem 
is the multidimensional analogue to malloc().
It is passed a number of arguments: a pointer which on
exiting the procedure will point to the begining of the
array, the element size, the number of dimensions 
required, followed by a list of the dimension sizes. 
To declare a 4 dimensional array normally one would code:
X.DS L
X
int array[10][11][12][13];
X
X.DE
however, this array is then fixed at compile time. This
same array can be declared dynamically at run time 
using the following code:
X.DS L
X
int ****array;
X
array = (int ****) dynamem(&array, sizeof(int), 4, 10, 11, 12, 13);
X
X.DE
X(Note that the number of levels of indirection in the cast
is equal to the number of dimensions in the array.)
This enables array sizes to be fixed via, for example, 
command line arguments. 
X.PP
X.I freeup
is the 
X.I dynamem
analogue to free(). When passed an array previously 
dynamically declared by 
X.I dynamem
the function returns this memory to the system.
X.PP
X.I dynamem
attempts to set up the array required in the same way that 
it would be set up by the compiler at compile time. Thus
a multidimensional dynamically array declared using 
X.I dynamem
can be used in exactly the same way as a fixed array declared
by the compiler. There is obviously some overhead in the actual
setting up of the array; however, this is minimal: 
when dynamically allocating 2 arrays of 346000
unsigned characters and one of the same number of shorts all in
two dimensions, the run time of a convolution of a 7x7 Lapacian-
Marr filter over an image of size 720 by 480 varied as follows:
X.sp 1
time convolve -fbfilt -X720 -Y480 -e < bubble2 > test.1
X.br
X	  222.0 real       213.4 user         1.6 sys  
X.sp 1
time convolve -fbfilt -e < bubble2 > test.2
X.br
X	  225.2 real       212.5 user         2.7 sys  
X.sp 1
which is probably adequate. From this we can see that 
it takes 1.1 secs for the fixed array to be set up
and zeroed and only 0.9 secs for the array to be
dynamically declared using
X.IR dynamem ; 
however, using dynamem the array is not initialized to
X0 and this is the reason for the 0.2 sec speed increase.
X.SH FILES
X.\" List of all files used by the program
src/dynamem.c
X.SH "SEE ALSO"
X.\" List of references, textual, and MAN pages.
X.BI convolve (1) ,
X.BI malloc (3)
X.SH DIAGNOSTICS
X.\" List of error messages and return codes the user may expect
X.br
X.I dynamem
returns NULL if it is unable to allocate sufficient
memory for the array.
X
END_OF_FILE
if test 2967 -ne `wc -c <'doc/man/man3/dynamem.3'`; then
    echo shar: \"'doc/man/man3/dynamem.3'\" unpacked with wrong size!
fi
# end of 'doc/man/man3/dynamem.3'
fi
if test -f 'doc/man/man3/matrix.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/man/man3/matrix.3'\"
else
echo shar: Extracting \"'doc/man/man3/matrix.3'\" \(3326 characters\)
sed "s/^X//" >'doc/man/man3/matrix.3' <<'END_OF_FILE'
X.\" .TH name section cent-foot left-foot cent-head
X.TH MATRIX 3 "13th November 1987"
X.SH NAME
X.\" name \- function
X.B matrix \- matrix and vector manipulation routines
X.SH SYNOPSIS
X.\" Bold keywords, Italic variables, [] options, | alternatives.
MATRIX minit( ... 16 doubles ... )
X.sp
MATRIX mnil()
X.sp
MATRIX mmult(A,B,C)
X.br
MATRIX A,B,C;
X.sp
mprint(A)
X.br
MATRIX A;
X.sp
VECTOR vinit(a,b,c,d)
X.br
double a,b,c,d;
X.sp
VECTOR vnil()
X.sp
VECTOR vmult(x,A,y)
X.br
VECTOR x,y;
X.br
MATRIX A;
X.sp
VECTOR vadd(v,w,y)
X.br
VECTOR v,w,y;
X.sp
VECTOR vsub(v,w,y)
X.br
VECTOR v,w,y;
X.sp
vprint(v)
X.br
VECTOR v;
X.sp
double dprod(v,w)
X.br
VECTOR v,w;
X.sp
VECTOR xprod(v,w,y)
X.br
VECTOR v,w,y;
X.sp
dbgmprint(A)
X.br
MATRIX A;
X.sp
mprint(A)
X.br
MATRIX A;
X.sp
dbgvprint(v)
X.br
VECTOR v;
X.sp
vprint(v)
X.br
VECTOR v;
X.sp
VECTOR vass(v,w)
X.br
VECTOR v,w;
X.sp
MATRIX mass(A,B)
X.br
MATRIX A,B;
X.sp
MATRIX mset(A, ... 16 doubles ... )
X.br
MATRIX A;
X.sp
VECTOR vset(v, ... 4 doubles ... )
X.br
VECTOR v;
X.sp
VECTOR vnorm(v,w)
X.br
VECTOR v,w;
X.sp
X.SH DESCRIPTION
X.\" Italic files, commands, IR manual-entry (manual-section)
X.I Matrix
is a set of 4x4 matrix multiplication
routines.
It can be effectively used to perform
the necessary computations for
X.IR "Homogeneous Coordinates" .
X.IR minit ()
initialises a 4x4 array to the
values (given in row order) which
must be
X.IR double s.
X.IR mnil ()
creates a zeroed 4x4 array.
This call should be used to
create destination arrays for
X.IR mmult ().
X.IR mmult ()
multiplies the arrays 
X.I A
and
X.I B
to yield an answer in
X.IR C ,
all of which should have
been created using
X.IR minit ()
or
X.IR mnil ()
calls.
X.IR vinit ()
corresponds to
X.IR minit ()
only for a 4x1 vector,
X.IR vnil ()
creates a nil vector,
X.IR vmult ()
premultiplies a vector
by a matrix,
X.IR vadd ()
adds two vectors and
X.IR vsub ()
subtracts two vectors.
X.LP
X.IR dprod ()
returns the dot product
of the two specified
vectors.
The scalar result
is returned in a double.
X.IR xprod ()
places the cross-product
of
X.I v
and
X.I w
in the vector
X.IR y .
The vector
X.I y
is also returned.
X.LP
X.IR dbgmprint ()
prints the matrix on the standard error stream,
X.IR mprint ()
prints the matrix on the standard output stream,
X.IR dbgvprint ()
prints the vector on the standard error stream and
X.IR vprint ()
prints the vector on the standard output stream.
X.LP
X.IR vass ()
assigns to vector
X.I v
vector 
X.I w
and also returns vector
X.IR w ,
X.IR mass ()
assigns to matrix
X.I A
matrix 
X.I B
and also returns matrix
X.IR B .
X.LP 
X.IR vset ()
assigns to the vector
X.I v
the 4 arguments, which must be doubles and 
X.IR mset ()
assigns to the matrix 
X.I A
the 16 arguments (in row major order), which must be doubles.
X.LP
X.IR vnorm ()
normalises vector
X.IR v ,
returning it in vector
X.I w
and also from the function
X.LP
Additional operations
may be performed by
accessing the matrix
or vector directly.
In C, the recommended
approach is to use the
syntax:
X.sp
A[i][j]
X.sp
to give the
X.IR i th
element
of the
X.IR j th
row of the matrix
X.IR A .
X.SH FILES
X.\" List of all files used by the program
src/matrix.h
X.br
src/matrix.c
X.br
X.SH "SEE ALSO"
X.\" List of references, textual, and MAN pages.
X.I dynamem (3)
X.\".SH DIAGNOSTICS
X.\" List of error messages and return codes the user may expect
X.\".SH BUGS
X.\" Known Limitations or Desirable additions to the command
END_OF_FILE
if test 3326 -ne `wc -c <'doc/man/man3/matrix.3'`; then
    echo shar: \"'doc/man/man3/matrix.3'\" unpacked with wrong size!
fi
# end of 'doc/man/man3/matrix.3'
fi
if test -f 'src/Makefile-merge' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile-merge'\"
else
echo shar: Extracting \"'src/Makefile-merge'\" \(3265 characters\)
sed "s/^X//" >'src/Makefile-merge' <<'END_OF_FILE'
X#Modify the following to point to your desired installation directories
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 CFLAGS are -g or -O
X#CFLAGS=-g
CFLAGS=-O
X
X##########################################################
X# You shouldn't need to modify anything below this point #
X# Type:                                                  #
X# 'make' to make tools merged in place                   #
X# 'make install' to make tools merged and install        #
X##########################################################
X
LIBS = -lsuntool -lsunwindow -lpixrect -lm 
X
LPROGS = convert dither rasthresh winlev dsp rasregion equalise ffill \
X	hist im2ras ras2im ras2lw invert rasval blend rasrange halftone \
X	box rasinfo scr2ras winlev8 rasscale transform convolve \
X	ras2array array2ras hough palettetool cst rasremap scrload ras8to1 \
X	fconvolve
X
TOOLOBJS = convert.o dither.o rasthresh.o winlev.o dsp.o rasregion.o \
X	equalise.o ffill.o hist.o im2ras.o ras2im.o ras2lw.o invert.o rasval.o \
X	blend.o rasrange.o halftone.o box.o rasinfo.o scr2ras.o winlev8.o \
X	rasscale.o transform.o convolve.o ras2array.o array2ras.o hough.o \
X	palettetool.o cst.o rasremap.o scrload.o ras8to1.o fconvolve.o
X
OTHEROBJS = dynamem.o matrix.o support.o
PALETTEOBJS = p_confirm.o p_init.o p_notif.o p_panel.o p_event.o
OBJS = $(TOOLOBJS) $(OTHEROBJS) $(PALETTEOBJS)
X
all: alvtools glass
X
glass: glass.o
X	cc $(CFLAGS) -o glass glass.o $(LIBS)
X
alvtools: $(OBJS) toolmerge.o
X	cc $(CFLAGS) -o alvtools toolmerge.o $(OBJS) $(LIBS)
X
toolmerge.o: toolmerge.c tools.h declarations.h
X	cc $(CFLAGS) -c toolmerge.c
X
convolve.o: convolve.c defs.h support.c
X	cc $(CFLAGS) -DFILTERS_DIR=\"$(FILDIR)\" -c convolve.c
X
fconvolve.o: fconvolve.c defs.h support.c
X	cc $(CFLAGS) -DFILTERS_DIR=\"$(FILDIR)\" -c fconvolve.c
X
dsp.o: dsp.c defs.h
X	cc $(CFLAGS) -DFILTER8TO1=\"$(FILTER8TO1)\" -c dsp.c
X
clean:
X	rm -f *.o *~ core
X
spotless: clean
X	rm -f $(LPROGS) glass double half quarter third triple quad MANIFEST alvtools
X
install: all
X	install -s alvtools $(BINDIR)
X	install -s glass $(BINDIR)
X	@for i in ${LPROGS}; do \
X		(rm -f $(BINDIR)/$$i; ln -s $(BINDIR)/alvtools $(BINDIR)/$$i); \
X	done
X	@rm -f $(BINDIR)/double; ln -s $(BINDIR)/alvtools $(BINDIR)/double
X	@rm -f $(BINDIR)/half; ln -s $(BINDIR)/alvtools $(BINDIR)/half
X	@rm -f $(BINDIR)/quarter; ln -s $(BINDIR)/alvtools $(BINDIR)/quarter
X	@rm -f $(BINDIR)/third; ln -s $(BINDIR)/alvtools $(BINDIR)/third
X	@rm -f $(BINDIR)/triple; ln -s $(BINDIR)/alvtools $(BINDIR)/triple
X	@rm -f $(BINDIR)/quad; ln -s $(BINDIR)/alvtools $(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'
END_OF_FILE
if test 3265 -ne `wc -c <'src/Makefile-merge'`; then
    echo shar: \"'src/Makefile-merge'\" unpacked with wrong size!
fi
# end of 'src/Makefile-merge'
fi
if test -f 'src/matrix.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/matrix.c'\"
else
echo shar: Extracting \"'src/matrix.c'\" \(3426 characters\)
sed "s/^X//" >'src/matrix.c' <<'END_OF_FILE'
static char     SccsID[] = "@(#)matrix.c	1.2	11/7/88";
X
X#include "matrix.h"
X
MATRIX 
mmult(A, B, C)
X	MATRIX          A, B, C;
X{
X	int             i, j, k;
X
X	MATRIX          D;
X
X	D = mnil();
X
X	for (i = 0; i < 4; i++)
X		for (j = 0; j < 4; j++) {
X			D[i][j] = 0.;
X			for (k = 0; k < 4; k++)
X				D[i][j] += A[i][k] * B[k][j];
X		}
X	mass(D, C);
X	mfree(D);
X
X	return C;
X}
X
VECTOR 
vmult(a, B, c)
X	VECTOR          a, c;
X	MATRIX          B;
X{
X	int             i, k;
X	VECTOR			d;
X	double 			s;
X
X	d = vnil();
X	for (i = 0; i < 4; i++) {
X		s = 0.;
X		for (k = 0; k < 4; k++)
X			s += a[k] * B[k][i];
X		d[i] = s;
X	}
X	vass(d,c);
X	vfree(d);
X	return c;
X}
X
VECTOR 
vadd(a, b, c)
X	VECTOR          a, b, c;
X{
X	int             i;
X
X	for (i = 0; i < 3; i++)
X		c[i] = a[i] + b[i];
X	return c;
X}
X
VECTOR 
vsub(a, b, c)
X	VECTOR          a, b, c;
X{
X	int             i;
X
X	for (i = 0; i < 3; i++)
X		c[i] = a[i] - b[i];
X	return c;
X}
X
dbgmprint(A)
X	MATRIX          A;
X{
X	int             i, j;
X
X	for (j = 0; j < 4; j++) {
X		for (i = 0; i < 4; i++)
X			fprintf(stderr,"%15g", A[j][i]);
X		fprintf(stderr,"\n");
X	}
X}
X
mprint(A)
X	MATRIX          A;
X{
X	int             i, j;
X
X	for (j = 0; j < 4; j++) {
X		for (i = 0; i < 4; i++)
X			printf("%15g", A[j][i]);
X		printf("\n");
X	}
X}
X
dbgvprint(V)
X	VECTOR          V;
X{
X	int             i, j;
X
X	fprintf(stderr,"(");
X	for (i = 0; i < 3; i++)
X		fprintf(stderr,"%g,", V[i]);
X	fprintf(stderr,"%g)\n", V[3]);
X}
X
vprint(V)
X	VECTOR          V;
X{
X	int             i, j;
X
X	printf("(");
X	for (i = 0; i < 3; i++)
X		printf("%g,", V[i]);
X	printf("%g)\n", V[3]);
X}
X
VECTOR 
vass(w, v)
VECTOR v,w;
X{
X	int             i;
X
X	for (i = 0; i < 4; i++)
X		v[i] = w[i];
X	return v;
X}
X
MATRIX 
mass(A, B)
X	MATRIX          A, B;
X{
X	int             i;
X
X	for (i = 0; i < 16; i++)
X		B[0][i] = A[0][i];
X	return B;
X}
X
MATRIX 
minit(p)
X	double          p;
X{
X	double         *q, *r;
X	int             i;
X	MATRIX          A;
X
X	A = (MATRIX) dynamem(&A, sizeof(double), 2, 4, 4);
X	r= *A;
X	for (q = &p, i = 0; i < 16; i++)
X		*r++ = *q++;
X	return A;
X}
X
MATRIX
mset(A, p)
X	MATRIX		A;
X	double		p;
X{
X	double		*q, *r;
X	int		i;
X
X	r= *A;
X        for (q = &p, i = 0; i < 16; i++)
X                *r++ = *q++;
X        return A;
X}
X
MATRIX 
mnil()
X{
X	int             i;
X	MATRIX          A;
X	double			*q;
X
X	A = (MATRIX) dynamem(&A, sizeof(double), 2, 4, 4);
X	q = *A;
X	for (i = 0; i < 16; i++)
X		*q++ = 0.0;
X	return A;
X}
X
VECTOR 
vinit(p)
X	double          p;
X{
X	double         *q;
X	int             i;
X	VECTOR          V;
X
X	V = (VECTOR) dynamem(&V, sizeof(double), 1, 4);
X	for (q = &p, i = 0; i < 4; i++)
X		V[i] = *q++;
X	return V;
X}
X
VECTOR
vset(V, p)
X	VECTOR		V;
X	double		p;
X{
X        double         *q;
X        int             i;
X 
X        for (q = &p, i = 0; i < 4; i++)
X                V[i] = *q++;
X        return V;
X}
X
VECTOR 
vnil()
X{
X	int             i;
X	VECTOR          V;
X
X	V = (VECTOR) dynamem(&V, sizeof(double), 1, 4);
X	for (i = 0; i < 4; i++)
X		V[i] = 0.0;
X	return V;
X}
X
double 
dprod(v, w)
X	VECTOR          v, w;
X{
X	return v[0] * w[0] + v[1] * w[1] + v[2] * w[2];
X}
X
VECTOR 
xprod(v, w, y)
X	VECTOR          v, w, y;
X{
X	double          x;
X
X	y[0] = v[1] * w[2] - v[2] * w[1];
X	y[1] = v[2] * w[0] - v[0] * w[2];
X	y[2] = v[0] * w[1] - v[1] * w[0];
X	y[3] = 1;
X	return y;
X}
X
VECTOR 
vnorm(v, w)
X	VECTOR          v, w;
X{
X	double          length;
X	int             i;
X
X	length = sqrt(dprod(v, v));
X	for (i = 0; i < 3; i++)
X		w[i] = v[i] / length;
X	w[3] = 1.;
X
X	return w;
X}
END_OF_FILE
if test 3426 -ne `wc -c <'src/matrix.c'`; then
    echo shar: \"'src/matrix.c'\" unpacked with wrong size!
fi
# end of 'src/matrix.c'
fi
if test -f 'src/p_main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/p_main.c'\"
else
echo shar: Extracting \"'src/p_main.c'\" \(2713 characters\)
sed "s/^X//" >'src/p_main.c' <<'END_OF_FILE'
X/************************************ palette_main.c ********/
X
X/* Palettetool.c, a color palette and code generation tool.
X *
X * Copyright (c) 1987, Sun Microsystems, Inc.
X *
X * Note:  this code is completely unsupported.
X *
X * Change Notes: (7/1/87, by hsc%vanderbilt@csnet-relay)
X *		1) a colormap stripe is added to reflect the
X *		   spectrum change while modifying the single
X *		   entry;
X *		2) colormap file generated is formatted to
X *		   our local specs.
X *
X */
X#include "p_include.h"
X#include "p_icons.h"
X
main(argc, argv)
int	argc;
char	**argv;
X{
X	progname = strsave(*argv);
X	palette_init();
X
X	base_frame = window_create(NULL, FRAME,
X	    	FRAME_ICON, &palette_icon,
X		FRAME_LABEL, "palettetool",
X	    	FRAME_ARGS, argc, argv,
X	    	0);
X
X	control_panel = window_create(base_frame, PANEL,
X	    	WIN_WIDTH, 560,
X	    	0);
X
X	panel_creation();
X
X	display_canvas = window_create(base_frame, CANVAS,
X			WIN_X, 0,
X			WIN_BELOW, control_panel,
X			CANVAS_AUTO_SHRINK, FALSE,
X			WIN_HEIGHT, 3*MAX_CMAP_LEN-(int)window_get(control_panel, WIN_HEIGHT)-11*(xspace+cwidth)+2*xoff,
X			WIN_WIDTH, (int) window_get(control_panel, WIN_WIDTH),
X			WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),
X			WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
X			WIN_EVENT_PROC, display_event_proc,
X			WIN_CONSUME_PICK_EVENTS, MS_LEFT, MS_MIDDLE, MS_RIGHT, 0,
X			0);
X	multiple_canvas = window_create(base_frame, CANVAS,
X	    	WIN_X, 0,
X	    	WIN_BELOW, display_canvas,
X	   	WIN_WIDTH, (int)window_get(control_panel, WIN_WIDTH), /*24*(xspace+cwidth)+2*xoff,*/
X	  	WIN_HEIGHT, 11*(yspace+cheight)+2*yoff,
X                CANVAS_AUTO_SHRINK, FALSE,
X	    	WIN_EVENT_PROC, multiple_canvas_event_proc,
X	    	0);
X
X      	brush_cursor = cursor_create(CURSOR_IMAGE, &brushpix,
X       	       	CURSOR_XHOT, 8, CURSOR_YHOT, 7,
X       	       	CURSOR_OP, PIX_SRC|PIX_DST,
X       	       	0);
X
X	window_set(multiple_canvas, WIN_CURSOR, brush_cursor, 0);
X
X	single_canvas = window_create(base_frame, CANVAS,
X	    	WIN_RIGHT_OF, control_panel,
X	    	WIN_Y, 0,
X	    	WIN_WIDTH, 100,
X	    	WIN_HEIGHT,  (int)window_get(display_canvas, WIN_HEIGHT) + (int) window_get(multiple_canvas, WIN_HEIGHT)+(int)window_get(control_panel,WIN_HEIGHT)+10, /*3*MAX_CMAP_LEN,*/
X                CANVAS_AUTO_SHRINK, FALSE,
X	    	WIN_EVENT_PROC, single_canvas_event_proc,
X		WIN_CONSUME_PICK_EVENTS, MS_LEFT, MS_MIDDLE, MS_RIGHT, 0,
X		CANVAS_REPAINT_PROC, paint_single_canvas,
X	    	0);
X
X	put_colors(0, MAX_CMAP_LEN, r, g, b);
X 	paint_multiple_canvas();
X	paint_single_canvas();
X
X	panel_set_value(red_slider, r[selected_n]);
X	panel_set_value(green_slider, g[selected_n]);
X	panel_set_value(blue_slider, b[selected_n]);
X
X	window_fit(base_frame);
X
X	window_main_loop(base_frame);
X
X}
END_OF_FILE
if test 2713 -ne `wc -c <'src/p_main.c'`; then
    echo shar: \"'src/p_main.c'\" unpacked with wrong size!
fi
# end of 'src/p_main.c'
fi
if test -f 'src/palettetool.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/palettetool.c'\"
else
echo shar: Extracting \"'src/palettetool.c'\" \(2785 characters\)
sed "s/^X//" >'src/palettetool.c' <<'END_OF_FILE'
X/************************************ palette_main.c ********/
X
X/* Palettetool.c, a color palette and code generation tool.
X *
X * Copyright (c) 1987, Sun Microsystems, Inc.
X *
X * Note:  this code is completely unsupported.
X *
X * Change Notes: (7/1/87, by hsc%vanderbilt@csnet-relay)
X *		1) a colormap stripe is added to reflect the
X *		   spectrum change while modifying the single
X *		   entry;
X *		2) colormap file generated is formatted to
X *		   our local specs.
X *
X */
X#include "p_include.h"
X#include "p_icons.h"
X
X#ifdef STANDALONE
main(argc, argv, envp)
X#else
palettetool_main(argc, argv, envp)
X#endif
int	argc;
char	**argv;
X{
X	progname = strsave(*argv);
X	palette_init();
X
X	base_frame = window_create(NULL, FRAME,
X	    	FRAME_ICON, &palette_icon,
X		FRAME_LABEL, "palettetool",
X	    	FRAME_ARGS, argc, argv,
X	    	0);
X
X	control_panel = window_create(base_frame, PANEL,
X	    	WIN_WIDTH, 560,
X	    	0);
X
X	panel_creation();
X
X	display_canvas = window_create(base_frame, CANVAS,
X			WIN_X, 0,
X			WIN_BELOW, control_panel,
X			CANVAS_AUTO_SHRINK, FALSE,
X			WIN_HEIGHT, 3*MAX_CMAP_LEN-(int)window_get(control_panel, WIN_HEIGHT)-11*(xspace+cwidth)+2*xoff,
X			WIN_WIDTH, (int) window_get(control_panel, WIN_WIDTH),
X			WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),
X			WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
X			WIN_EVENT_PROC, display_event_proc,
X			WIN_CONSUME_PICK_EVENTS, MS_LEFT, MS_MIDDLE, MS_RIGHT, 0,
X			0);
X	multiple_canvas = window_create(base_frame, CANVAS,
X	    	WIN_X, 0,
X	    	WIN_BELOW, display_canvas,
X	   	WIN_WIDTH, (int)window_get(control_panel, WIN_WIDTH), /*24*(xspace+cwidth)+2*xoff,*/
X	  	WIN_HEIGHT, 11*(yspace+cheight)+2*yoff,
X                CANVAS_AUTO_SHRINK, FALSE,
X	    	WIN_EVENT_PROC, multiple_canvas_event_proc,
X	    	0);
X
X      	brush_cursor = cursor_create(CURSOR_IMAGE, &brushpix,
X       	       	CURSOR_XHOT, 8, CURSOR_YHOT, 7,
X       	       	CURSOR_OP, PIX_SRC|PIX_DST,
X       	       	0);
X
X	window_set(multiple_canvas, WIN_CURSOR, brush_cursor, 0);
X
X	single_canvas = window_create(base_frame, CANVAS,
X	    	WIN_RIGHT_OF, control_panel,
X	    	WIN_Y, 0,
X	    	WIN_WIDTH, 100,
X	    	WIN_HEIGHT,  (int)window_get(display_canvas, WIN_HEIGHT) + (int) window_get(multiple_canvas, WIN_HEIGHT)+(int)window_get(control_panel,WIN_HEIGHT)+10, /*3*MAX_CMAP_LEN,*/
X                CANVAS_AUTO_SHRINK, FALSE,
X	    	WIN_EVENT_PROC, single_canvas_event_proc,
X		WIN_CONSUME_PICK_EVENTS, MS_LEFT, MS_MIDDLE, MS_RIGHT, 0,
X		CANVAS_REPAINT_PROC, paint_single_canvas,
X	    	0);
X
X	put_colors(0, MAX_CMAP_LEN, r, g, b);
X 	paint_multiple_canvas();
X	paint_single_canvas();
X
X	panel_set_value(red_slider, r[selected_n]);
X	panel_set_value(green_slider, g[selected_n]);
X	panel_set_value(blue_slider, b[selected_n]);
X
X	window_fit(base_frame);
X
X	window_main_loop(base_frame);
X
X}
END_OF_FILE
if test 2785 -ne `wc -c <'src/palettetool.c'`; then
    echo shar: \"'src/palettetool.c'\" unpacked with wrong size!
fi
# end of 'src/palettetool.c'
fi
if test -f 'src/ras2lw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/ras2lw.c'\"
else
echo shar: Extracting \"'src/ras2lw.c'\" \(3129 characters\)
sed "s/^X//" >'src/ras2lw.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X#include "defs.h"
X
X#define MIDX        285		/* center of output page */
X#define MIDY        396
X
Pixrect        *pr;
char           *progname;
char           *filename;
int             small, large, mail, special, nopipe;
char           *title;
X
X#ifdef STANDALONE
main(argc, argv, envp)
X#else
ras2lw_main(argc, argv, envp)
X#endif
X	int             argc;
X	char          **argv;
X	char          **envp;
X{
X	int             c, x = 0, y = 0, r = 0;
X	register int    i, j;
X	double          sx = 1.0, sy = 1.0, atof();
X	char           *hex();
X	char            buf1[BUFSIZ];
X	FILE           *pd;
X
X	small = TRUE;
X	large = mail = special = nopipe = FALSE;
X
X	progname = strsave(argv[0]);
X	parse_profile(&argc, argv, envp);
X
X	title = NULL;
X
X	while ((gc = getopt(argc, argv, "mslt:T")) != EOF)
X		switch (gc) {
X		case 'm':
X			mail = TRUE;
X			break;
X		case 's':
X			small = TRUE;
X			break;
X		case 'l':
X			large = TRUE;
X			break;
X		case 't':
X			title = strsave(optarg);
X			break;
X		case 'T':
X			special = TRUE;
X			nopipe = TRUE;
X			break;
X		case '?':
X			errflag++;
X			break;
X		}
X
X	if (errflag)
X		error((char *) 0, "Usage: %s: [-s] [-l] [-m] [-t title] [-T] [infile]\n", progname);
X
X	for (stream = 0; optind < argc; stream++, optind++)
X		if (stream == 0 && 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 ((pr = pr_load(stdin, NULL)) == NULL)
X		error(PR_IO_ERR_RASREAD);
X
X	if (pr->pr_depth > 8)
X		error("Cannot print images with depth greater than 8 bits");
X
X	if (!nopipe) {
X		if ((pd = popen(strcat("lpr -Plw -v", ((mail) ? " -m" : "")), "w")) == NULL)
X			error("Cannot open pipe to lpr");
X	} else
X		pd = stdout;
X
X	fprintf(pd, "%%!PS-Adobe-1.0\n");	/* PostScript magic strings */
X	fprintf(pd, "/picstr %d string def\n", pr->pr_size.x);
X
X	if (title) {
X		fprintf(pd, "/Helvetica-Bold findfont\n");
X		fprintf(pd, "12 scalefont setfont\n");
X		fprintf(pd, "285 (%s) stringwidth pop 2 div sub 720 moveto\n", title);
X		fprintf(pd, "(%s) show\n", title);
X	}
X	if (small || large) {
X		sx = 7.91 * 300 / pr->pr_size.x;
X		sy = 8.5 * 300 / pr->pr_size.y;	/* avoid title area */
X		if (large) {
X			sx /= 2.;
X			sy /= 2.;
X		}
X		sx = sy = (sx > sy) ? sy : sx;
X		x = -sx * pr->pr_size.x * 72 / 300 / 2;
X		y = -sy * pr->pr_size.y * 72 / 300 / 2;
X	}
X	if (special)
X		fprintf(pd, " 0 0 translate\n");
X	else
X		fprintf(pd, "%d %d translate\n", MIDX + x, MIDY - 36 + y);
X
X	fprintf(pd, "%d %d scale\n", (int) (pr->pr_size.x / 300.0 * 72.0 * sx), (int) (pr->pr_size.y / 300.0 * 72.0 * sy));
X	fprintf(pd, "%d %d 8\n", pr->pr_size.x, pr->pr_size.y);
X	fprintf(pd, "[ %d 0 0 -%d 0 %d ]\n", pr->pr_size.x, pr->pr_size.y, pr->pr_size.y);
X	fprintf(pd, "{currentfile\npicstr readhexstring pop}\nimage\n");
X
X	for (j = 0; j < pr->pr_size.y; j++)
X		for (i = 0; i < pr->pr_size.x; i++) {
X			if (nopipe && !(i % 40))
X				fputs("\n", pd);
X			fputs(hex(pr_get(pr, i, j)), pd);
X			}
X
X	if (!special)
X		fprintf(pd, "showpage\n");
X	if (!nopipe)
X		pclose(pd);
X}
X
char           *
hex(d)
X{
X	static char     a[10];
X
X	sprintf(a, "%02x", d);
X	return (a);
X}
END_OF_FILE
if test 3129 -ne `wc -c <'src/ras2lw.c'`; then
    echo shar: \"'src/ras2lw.c'\" unpacked with wrong size!
fi
# end of 'src/ras2lw.c'
fi
if test -f 'src/support.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/support.c'\"
else
echo shar: Extracting \"'src/support.c'\" \(3180 characters\)
sed "s/^X//" >'src/support.c' <<'END_OF_FILE'
X#include "defs.h"
X#include <varargs.h>
X
extern char *progname;
extern Pixfont *font;
X
X/* VARARGS */
void
error(va_alist)
va_dcl
X{
X	va_list ap;
X	char   *fmt;
X
X	va_start(ap);
X	if (fmt = va_arg(ap, char *))
X		(void) fprintf(stderr, "%s: ", progname);
X	else
X		fmt = va_arg(ap, char *);
X
X	(void) _doprnt(fmt, ap, stderr);
X	va_end(ap);
X
X	(void) fprintf(stderr, "\n");
X
X	exit(1);
X}
X
X/* VARARGS */
void
warning(va_alist)
va_dcl
X{
X	va_list ap;
X	char   *fmt;
X
X	va_start(ap);
X	if (fmt = va_arg(ap, char *))
X		(void) fprintf(stderr, "%s: ", progname);
X	else
X		fmt = va_arg(ap, char *);
X
X	(void) _doprnt(fmt, ap, stderr);
X	va_end(ap);
X
X	(void) fprintf(stderr, "\n");
X
X}
X
X
setup_font()
X{
X	Pixfont *pf_open();
X
X	if ((font = pf_open(FONT)) == NULL)
X		error("Couldn't open %s", FONT);
X	if ((smallfont = pf_open(SMALL_FONT)) == NULL)
X		error("Couldn't open %s", SMALL_FONT);
X}
X
X
calc_max(in)
X	Pixrect *in;
X{
X	register int i, j;
X	int     max_level, val;
X
X	max_level = 0;
X	for (i = 0; i < in->pr_size.x; i++)
X		for (j = 0; j < in->pr_size.y; j++) {
X			val = pr_get(in, i, j);
X			max_level = MAX(max_level, val);
X		} return max_level;
X}
parse_profile(argc, argv, envp)
X	int    *argc;
X	char  **argv;
X	char  **envp;
X{
X	int     i;
X	char    buf[BUFSIZ], buf1[BUFSIZ];
X	char   *start;
X	int     newargc;
X	char  **newargv;
X	char    baseprogname[BUFSIZ];
X	char   *home;
X	char   *profile;
X	char   *str;
X	char    array[100][100];
X	FILE   *fp, *fopen();
X	char   *getenv();
X
X	if ((profile = getenv("ALV")) == NULL)
X		if ((home = getenv("HOME")) != NULL) {
X			sprintf(buf1, "%s/%s", home, PROFILE);
X			profile = buf1;
X		}
X	bitrestrict = FALSE;
X	verbose = FALSE;
X	mono_override = FALSE;
X
X	if (strrchr(progname, '/') == NULL)
X		strcpy(baseprogname, progname);
X	else
X		strcpy(baseprogname, strrchr(progname, '/') + 1);
X
X	/* initialise the getopt variables here */
X	f[0] = stdin;
X	f[1] = stdout;
X	mode[0] = strsave("r");
X	mode[1] = strsave("w");
X	errflag = 0;
X
X	if ((fp = fopen(profile, "r")) == NULL)
X		return;
X
X	while (fgets(buf, BUFSIZ, fp) != NULL) {
X		if (buf[0] == '#')
X			continue;
X
X		buf[strlen(buf) - 1] = '\0';
X
X		if (strcmp(buf, "bitrestrict") == 0 || strcmp(buf, "bit-restrict") == 0)
X			bitrestrict = TRUE;
X		else if (strcmp(buf, "verbose") == 0)
X			verbose = TRUE;
X		else if (strcmp(buf, "mono-override") == 0 || strcmp(buf, "mono-overwrite") == 0)
X			mono_override = TRUE;
X		else if (strncmp(buf, baseprogname, strlen(baseprogname)) == 0) {
X			strtok(buf, ":");
X			strcpy(array[0], argv[0]);
X			newargc = 1;
X			while ((str = strtok(NULL, " \t")) != NULL)
X				strcpy(array[newargc++], str);
X
X			for (i = 1; i < *argc; i++)
X				strcpy(array[newargc++], argv[i]);
X
X			*argc = newargc;
X			for (i = 0; i < *argc; i++) {
X				argv[i] = (char *) malloc(sizeof (char) * strlen(array[i]) +1);
X				strcpy(argv[i], array[i]);
X			}
X		}
X	}
X	fclose(fp);
X}
X
char   *
itoa(i)
X{
X	char   *a;
X
X	if ((a = (char *) malloc(20 * sizeof (char))) == NULL)
X		error("malloc returned NULL");
X	sprintf(a, "%d", i);
X	return a;
X}
truncate(val, high, low)
X	int     val, high, low;
X{
X	val = MIN(val, high);
X	val = MAX(val, 0);
X	return val;
X}
X
setup_greylevelmap()
X{
X	int i;
X
X	for(i=0;i<256;i++) 
X		greylevelmap[i] = (unsigned char) i;
X}
END_OF_FILE
if test 3180 -ne `wc -c <'src/support.c'`; then
    echo shar: \"'src/support.c'\" unpacked with wrong size!
fi
# end of 'src/support.c'
fi
if test -f 'src/winlev.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/winlev.c'\"
else
echo shar: Extracting \"'src/winlev.c'\" \(3613 characters\)
sed "s/^X//" >'src/winlev.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include "defs.h"
X
char   *progname;
char   *filename;
Pixrect *pr1, *pr2;
int     old_level, old_window;
int     max_level, min_level;
int     lower, upper;
int     table[10000];
int     window, level;
X
X#ifdef STANDALONE
main(argc, argv, envp)
X#else
winlev_main(argc, argv, envp)
X#endif
X	int     argc;
X	char  **argv;
X	char  **envp;
X{
X	register int i, j;
X	int     levels;
X	float   winlev_calc_mean();
X	colormap_t colormap;
X
X	window = level = -1;
X	progname = strsave(argv[0]);
X	parse_profile(&argc, argv, envp);
X
X	while ((gc = getopt(argc, argv, "w:l:")) != EOF)
X		switch (gc) {
X		case 'w':
X			window = atoi(optarg);
X			break;
X		case 'l':
X			level = atoi(optarg);
X			break;
X		case '?':
X			errflag++;
X			break;
X		}
X
X	if (errflag)
X		error((char *) 0, "Usage: %s: [-w window] [-l level] [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	if (bitrestrict)
X		levels = calc_max(pr1)+1;
X	else
X		levels = MAXLEVEL(pr1->pr_depth);
X
X	if (window == -1)
X		window = MAXLEVEL(8) * 2;
X	if (level == -1)
X		level = (int) winlev_calc_mean(pr1);
X
X	if (level > levels || level < 0)
X		error("level setting outside range of levels in image");
X
X	if (window > levels || window < 0)
X		error("window setting outside range of levels in image");
X
X	if ((pr2 = mem_create(pr1->pr_size.x, pr1->pr_size.y, 8)) == NULL)
X		error("mem_create returned NULL");
X
X	min_level = 0;
X	max_level = levels;
X	old_window = levels;
X	old_level = levels / 2;
X	setuptable();
X	winlev_convert_to_8bits(pr1, pr2);
X
X	pr_dump(pr2, stdout, &colormap, RT_STANDARD, 0);
X}
X/* initialise lookup table for current window & level */
setuptable()
X{
X	register int i;
X	register int *t;
X	register int new_lower, new_upper;
X	int     old_lower, old_upper;
X	double  m, cumulative_greylevel;
X
X	if (window != 0)
X		m = 253. / (float) window;  /* 253 = No. greylevels * - 1 */
X
X	cumulative_greylevel = 1.;
X	new_lower = level - window / 2;
X	new_upper = level + window / 2;
X	old_lower = old_level - old_window / 2;
X	old_upper = old_level + old_window / 2;
X
X	lower = MIN(old_lower, new_lower);
X	upper = MAX(old_upper, new_upper);
X
X	lower = 0;
X	upper = max_level;
X	t = &table[lower];
X	for (i = lower; i < upper; i++)
X		if (i <= new_lower)
X			*t++ = 1;
X		else if (i >= new_upper)
X			*t++ = 254;
X		else {
X			*t++ = cumulative_greylevel;
X			cumulative_greylevel += m;
X		}
X	old_level = level;
X	old_window = window;
X}
X
winlev_convert_to_8bits(in, out)
X	Pixrect *in, *out;
X{
X	short  *ptr16;
X	int    *ptr32;
X	char   *ptr8;
X	register int i;
X	int     n;
X	int     mode = TRUE;
X
X#define ALL_PIXELS      TRUE
X
X	ptr8 = (char *) mpr_d(out)->md_image;
X	n = in->pr_size.x * in->pr_size.x;
X
X	switch (in->pr_depth) {
X	case 16:
X		ptr16 = (short *) mpr_d(in)->md_image;
X		for (i = 0; i < n; i++) {
X			if ((mode == ALL_PIXELS) || ((*ptr16 >= lower) && (*ptr16 <= upper)))
X				*ptr8 = *(table + (*ptr16));
X			ptr8++;
X			ptr16++;
X		}
X		break;
X	case 32:
X		ptr32 = (int *) mpr_d(in)->md_image;
X
X		for (i = 0; i < n; i++) {
X			if ((mode == ALL_PIXELS) || ((*ptr32 >= lower) && (*ptr32 <= upper)))
X				*ptr8 = *(table + (*ptr32));
X			ptr8++;
X			ptr16++;
X		}
X		break;
X	}
X}
X
X
float
winlev_calc_mean(pr)
X	Pixrect *pr;
X{
X	register int i, j;
X	int     sum;
X
X	sum = 0;
X	for (j = 0; j < pr->pr_size.y; j++)
X		for (i = 0; i < pr->pr_size.x; i++)
X			sum += pr_get(pr, i, j);
X
X	return (sum / (pr->pr_size.x * pr->pr_size.y));
X}
END_OF_FILE
if test 3613 -ne `wc -c <'src/winlev.c'`; then
    echo shar: \"'src/winlev.c'\" unpacked with wrong size!
fi
# end of 'src/winlev.c'
fi
echo shar: End of archive 4 \(of 10\).
cp /dev/null ark4isdone
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