home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume40
/
lic
/
part05
< prev
next >
Wrap
Text File
|
1993-11-09
|
62KB
|
2,065 lines
Newsgroups: comp.sources.misc
From: casey@gauss.llnl.gov (Casey Leedom)
Subject: v40i119: lic - LLNL Line Integral Convolution, v1.3, Part05/09
Message-ID: <1993Nov9.170952.26760@sparky.sterling.com>
X-Md4-Signature: 04c794282e80fb12c44bc143dd9fe995
Sender: kent@sparky.sterling.com (Kent Landfield)
Organization: Sterling Software
Date: Tue, 9 Nov 1993 17:09:52 GMT
Approved: kent@sparky.sterling.com
Submitted-by: casey@gauss.llnl.gov (Casey Leedom)
Posting-number: Volume 40, Issue 119
Archive-name: lic/part05
Environment: UNIX
Supersedes: lic: Volume 38, Issue 104
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: lic.1.3/liblic/LIC_Create.3 lic.1.3/lic/lic.1
# lic.1.3/lic/lic.c lic.1.3/test/gl-disp.c
# Wrapped by kent@sparky on Tue Nov 9 10:09:39 1993
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 5 (of 9)."'
if test -f 'lic.1.3/liblic/LIC_Create.3' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lic.1.3/liblic/LIC_Create.3'\"
else
echo shar: Extracting \"'lic.1.3/liblic/LIC_Create.3'\" \(11379 characters\)
sed "s/^X//" >'lic.1.3/liblic/LIC_Create.3' <<'END_OF_FILE'
X.\" Copyright (c) 1993 The Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\" 1. Redistributions of source code must retain the above copyright
X.\" notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\" notice, this list of conditions and the following disclaimer in the
X.\" documentation and/or other materials provided with the distribution.
X.\" 3. All advertising materials mentioning features or use of this software
X.\" must display the following acknowledgement:
X.\" This product includes software developed by the University of
X.\" California, Lawrence Livermore National Laboratory and its
X.\" contributors.
X.\" 4. Neither the name of the University nor the names of its contributors
X.\" may be used to endorse or promote products derived from this software
X.\" without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.de Hd
X.ds Dt \\$4
X..
X.Hd $Header: /usr/local/src/lic/liblic/RCS/LIC_Create.3,v 1.8 1993/10/28 01:08:08 casey Exp $
X.TH LIC_CREATE 3 \*(Dt
X.SH NAME
XLIC_Create \- create Line Integral Convolution object instance
X.SH SYNOPSIS
X.nf
X#include <lic.h>
X
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX('u
XLIC *\fBLIC_Create\fP(unsigned char *\fIInputImage\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX(*'u
X int \fIiiXres\fP,
X int \fIiiYres\fP,
X int \fIiiZres\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX('u
X float *\fIInputField\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX(*'u
X int \fIifXres\fP,
X int \fIifYres\fP,
X int \fIifZres\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX('u
X unsigned char *\fIOutputImage\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX(*'u
X LIC_Filter \fIFilter\fP,
X int \fINormalizationType\fP,
X int \fINormalized\fP,
X double \fILength\fP,
X double \fIFrequency\fP,
X int \fIVariableLength\fP,
X int \fIVariableSpeed\fP,
X int \fIDefaultRed\fP,
X int \fIDefaultGreen\fP,
X int \fIDefaultBlue\fP,
X int \fIDefaultAlpha\fP,
X.ta \w'LIC *\fBLIC_Create\fP('u +\w'unsigned charXXX'u
X void (*\fIUpdateUser\fP)(double \fIpercent-complete\fP),
X void (*\fIReportError\fP)(const char *\fImessage\fP))
X.DT
X.fi
X.SH DESCRIPTION
X.if t .ds pi \(*p
X.if n .ds pi Pi
X.B LIC_Create
Xconstructs an instance of a LIC object.
X.PP
X.I InputImage
Xis the input image to be convolved,
X.I InputField
Xis the input vector field which controls the directional convolution and
X.I OutputImage
Xis the output image where Line Integral Convolution results will be placed.
X.IR iiXres ,
X.I iiYres
Xand
X.I iiZres
Xare the X, Y and Z sizes of
X.IR InputImage .
X.IR ifXres ,
X.I ifYres
Xand
X.I ifZres
Xare the X, Y and Z sizes of
X.I InputField
Xand
X.IR OutputImage .
XIf
X.I InputImage
Xis smaller than
X.I InputField
Xin some dimension, references to
X.I InputImage
Xpixels corresponding to
X.I InputField
Xcells will be wrapped toriodally.
XIf
X.B NULL
Xis passed for
X.IR OutputImage ,
X.B LIC_Create
Xwill automatically allocate space for it.
X.PP
XThe input and output images and input vector field are stored as raw binary
Xrow major arrays.
X.PP
X.I InputImage
Xand
X.I OutputImage
Xare arrays of pixels. Each pixel is 1 to 4 bytes and must match
Xthe pixel size configured into the LIC library when it was compiled (see
X.B LIC_ConfiguredPixelSize
Xin the
X.B LIC_Query
Xmanual page).
X.PP
X.I InputField
Xis an array of single precision floating point Cartesian vectors. Each vector
Xis of rank equal to the dimension of the data, 2 for two-dimensional
Xfields and 3 for three-dimensional fields. The vectors are stored as
Xtwo- and three-tuples, respectively, ordered as x-ordinate, y-ordinate
Xand, if applicable, z-ordinate.
X.PP
XNote that vectors with positive y-coordinates point towards lower row
Xcoordinates. That is, towards the \(lqtop\(rq of a two-dimensional
Ximage. Positive x-coordinates and z-coordinates point towards larger
Xcolumn and plane coordinates, respectively. The y-coordinate flip is
Xa consequence of using the left-handed image field coordinate system
Xto access the input vector field which contains right-handed vectors.
X.PP
X.I Filter
Xmust be a pointer to a LIC_Filter type function:
X.PP
X.RS
X.nf
Xdouble \fIFilter\fP(LIC *\fIThis\fP, double \fIa\fP, double \fIb\fP, int \fIspeed\fP)
X.fi
X.RE
X.PP
X.I Filter
Xshould return the integral of the filter kernel between
X.I a
Xand
X.IR b .
X.I speed
Xspecifies the speed with respect to phase shift animation that
X.I Filter
Xshould use for its filter kernel.
X.I speed
Xis used to implement the variable speed option (though many filters ignore
Xthis parameter).
X.PP
XThe following filters are supplied with the LIC library:
X.PP
X.RS
X.nf
Xdouble \fBLIC_Box\fP(LIC *\fIThis\fP, double \fIa\fP, double \fIb\fP, int \fIspeed\fP)
Xdouble \fBLIC_Ripple\fP(LIC *\fIThis\fP, double \fIa\fP, double \fIb\fP, int \fIspeed\fP)
Xdouble \fBLIC_Ramp\fP(LIC *\fIThis\fP, double \fIa\fP, double \fIb\fP, int \fIspeed\fP)
Xdouble \fBLIC_Select\fP(LIC *\fIThis\fP, double \fIa\fP, double \fIb\fP, int \fIspeed\fP)
X.fi
X.RE
X.PP
XThey implement a box filter, a Hanning windowed Hanning ripple filter,
Xa ramp filter and a pixel selection filter, respectively. See
X.BR LIC_Filters (3)
Xfor more information on LIC filters and the integration process.
X.PP
X.I NormalizationType
Xspecifies the type of normalization to be used:
X.B LIC_FIXED
Xor
X.BR LIC_VARIABLE .
XWith fixed normalization, output image pixels will be attenuated near
Xinput vector field singularities and edges of the input field where
Xvectors are not parallel to the edges. With variable normalization,
Xoutput image pixels will maintain an even brightness level (relative
Xto the input image pixels they are summed from).
X.PP
X.I Normalized
Xspecifies that the input vector field is normalized: all vectors have
Xmagnitude 1 or 0. If the vector field is not normalized, a separate
Xnormalized copy will be constructed for use in the convolution
Xmethods. This may affect the ability to handle large problems because
Xof memory constraints. If this becomes a problem, you may want to
Xconsider pre-normalizing the vector field. However, this isn't an
Xoption if you want to do variable length or variable speed convolution
Xsince the vector magnitudes are used to control the length and speed
Xvariations (see variable length and variable speed documentation
Xbelow).
X.PP
X.I Length
Xspecifies the length of the filter kernel. The filter kernel will actually be
X.RI 2* Length ,
Xextending from
X.RI - Length
Xto
X.RI + Length .
XIt is an error to specify a
X.I length
Xless than
X.BR 0 .
X.PP
X.I Frequency
Xspecifies the frequency of the filter kernel.
X.I Frequency
Xis interpreted as the number of cycles of the filter kernel over the domain
X.RB - \*(pi
Xto
X.BR \*(pi .
X(See
X.B LIC_ChangePhase
Xin the
X.BR LIC_Modify (3)
Xmanual page for a description of how to change the phase of the filter
Xkernel.)
X.I Frequency
Xis scaled to the length of the filter kernel. Thus, a
X.I Frequency
Xof 2 will cause two repetitions of the filter kernel across the domain
X.RI - Length
Xto
X.RI + Length .
X.I Frequency
Xmust be non-zero and positive.
XCurrently, the only filter supplied with the LIC library that uses this
Xoption is
X.BR LIC_Ripple .
X.PP
X.I VariableLength
Xis a boolean flag which, when TRUE, specifies that variable length filtering
Xshould be performed. The LIC filter length for each vector \fIv\fP will
Xvary from 0 to
X.I Length
Xbased on the vector's magnitude. This magnitude scaling is performed
Xby finding the maximum magnitude vector in the input vector field,
X\fImax_v\fP, and then using a filter length equal to
X\fILength\fP * ||\fIv\fP|| / ||\fImax_v\fP||.
XThe filter will be dilated to match the length of the convolution.
XThis prevents any visual artifacts which might occur because of abrupt
Xfilter truncation if the filter were not dilated.
X.PP
X.I VariableSpeed
Xis a boolean flag which, when TRUE, specifies that variable
X.I speed
Xfiltering should be performed.
XHigh magnitude regions of the vector field will use high
X.I speed
Xversions of the filter. These higher speeds variations are typically
Xphase multiplied versions of the base phase and are used in periodic
Xmotion animations to give the appearance of higher speed in higher magnitude
Xregions of the vector field.
XHowever, it is up to each filter to implement its own interpretation of
X.IR speed .
X.PP
XFor the ripple filter, the speed variations use a different phase for each
Xvector
X.I v
Xbased on its magnitude. These phase variations vary from
X.I Phase
Xto 3 *
X.IR Phase .
X.PP
XVariable speed filtering is currently only implemented by the ripple
Xfilter (it doesn't have any effect on the box filter and is of dubious
Xvalue for the ramp filter.)
X.PP
X.IR DefaultRed ,
X.IR DefaultGreen ,
X.I DefaultBlue
Xand
X.I DefaultAlpha
Xdefine the default red, green, blue and alpha pixel values to use to represent
Xzero magnitude vectors. A value of
X.B -1
Xspecifies that the underlaying input image pixel value should be used.
XFor
X.B MONOCHROME
Ximages,
X.I default-alpha
Xcontrols the default pixel value.
X.PP
X.I UpdateUser
Xshould be
X.B NULL
Xor a pointer to user supplied function. If
X.RB non- NULL ,
Xit will be called by
X.B LIC_ComputeImage
Xfrom time to time to report computation progress with a
X.I percent-complete
Xvalue between 0.0 and 100.0.
X.PP
X.B ReportError
Xshould be
X.B NULL
Xor a pointer to user supplied function. If
X.RB non- NULL ,
Xit will be called by the LIC library routines to report various errors.
XTypically these will be to report memory allocation failure or errors
Xin user supplied parameters. A
X.B NULL
Xterminated character string value,
X.IR message ,
Xwill be passed to
X.BR ReportError .
X.I message
Xwill not contain a trailing newline.
X.SH "RETURN VALUES"
X.B NULL
Xwill be returned if
X.B LIC_Create
Xis unable to allocate memory for the new LIC instance, otherwise a pointer
Xto the new instance is returned.
X.SH ERRORS
XLIC_Create: Unable to allocate memory for LIC instance variable
X.PP
XLIC_Create: Unable to allocate memory for normalized input vector field
X.PP
XLIC_Create: Unable to allocate memory for output image
X.SH "SEE ALSO"
X.BR LIC (3),
X.BR LIC_Destroy (3),
X.BR LIC_Modify (3),
X.BR LIC_Query (3)
X.SH BUGS
XIf a negative
X.I Length
Xis specified, a length of 0 will be used instead.
XIf a negative or zero
X.I Frequency
Xis specified, a frequency of 1e-6 will be used instead. In both cases error
Xmessages should probably be output.
X.SH STANDARDS
XThis is unsupported, non-standard software. It is not the subject of any
Xstandards effort.
END_OF_FILE
if test 11379 -ne `wc -c <'lic.1.3/liblic/LIC_Create.3'`; then
echo shar: \"'lic.1.3/liblic/LIC_Create.3'\" unpacked with wrong size!
fi
# end of 'lic.1.3/liblic/LIC_Create.3'
fi
if test -f 'lic.1.3/lic/lic.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lic.1.3/lic/lic.1'\"
else
echo shar: Extracting \"'lic.1.3/lic/lic.1'\" \(12167 characters\)
sed "s/^X//" >'lic.1.3/lic/lic.1' <<'END_OF_FILE'
X.\" Copyright (c) 1993 The Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\" 1. Redistributions of source code must retain the above copyright
X.\" notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\" notice, this list of conditions and the following disclaimer in the
X.\" documentation and/or other materials provided with the distribution.
X.\" 3. All advertising materials mentioning features or use of this software
X.\" must display the following acknowledgement:
X.\" This product includes software developed by the University of
X.\" California, Lawrence Livermore National Laboratory and its
X.\" contributors.
X.\" 4. Neither the name of the University nor the names of its contributors
X.\" may be used to endorse or promote products derived from this software
X.\" without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.de Hd
X.ds Dt \\$4
X..
X.Hd $Header: /usr/local/src/lic/lic/RCS/lic.1,v 1.14 1993/11/05 00:30:51 casey Exp $
X.TH LIC 1 \*(Dt
X.SH NAME
Xlic \- Line Integral Convolution processor
X.SH SYNOPSIS
X.nf
X\fBlic\fP [\fIoptions\fP] \fIinput-image\fP \fIinput-vector-field\fP \fIoutput-image\fP
X.fi
X.SH DESCRIPTION
X.if t .ds pi \(*p
X.if n .ds pi Pi
X.B lic
Xis a command line interface to the
X.I "Line Integral Convolution"
Xlibrary. Line Integral Convolution was designed for vector field
Xvisualization but has applications in a number of other domains
Xincluding image processing, special effects and artistic rendering.
XFor an in depth description of Line Integral Convolution, see
X.BR LIC (3).
X.PP
XThe input and output files are stored as raw binary files without any
Xheaders. The files are organized as sequential row major (C-style)
Xarrays.
X.PP
XThe
X.I input-image
Xand
X.I output-image
Xfiles are arrays of pixels. Each pixel is 1 to 4 bytes and must match
Xthe pixel size configured into
X.B lic
Xwhen it was compiled (see
X.B LIC_ConfiguredPixelSize
Xin the
X.B LIC_Query
Xmanual page).
X.PP
XThe
X.I input-vector-field
Xfile is an array of single precision floating point vectors. Each vector
Xis of rank equal to the dimension of the data, 2 for two-dimensional
Xfields and 3 for three-dimensional fields. The vectors are stored as
Xtwo- and three-tuples, respectively, ordered as x-coordinate, y-coordinate
Xand, if applicable, z-coordinate.
X.PP
XNote that vectors with positive y-coordinates point towards lower row
Xcoordinates. That is, towards the \(lqtop\(rq of a two-dimensional
Ximage. Positive x-coordinates and z-coordinates point towards larger
Xcolumn and plane coordinates, respectively. The y-coordinate flip is
Xa consequence of using the left-handed image field coordinate system
Xto access the input vector field which contains right-handed vectors.
X.PP
XThe
X.I output-image
Xis created by
X.BR lic .
XThe x-y-z size of the file is equal to that of the
X.IR input-vector-field .
XAs a safety feature
X.B lic
Xwill never overwrite an existing file.
X.PP
XOptions available are:
X.PP
X\fB\-x\fP \fIx-extent\fP (required parameter, \fBno default\fP)
X.br
X\fB\-y\fP \fIy-extent\fP (required parameter, \fBno default\fP)
X.br
X\fB\-z\fP \fIz-extent\fP (default: \fB1\fP)
X.RS 5
XSets the
X.IR x ,
X.I y
Xand
X.I z
Xsize of
X.IR input-vector-field .
XThe
X.B \-x
Xand
X.B \-y
Xoptions are not optional. They must be provided. The
X.B \-z
Xis optional and defaults to the value of
X.BR 1 .
X.RE
X.PP
X\fB\-i\fP \fIi-extent\fP (default: \fIx-extent\fP)
X.br
X\fB\-j\fP \fIj-extent\fP (default: \fIy-extent\fP)
X.br
X\fB\-k\fP \fIk-extent\fP (default: \fIz-extent\fP)
X.RS 5
XSets the
X.IR x ,
X.I y
Xand
X.I z
Xsize of
X.IR input-image .
XIf not specified, they will default to the same values specified for
X.IR input-vector-field .
XThe sizes for
X.I input-image
Xand
X.I input-vector-field
Xneed not match in any way. If
X.I input-image
Xis smaller than
X.I input-vector-field
Xin some dimension, references to
X.I input-image
Xpixels corresponding to
X.I input-vector-field
Xcells will be wrapped toriodally.
X.RE
X.TP 5
X\fB\-f\fP \fIfilter\fP (default: \fBbox\fP)
XSpecifies the filter shape to use for the LIC.
XAvailable filters are:
X.PP
X.RS
X.TP 8
X.B box
XSpecifies a constant box shape filter: \fIk\fP(\fIs\fP) = 1.
XAll input image pixels along LIC paths will be given equal weight.
X.TP 8
X.B ripple
XSpecifies a phase shifted Hanning ripple function, windowed by a Hanning
Xfunction: \fIk\fP(\fIs\fP) = (cos(\fId\fP*\fIs\fP + \fIphase\fP) + 1)/2
X* (cos(\fIc\fP*\fIs\fP) + 1)/2.
XWhere
X.I d
Xand
X.I c
Xare the dilation constants for the ripple and window functions,
Xrespectively, and
X.I phase
Xis the phase shift of the ripple function.
X.I d
Xand
X.I c
Xcontrol the number of cycles of the Hanning functions over the filter kernel
Xfrom
X.RI - L
Xto
X.RI + L .
X.I d
Xis controlled by the
X.B \-d
Xoption and
X.I c
Xis always equal to
X.BR 1 .
X.I phase
Xis controlled by the
X.B \-p
Xoption.
X.TP 8
X.B ramp
XSpecifies a ramp shape filter whose value is
X.B 0
Xat
X.RI - L
Xand
X.B 1
Xat
X.RI + L :
X\fIk\fP(\fIs\fP) = (\fIs\fP + \fIL\fP) / 2\fIL\fP.
X.TP 8
X.B select
XSpecifies a filter which is used to select an approximately one pixel
Xwide window near the end of the advected streamline and place it at
Xthe advection starting pixel. This is achieved using a narrow
XGaussian filter and placing this filter near the end of the advected
Xstreamline. This can be used to produce a warp of the input image.
X.RE
X.TP 5
X\fB\-n\fP \fInormalization\fP (default: \fBvariable\fP)
XSpecifies the type of normalization to be used:
X.B fixed
Xor
X.BR variable .
XWith
X.B fixed
Xnormalization, output image pixels will be attenuated near input vector
Xfield singularities and edges of the input vector field where vectors are not
Xparallel to the edges.
XWith
X.B variable
Xnormalization, output image pixels will maintain an even brightness level
X(relative to the input image pixels they are summed from).
X.TP 5
X\fB\-N\fP
XSpecifies that the input vector field is normalized: all vectors have
Xmagnitude 1 or 0. If the vector field is not normalized, a separate
Xnormalized copy will be constructed for use in the convolution
Xmethods. This may affect the ability to handle large problems because
Xof memory constraints. If this becomes a problem, you may want to
Xconsider pre-normalizing the vector field. However, this isn't an
Xoption if you want to do variable length or variable speed convolution
Xsince the vector magnitudes are used to control the length and speed
Xvariations (see variable length and variable speed documentation
Xbelow).
X.TP 5
X\fB\-l\fP \fIfilter-length\fP (default: \fB10.0\fP)
XSpecifies the length,
X.IR L ,
Xof the filter kernel. The length of the filter kernel will actually be
X.RI 2* L ,
Xextending from
X.RI - L
Xto
X.RI + L .
X.PP
X\fB\-d\fP \fIfilter-frequency\fP (default: \fB3.0\fP)
X.br
X\fB\-p\fP \fIfilter-phase\fP (default: \fB0.0\fP)
X.RS 5
XSpecifies the frequency and phase of the filter kernel.
X.I filter-frequency
Xis interpreted as the number of cycles of the filter kernel over the domain
X.RB - \*(pi
Xto
X.BR \*(pi .
X.I filter-phase
Xis interpreted as the phase offset of the filter kernel in the same domain.
XBoth
X.I filter-frequency
Xand
X.I filter-phase
Xare scaled to the length of the filter kernel. Thus, a
X.I filter-frequency
Xof 2 will cause two repetitions of the filter kernel across the domain
X.RI - L
Xto
X.RI + L .
XCurrently, only the
X.B ripple
Xfilter uses these options.
X.RE
X.TP 5
X\fB\-L\fP
XSpecifies that variable length filtering should be performed. The LIC
Xfilter length for each vector \fIv\fP will vary from 0 to
X.I L
Xbased on the vector's magnitude. This magnitude scaling is performed
Xby finding the maximum magnitude vector in the input vector field,
X\fImax_v\fP, and then using a filter length equal to
X\fIL\fP * ||\fIv\fP|| / ||\fImax_v\fP||.
XThe filter will be dilated to match the length of the convolution.
XThis prevents any visual artifacts which might occur because of abrupt
Xfilter truncation if the filter were not dilated.
X.TP 5
X\fB\-S\fP
XSpecifies that variable
X.I speed
Xfiltering should be performed.
XHigh magnitude regions of the vector field will use high
X.I speed
Xversions of the filter. These higher speeds variations are typically
Xfrequency scaled versions of the base filter and are used in periodic
Xmotion animations to give the appearance of higher speed in higher magnitude
Xregions of the vector field.
XHowever, it is up to each filter to implement its own interpretation of
X.IR speed .
X.PP
XFor the
X.B ripple
Xfilter, the speed variations use a different frequency for each vector
X.I v
Xbased on its magnitude. These frequency variations vary from 6 *
X.I filter-frequency
Xfor zero magnitude vectors to
X.I filter-frequency
Xfor maximum magnitude vectors. Variable speed filtering is currently only
Ximplemented by the
X.B ripple
Xfilter (it doesn't have any effect on the
X.B box
Xfilter and is of dubious value for the
X.B ramp
Xfilter.)
X.PP
X\fB\-r\fP \fIdefault-red\fP (default: \fB-1\fP)
X.br
X\fB\-g\fP \fIdefault-green\fP (default: \fB-1\fP)
X.br
X\fB\-b\fP \fIdefault-blue\fP (default: \fB-1\fP)
X.br
X\fB\-a\fP \fIdefault-alpha\fP (default: \fB-1\fP)
X.RS 5
XDefine the default red, green, blue and alpha pixel values to use to represent
Xzero magnitude vectors. A value of
X.B -1
Xspecifies that the underlaying input image pixel value should be used.
XFor
X.B MONOCHROME
Ximages,
X.I default-alpha
Xcontrols the default pixel value.
X.RE
X.TP 5
X\fB\-t\fP \fIthreads\fP (default: \fB1\fP)
XSpecifies the number of parallel threads to use when computing
X.IR output-image .
XIf
X.BR 0 ,
Xthe maximum number of CPUs available for parallel processing on the
Xcurrent system will be used. Note that parallel processing support is
Xnot available on all systems. If a value other than
X.B 1
Xis specified on a system which does not support parallel processing, a
Xwarning will be issued and the calculation will proceed single
Xthreaded.
X.TP 5
X\fB\-T\fP
XCauses execution performance statistics to be displayed at the end of
Xthe computation. The statistics include wall clock time, CPU time,
XCPU utilization, cells processed per second, average convolution line
Xlength, etc.
X.TP 5
X\fB\-v\fP
XCauses verbose performance information to be displayed during the
Xexecution of the calculation. A progress message will be printed
Xperiodically detailing how much of the computation has been finished
Xand an estimate of the completion time for the entire computation.
XSpecifying
X.B \-v
Xautomatically implies
X.BR \-T .
X.TP 5
X\fB\-V\fP
XCauses configuration information about the LIC library version to be printed.
XCurrently the size of pixels and their types,
X.BR RGB ,
X.BR ABGR ,
X.BR MONOCHROME ,
Xetc. are controlled by library compile-time definitions.
X.SH ERRORS
XObjections to bad command line arguments, missing files, wrong size files,
Xoutput files already existing, etc. Additionally, complaints about not
Xbeing able to map files into memory
X.RB ( mmap
Xversion) or inability to allocate memory
X.RB ( malloc
Xversion).
X.SH "SEE ALSO"
X.BR LIC (3),
X.BR LIC_Filters (3)
X.SH BUGS
XPixel types and sizes are configured into the LIC software at compile time.
XOnly single precision vector field ordinate values are supported. These should
Xboth be handled dynamically at run time.
X.SH STANDARDS
XThis is unsupported, non-standard software. It is not the subject of any
Xstandards effort.
END_OF_FILE
if test 12167 -ne `wc -c <'lic.1.3/lic/lic.1'`; then
echo shar: \"'lic.1.3/lic/lic.1'\" unpacked with wrong size!
fi
# end of 'lic.1.3/lic/lic.1'
fi
if test -f 'lic.1.3/lic/lic.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lic.1.3/lic/lic.c'\"
else
echo shar: Extracting \"'lic.1.3/lic/lic.c'\" \(24791 characters\)
sed "s/^X//" >'lic.1.3/lic/lic.c' <<'END_OF_FILE'
X/*
X * $Header: /usr/local/src/lic/lic/RCS/lic.c,v 1.31 1993/11/05 00:30:51 casey Exp $
X */
X
X/*
X * Copyright (c) 1993 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Lawrence Livermore National Laboratory and its
X * contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#ifndef lint
X static char rcsid[] = "$Header: /usr/local/src/lic/lic/RCS/lic.c,v 1.31 1993/11/05 00:30:51 casey Exp $";
X static char copyright[] =
X "Copyright (c) 1993 The Regents of the University of California.\n"
X "All rights reserved.\n";
X#endif
X
X
X/*
X * UNIX command line interface to the Line Integral Convolution library.
X */
X
X
X#include <stdlib.h>
X#include <unistd.h>
X#include <errno.h>
X#include <string.h>
X#include <stdio.h>
X#include <time.h>
X#include <sys/times.h>
X#include <sys/types.h>
X
X#include <fcntl.h>
X#include <math.h>
X#include <sys/stat.h>
X
X#if defined(HAS_MMAP)
X# include <sys/mman.h>
X#endif
X
X#include <lic.h>
X
X
X#ifdef NEED_STRERROR
X /*
X * strerror is supposed to be defined in <string.h> and supplied in the
X * standard C library according to the ANSI C X3.159-1989 specification,
X * but Sun OS 4.1.1 fails to define or supply it ... Unfortunately the
X * only way we can control this is with an externally supplied define.
X */
X extern int errno; /* system error number */
X extern char *sys_errlist[]; /* system error messages */
X extern int sys_nerr; /* number of entries in sys_errlist */
X
X static char *
X strerror(int err)
X {
X if (err < 0 || err >= sys_nerr) {
X static char msg[100];
X
X sprintf(msg, "system error number %d", err);
X return(msg);
X }
X return(sys_errlist[err]);
X }
X#endif
X
X
X/*
X * Arguments
X * =========
X */
Xstatic char *usage =
X"usage: %s [options] input-image input-vector-field output-image\n"
X" -x x-extent - input-vector-field X extent (required: no default)\n"
X" -y y-extent - input-vector-field Y extent (required: no default)\n"
X" -z z-extent - input-vector-field Z extent (default: 1)\n"
X" -i i-extent - input-image X extent (default: x-extent)\n"
X" -j j-extent - input-image Y extent (default: y-extent)\n"
X" -k k-extent - input-image Z extent (default: z-extent)\n"
X" -f filter - 'box', 'ripple', 'ramp' or (default: 'box')\n"
X" 'select'\n"
X" -n normalization - 'fixed' or 'variable' (default: 'variable')\n"
X" -N - input vector field already normalized\n"
X" -l filter-length - (default: 10.0)\n"
X" -d filter-frequency - (default: 3.0)\n"
X" -p filter-phase - (default: 0.0)\n"
X" -L - vary filter-length based on vector magnitude\n"
X" -S - vary filter-phase based on vector magnitude\n"
X" -r default-red - for zero vectors (default: -1)\n"
X" -g default-green - for zero vectors (default: -1)\n"
X" -b default-blue - for zero vectors (default: -1)\n"
X" -a default-alpha - for zero vectors (default: -1)\n"
X" -t threads - number of parallel threads (default: 1)\n"
X" -T - overall timing information\n"
X" -v - verbose progress and overall timing information\n"
X" -V - version information\n"
X ;
X
Xstatic char *myname; /* argv[0]: name we were invoked by */
Xstatic int size_x; /* -x: X extent */
Xstatic int size_y; /* -y: Y extent */
Xstatic int size_z = 1; /* -z: Z extent (default 1) */
Xstatic int size_i; /* -i: input image X extent */
Xstatic int size_j; /* -j: input image Y extent */
Xstatic int size_k; /* -k: input image Z extent */
Xstatic LIC_Filter
X filter = LIC_Box; /* -f: filter */
Xstatic int normalization = LIC_VARIABLE;
X /* -n: normalization */
Xstatic int normalized = FALSE; /* -N: input vectors prenormalized */
Xstatic double filter_length = 10.0; /* -l: filter length */
Xstatic double filter_frequency = 3.0; /* -d: filter frequency */
Xstatic double filter_phase = 0.0; /* -p: filter phase */
Xstatic int vary_length = FALSE; /* -L: vary length by vector mag. */
Xstatic int vary_speed = FALSE; /* -S: vary phase by vector mag. */
Xstatic int default_red = -1; /* -r: default red for zero vector */
Xstatic int default_green = -1; /* -g: default green ... */
Xstatic int default_blue = -1; /* -b: default blue ... */
Xstatic int default_alpha = -1; /* -a: default alpha ... */
Xstatic int threads = 1; /* -t: number of parallel threads */
Xstatic int timing = FALSE; /* -T: display timing information */
Xstatic int verbose = FALSE; /* -v: display progress information */
Xstatic int version = FALSE; /* -V: display version information */
X
Xstatic char *in_img; /* input image filename */
Xstatic char *in_vec; /* input vector field filename */
Xstatic char *out_img; /* output image filename */
X
X
X/*
X * Local variables
X * ===============
X */
Xstatic time_t t0; /* time we started/ended the LIC */
Xstatic clock_t t0_clk, tN_clk; /* calculation */
Xstatic struct tms t0_tms, tN_tms;
X
Xstatic void *in_img_addr, /* virtual addresses of memory */
X *in_vec_addr, /* mapped input image, input */
X *out_img_addr; /* vector field and output image */
Xstatic off_t in_img_size, /* sizes of image and vector files */
X in_vec_size,
X out_img_size;
X#if !defined(HAS_MMAP)
X static int out_img_fd; /* output image file descriptor */
X#endif
X
X
X/*
X * Local routines
X * ==============
X */
Xint main(int argc, char *argv[]);
Xstatic void ParseArguments(int argc, char *argv[]);
Xstatic void LoadFiles(void);
Xstatic void UnloadFiles(void);
Xstatic void LicFiles(void);
Xstatic void PrintLicStatus(double PercentDone);
Xstatic void PrintLicError(const char *message);
X
X
Xint
Xmain(int argc, char *argv[])
X{
X ParseArguments(argc, argv);
X LoadFiles();
X LicFiles();
X UnloadFiles();
X exit(EXIT_SUCCESS);
X /*NOTREACHED*/
X}
X
X
Xstatic void
XParseArguments(int argc, char *argv[])
X{
X int ch;
X#if defined(HAS_HP_GETOPT)
X extern int getopt(int, char * const [], const char *);
X#else
X extern int getopt(int, char **, char *);
X#endif
X extern char *optarg;
X extern int optind;
X
X myname = strrchr(argv[0], '/');
X if (myname != NULL)
X myname++;
X else
X myname = argv[0];
X while ((ch = getopt(argc, argv, "x:y:z:i:j:k:f:n:Nl:d:p:LSr:g:b:a:t:TvV")) != EOF)
X switch ((char)ch)
X {
X default:
X case '?':
X (void)fprintf(stderr, "%s: unknown option -%c\n",
X myname, ch);
X (void)fprintf(stderr, usage, myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X
X case 'x':
X size_x = atoi(optarg);
X if (size_x <= 0)
X goto bad_size;
X break;
X
X case 'y':
X size_y = atoi(optarg);
X if (size_y <= 0)
X goto bad_size;
X break;
X
X case 'z':
X size_z = atoi(optarg);
X if (size_z <= 0)
X goto bad_size;
X break;
X
X case 'i':
X size_i = atoi(optarg);
X if (size_i <= 0)
X goto bad_size;
X break;
X
X case 'j':
X size_j = atoi(optarg);
X if (size_j <= 0)
X goto bad_size;
X break;
X
X case 'k':
X size_k = atoi(optarg);
X if (size_k <= 0)
X goto bad_size;
X break;
X
X bad_size:
X (void)fprintf(stderr, "%s: bad size specification: -%c %d"
X " -- must be greater than 0\n",
X myname, ch, atoi(optarg));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X
X case 'f':
X if (strcasecmp(optarg, "box") == 0)
X filter = LIC_Box;
X else if (strcasecmp(optarg, "ripple") == 0)
X filter = LIC_Ripple;
X else if (strcasecmp(optarg, "ramp") == 0)
X filter = LIC_Ramp;
X else if (strcasecmp(optarg, "select") == 0)
X filter = LIC_Select;
X else
X {
X (void)fprintf(stderr, "%: invalid filter type %s"
X " -- use 'box', 'ripple', 'ramp'"
X " or 'select'\n",
X myname, optarg);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X break;
X
X case 'n':
X if (strcasecmp(optarg, "fixed") == 0)
X normalization = LIC_FIXED;
X else if (strcasecmp(optarg, "variable") == 0)
X normalization = LIC_VARIABLE;
X else
X {
X (void)fprintf(stderr, "%: invalid normalization type %s"
X " -- use 'fixed' or 'variable'\n",
X myname, optarg);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X break;
X
X case 'N':
X normalized = TRUE;
X break;
X
X case 'l':
X filter_length = atof(optarg);
X if (filter_length < 0.0)
X {
X (void)fprintf(stderr, "%s: invalid filter length %f"
X " -- must be greater than or equal to 0.0\n",
X myname, filter_length);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X break;
X
X case 'd':
X filter_frequency = atof(optarg);
X if (filter_frequency <= 0.0)
X {
X (void)fprintf(stderr, "%s: invalid filter frequency %f"
X " -- must be greater than 0.0\n",
X myname, filter_length);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X break;
X
X case 'p':
X filter_phase = atof(optarg);
X break;
X
X case 'L':
X vary_length = TRUE;
X break;
X
X case 'S':
X vary_speed = TRUE;
X break;
X
X case 'r':
X default_red = atoi(optarg);
X if (default_red < -1 || default_red > 255)
X goto bad_color;
X break;
X
X case 'g':
X default_green = atoi(optarg);
X if (default_green < -1 || default_green > 255)
X goto bad_color;
X break;
X
X case 'b':
X default_blue = atoi(optarg);
X if (default_blue < -1 || default_blue > 255)
X goto bad_color;
X break;
X
X case 'a':
X default_alpha = atoi(optarg);
X if (default_alpha < -1 || default_alpha > 255)
X goto bad_color;
X break;
X
X bad_color:
X (void)fprintf(stderr, "%s: bad color specification: -%c %d"
X " -- must be between -1 and 255\n",
X myname, ch, atoi(optarg));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X
X case 't':
X threads = atoi(optarg);
X if (threads < 0)
X {
X (void)fprintf(stderr, "%s: invalid number of threads %d"
X " -- must be greather than or equal to 0\n",
X myname, threads);
X threads = 1;
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X break;
X
X case 'T':
X timing = TRUE;
X break;
X
X case 'v':
X verbose = TRUE;
X timing = TRUE;
X break;
X
X case 'V':
X version = TRUE;
X break;
X }
X
X if (version)
X (void)printf("%s: compiled with LIC library version %s"
X " using %d byte %s pixels\n",
X myname, LIC_VERSION,
X LIC_ConfiguredPixelSize(),
X LIC_ConfiguredPixelType());
X
X if (argc != optind + 3)
X {
X (void)fprintf(stderr, "%s: need three file options\n", myname);
X (void)fprintf(stderr, usage, myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_img = argv[optind + 0];
X in_vec = argv[optind + 1];
X out_img = argv[optind + 2];
X if (size_x == 0 || size_y == 0)
X {
X (void)fprintf(stderr, "%s: need both -x and -y options ...\n",
X myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (size_i == 0)
X size_i = size_x;
X if (size_j == 0)
X size_j = size_y;
X if (size_k == 0)
X size_k = size_z;
X}
X
X
X#if defined(HAS_MMAP)
X
X/*
X * Versions of LoadFiles and UnloadFiles for systems that support mmap(2).
X */
X
Xstatic void
XLoadFiles(void)
X /*
X * Map input and output files into virtual memory. Make sure that the
X * input files match the user specified sizes and pre-extend the
X * output file to its final length.
X */
X{
X char c;
X int fd;
X struct stat stbuf;
X
X /*
X * Map input vector field into virtual memory. (We always map the
X * input vector field first because it will always be larger than
X * either of the other two files. This should, hopefully, give the
X * operating system the best possible chance to find virtual address
X * space for the three files.)
X */
X fd = open(in_vec, O_RDONLY);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, in_vec, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (fstat(fd, &stbuf) < 0)
X {
X (void)fprintf(stderr, "%s: unable to stat %s: %s\n",
X myname, in_vec, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_vec_size = stbuf.st_size;
X if (size_x * size_y * size_z * sizeof(float) * (size_z == 1 ? 2 : 3)
X != in_vec_size)
X {
X (void)fprintf(stderr, "%s: input vector field size doesn't"
X " match %d * x=%d * y=%d * z=%d\n",
X myname, sizeof(float) * (size_z == 1 ? 2 : 3),
X size_x, size_y, size_z);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_vec_addr = mmap((void *)0, (int)in_vec_size, PROT_READ,
X MAP_SHARED, fd, (off_t)0);
X if ((int)in_vec_addr == -1)
X {
X (void)fprintf(stderr, "%s: unable to map %s: %s\n",
X myname, in_vec, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X
X /*
X * Map input image into virtual memory.
X */
X fd = open(in_img, O_RDONLY);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, in_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (fstat(fd, &stbuf) < 0)
X {
X (void)fprintf(stderr, "%s: unable to stat %s: %s\n",
X myname, in_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_img_size = stbuf.st_size;
X if (size_i * size_j * size_k * LIC_ConfiguredPixelSize() != in_img_size)
X {
X (void)fprintf(stderr, "%s: input image size doesn't"
X " match %d * x=%d * y=%d * z=%d\n",
X myname, LIC_ConfiguredPixelSize(),
X size_i, size_j, size_k);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_img_addr = mmap((void *)0, (int)in_img_size, PROT_READ,
X MAP_SHARED, fd, (off_t)0);
X if ((int)in_img_addr == -1)
X {
X (void)fprintf(stderr, "%s: unable to map %s: %s\n",
X myname, in_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X
X /*
X * Map output image into virtual memory. O_EXCL prevents lic from
X * overwriting a file that already exists. Have to use O_RDWR rather
X * than O_WRONLY because the OS will end up ``paging in pages from the
X * file'' (sic). In reality they'll just be zero fill on demand pages ...
X */
X fd = open(out_img, O_CREAT|O_EXCL|O_RDWR, 0666);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, out_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X out_img_size = size_x * size_y * size_z * LIC_ConfiguredPixelSize();
X (void)lseek(fd, out_img_size - 1, SEEK_SET);
X c = '\0';
X if (write(fd, &c, 1) != 1)
X {
X (void)fprintf(stderr, "%s: unable to preextend %s to %ld bytes: %s\n",
X myname, out_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X out_img_addr = mmap((void *)0, (int)out_img_size, PROT_WRITE,
X MAP_SHARED, fd, (off_t)0);
X if ((int)out_img_addr == -1)
X {
X (void)fprintf(stderr, "%s: unable to map %s: %s\n",
X myname, out_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X}
X
X
Xstatic void
XUnloadFiles(void)
X /*
X * Unmap input and output files from virtual memory.
X */
X{
X (void)munmap(in_img_addr, (int)in_img_size);
X (void)munmap(in_vec_addr, (int)in_vec_size);
X (void)munmap(out_img_addr, (int)out_img_size);
X}
X
X#else /* HAS_MMAP */
X
X/*
X * Versions of LoadFiles and UnloadFiles for systems that *don't* support
X * mmap(2).
X */
X
Xstatic void
XLoadFiles(void)
X /*
X * Load input files into malloc'ed memory and malloc memory for
X * output image. Make sure that the input files match the user
X * specified sizes. Preallocate output image on disk in order to
X * make sure we have the space to output the image later in
X * UnloadFiles.
X */
X{
X int fd;
X struct stat stbuf;
X
X /*
X * Load input image into malloc'ed memory.
X */
X fd = open(in_img, O_RDONLY);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, in_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (fstat(fd, &stbuf) < 0)
X {
X (void)fprintf(stderr, "%s: unable to stat %s: %s\n",
X myname, in_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_img_size = stbuf.st_size;
X if (size_i * size_j * size_k * LIC_ConfiguredPixelSize()
X != in_img_size)
X {
X (void)fprintf(stderr, "%s: input image size doesn't"
X " match %d * x=%d * y=%d * z=%d\n",
X myname, LIC_ConfiguredPixelSize(),
X size_i, size_j, size_k);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_img_addr = malloc(in_img_size);
X if (in_img_addr == NULL)
X {
X (void)fprintf(stderr, "%s: unable to allocate %u bytes for"
X " input image\n", myname, in_img_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (read(fd, in_img_addr, in_img_size) != in_img_size)
X {
X (void)fprintf(stderr, "%s: unable to read %u bytes from %s\n",
X myname, in_img_size, in_img);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X
X /*
X * Load input vector field into malloc'ed memory.
X */
X fd = open(in_vec, O_RDONLY);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, in_vec, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (fstat(fd, &stbuf) < 0)
X {
X (void)fprintf(stderr, "%s: unable to stat %s: %s\n",
X myname, in_vec, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_vec_size = stbuf.st_size;
X if (size_x * size_y * size_z * sizeof(float) * (size_z == 1 ? 2 : 3)
X != in_vec_size)
X {
X (void)fprintf(stderr, "%s: input vector field size doesn't"
X " match %d * x=%d * y=%d * z=%d\n",
X myname, (size_z == 1 ? 2 : 3),
X size_x, size_y, size_z);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X in_vec_addr = malloc(in_vec_size);
X if (in_vec_addr == NULL)
X {
X (void)fprintf(stderr, "%s: unable to allocate %u bytes for"
X " input vector field\n", myname, in_vec_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (read(fd, in_vec_addr, in_vec_size) != in_vec_size)
X {
X (void)fprintf(stderr, "%s: unable to read %u bytes from %s\n",
X myname, in_vec_size, in_vec);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X
X /*
X * Open output file and allocate space for output image (both in
X * memory and on disk). O_EXCL prevents lic from overwriting a file
X * that already exists.
X */
X out_img_fd = open(out_img, O_CREAT|O_EXCL|O_WRONLY, 0666);
X if (out_img_fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, out_img, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X out_img_size = size_x * size_y * size_z * LIC_ConfiguredPixelSize();
X out_img_addr = malloc(out_img_size);
X if (out_img_addr == NULL)
X {
X (void)fprintf(stderr, "%s: unable to allocate %u bytes for"
X " output image\n", myname, out_img_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (write(out_img_fd, out_img_addr, out_img_size) != out_img_size)
X {
X (void)fprintf(stderr, "%s: unable to extend %s to %u bytes\n",
X myname, out_img, out_img_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)lseek(out_img_fd, (off_t)0, SEEK_SET);
X}
X
X
Xstatic void
XUnloadFiles(void)
X /*
X * Free malloc'ed space used by input files, write output image and
X * free up it's malloc'ed memory.
X */
X{
X if (write(out_img_fd, out_img_addr, out_img_size) != out_img_size)
X (void)fprintf(stderr, "%s: unable to write %u bytes to %s!\n",
X myname, out_img_size, out_img);
X close(out_img_fd);
X free(in_img_addr);
X free(in_vec_addr);
X free(out_img_addr);
X}
X
X#endif /* HAS_MMAP */
X
X
Xstatic void
XLicFiles()
X /*
X * Execute LIC algorithm on arguments.
X */
X{
X LIC *lic;
X
X lic = LIC_Create((unsigned char *)in_img_addr, size_i, size_j, size_k,
X (float *) in_vec_addr, size_x, size_y, size_z,
X (unsigned char *)out_img_addr,
X filter, normalization, normalized,
X filter_length,
X filter_frequency,
X vary_length,
X vary_speed && (filter == LIC_Ripple),
X default_red, default_green, default_blue, default_alpha,
X verbose ? PrintLicStatus : (void (*)(double))NULL,
X PrintLicError);
X if (lic == (LIC *)NULL)
X {
X (void)fprintf(stderr, "%s: LIC_Create returned NULL!\n", myname);
X return;
X }
X LIC_ChangePhase(lic, filter_phase);
X LIC_ChangeNumThreads(lic, threads);
X
X /*
X * Build integral tables here so the build isn't computed as part of the
X * time to compute the image.
X */
X LIC_BuildIntegralTables(lic);
X
X t0 = time(NULL);
X t0_clk = times(&t0_tms);
X LIC_ComputeImage(lic);
X tN_clk = times(&tN_tms);
X
X LIC_Destroy(lic);
X
X if (timing)
X {
X long clk_tck = sysconf(_SC_CLK_TCK);
X#if defined(HAS_OLD_TIMES)
X double wall = (double)(time(NULL) - t0);
X#else
X double wall = (double)(tN_clk - t0_clk) / clk_tck;
X#endif
X double cpu = (double)( tN_tms.tms_utime - t0_tms.tms_utime
X + tN_tms.tms_cutime - t0_tms.tms_cutime)
X /clk_tck;
X double ncells = (double)(size_x * size_y * size_z);
X
X if (wall == 0.0)
X wall = 1.0e-6;
X if (cpu == 0.0)
X cpu = 1.0e-6;
X (void)printf("\n"
X "Performance statistics\n"
X "-------------------------------------------\n"
X "Wall time (seconds) = %.2f\n"
X "CPU time (seconds) = %.2f\n"
X "CPU utilization = %d%%\n"
X "Cells processed per Wall second = %.2f\n"
X "Cells processed per CPU second = %.2f\n"
X "Ave loop count = %.2f\n"
X "Ave length = %.2f\n",
X wall,
X cpu,
X (int)(cpu/wall*100),
X ncells/wall,
X ncells/cpu,
X lic->TotalLoopCount/ncells/2,
X lic->TotalLength/ncells/2);
X }
X}
X
X
Xstatic void
XPrintLicStatus(double PercentDone)
X /*
X * Output the current LIC progress statistics. (Only called if verbose
X * is TRUE.)
X */
X{
X if (PercentDone == 0.0)
X (void)printf("%s: %6.2f%% done ...\r", myname, PercentDone);
X else
X {
X /*
X * Should really use a smoothed exponentially decaying sample series
X * of CPU utilization to predict future CPU utilization to get better
X * estimates of completion times. But, I mean, get real. This is
X * really just a convenience! :-) So, we cheat and just use CPU
X * utilization since the start of the computation to predict future
X * CPU ultilization.
X */
X time_t t = time(NULL);
X time_t tN = t0 + (unsigned int)((double)(t-t0) * 100/PercentDone);
X char *cp = ctime(&tN);
X char cbuf[26];
X
X (void)strcpy(cbuf, cp);
X cbuf[24] = '\0';
X (void)printf("%s: %6.2f%% done, estimated completion: %s\r",
X myname, PercentDone, cbuf);
X }
X fflush(stdout);
X}
X
X
Xstatic void
XPrintLicError(const char *message)
X /*
X * Print an error reported by the LIC subroutine library.
X */
X{
X (void)fprintf(stderr, "%s: LIC library error: %s\n", myname);
X}
END_OF_FILE
if test 24791 -ne `wc -c <'lic.1.3/lic/lic.c'`; then
echo shar: \"'lic.1.3/lic/lic.c'\" unpacked with wrong size!
fi
# end of 'lic.1.3/lic/lic.c'
fi
if test -f 'lic.1.3/test/gl-disp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lic.1.3/test/gl-disp.c'\"
else
echo shar: Extracting \"'lic.1.3/test/gl-disp.c'\" \(7984 characters\)
sed "s/^X//" >'lic.1.3/test/gl-disp.c' <<'END_OF_FILE'
X/*
X * Quick program to display raw rasters on SGI using GL.
X */
X
X
X#include <stdlib.h>
X#include <unistd.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <string.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include <gl/gl.h>
X#include <gl/device.h>
X
X
X/*
X * Use LIC library to snag input raster file pixel format but could just
X * as easily be specified from the command line. PIXEL_TYPE should be
X * MONOCHOROME, RGB, BGR, ARGB, ABGR, RGBA or BGRA. PIXEL_SIZE should be 1,
X * 3 or 4 corresponding to the above types.
X */
X
X#include <lic.h>
X
X#define PIXEL_TYPE LIC_ConfiguredPixelType()
X#define PIXEL_SIZE LIC_ConfiguredPixelSize()
X
X
X/*
X * Command line arguments.
X */
Xstatic char *myname;
Xstatic char *file;
Xstatic int xres, yres, zres;
X
X
X/*
X * Local routines.
X */
Xstatic void ParseArguments(int argc, char *argv[]);
Xstatic unsigned char *LoadRaster(char *file, int pixels);
X
Xstatic unsigned long *ConvertRaster(unsigned char *raster, int pixels);
Xstatic void ConvertRasterMONO(unsigned long *buffer,
X unsigned char *raster, int pixels);
Xstatic void ConvertRasterRGB (unsigned long *buffer,
X unsigned char *raster, int pixels,
X int ir, int ig, int ib);
Xstatic void ConvertRasterARGB(unsigned long *buffer,
X unsigned char *raster, int pixels,
X int ia, int ir, int ig, int ib);
X
Xstatic void DisplayRaster(unsigned long *buffer,
X int xres, int yres, int zres);
X
X
Xint
Xmain(int argc, char *argv[])
X{
X unsigned char *raster;
X unsigned long *buffer;
X
X ParseArguments(argc, argv);
X raster = LoadRaster(file, xres*yres*zres);
X buffer = ConvertRaster(raster, xres*yres*zres);
X free(raster);
X DisplayRaster(buffer, xres, yres, zres);
X free(buffer);
X exit(0);
X}
X
X
Xstatic void
XParseArguments(int argc, char *argv[])
X /*
X * Grab arguments.
X */
X{
X myname = argv[0];
X if (argc != 4 && argc != 5)
X {
X (void)fprintf(stderr, "usage: %s file_name x_res y_res [z_res]\n", myname);
X exit(EXIT_FAILURE);
X }
X file = argv[1];
X xres = atoi(argv[2]);
X yres = atoi(argv[3]);
X if (argc == 4)
X zres = 1;
X else
X zres = atoi(argv[4]);
X}
X
X
Xstatic unsigned char *
XLoadRaster(char *file, int pixels)
X /*
X * Allocate space for input raster, load input raster from file and
X * return pointer to loaded raster.
X */
X{
X unsigned char *raster;
X size_t raster_size;
X int fd, cc;
X struct stat stbuf;
X
X raster_size = pixels * PIXEL_SIZE;
X raster = (unsigned char *)malloc(raster_size);
X if (raster == NULL)
X {
X (void)fprintf(stderr, "%s: unable to allocate memory for raster\n",
X myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X
X fd = open(file, O_RDONLY);
X if (fd < 0)
X {
X (void)fprintf(stderr, "%s: unable to open %s: %s\n",
X myname, file, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (fstat(fd, &stbuf) < 0)
X {
X (void)fprintf(stderr, "%s: unable to stat %s: %s\n",
X myname, file, strerror(errno));
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X if (stbuf.st_size != raster_size)
X {
X (void)fprintf(stderr, "%s: %s size is %d, not %d * %d = %d\n",
X myname, file, (int)stbuf.st_size,
X pixels, PIXEL_SIZE, raster_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X cc = read(fd, (void *)raster, raster_size);
X if (cc != raster_size)
X {
X if (cc < 0)
X (void)fprintf(stderr, "%s: error reading %s: %s\n",
X myname, file, strerror(errno));
X else
X (void)fprintf(stderr, "%s: incomplete read of %s:"
X " only got %d of %d requested\n",
X myname, (int)cc, (int)raster_size);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X (void)close(fd);
X
X return(raster);
X}
X
X
Xstatic unsigned long *
XConvertRaster(unsigned char *raster, int pixels)
X /*
X * Convert raw raster image into SGI ABGR image suitable for lrectwrite.
X * Return pointer to converted raster in malloc'ed storage.
X */
X{
X unsigned long *buffer;
X
X buffer = (unsigned long *)malloc(pixels * sizeof(long));
X if (buffer == NULL)
X {
X (void)fprintf(stderr, "%s: unable to allocate memory for raster\n",
X myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X
X if (strcmp(PIXEL_TYPE, "MONOCHROME") == 0)
X ConvertRasterMONO(buffer, raster, pixels);
X else if (strcmp(PIXEL_TYPE, "RGB") == 0)
X ConvertRasterRGB(buffer, raster, pixels, 0, 1, 2);
X else if (strcmp(PIXEL_TYPE, "BGR") == 0)
X ConvertRasterRGB(buffer, raster, pixels, 2, 1, 0);
X else if (strcmp(PIXEL_TYPE, "ARGB") == 0)
X ConvertRasterARGB(buffer, raster, pixels, 0, 1, 2, 3);
X else if (strcmp(PIXEL_TYPE, "ABGR") == 0)
X ConvertRasterARGB(buffer, raster, pixels, 0, 3, 2, 1);
X else if (strcmp(PIXEL_TYPE, "RGBA") == 0)
X ConvertRasterARGB(buffer, raster, pixels, 3, 0, 1, 2);
X else if (strcmp(PIXEL_TYPE, "BGRA") == 0)
X ConvertRasterARGB(buffer, raster, pixels, 3, 2, 1, 0);
X else
X {
X (void)fprintf(stderr, "%s: unknown pixel type %s\n",
X myname, PIXEL_TYPE);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X
X return(buffer);
X}
X
X
Xstatic void
XConvertRasterMONO(unsigned long *buffer, unsigned char *raster, int pixels)
X{
X int i;
X unsigned char *rp, *bp;
X
X for (i = 0, rp = raster, bp = (unsigned char *)buffer;
X i < pixels;
X i++, rp += 1, bp += sizeof(long))
X {
X bp[0] = 255;
X bp[1] = rp[0];
X bp[2] = rp[0];
X bp[3] = rp[0];
X }
X}
X
X
Xstatic void
XConvertRasterRGB(unsigned long *buffer, unsigned char *raster, int pixels,
X int ir, int ig, int ib)
X{
X int i;
X unsigned char *rp, *bp;
X
X for (i = 0, rp = raster, bp = (unsigned char *)buffer;
X i < pixels;
X i++, rp += 3, bp += sizeof(long))
X {
X bp[0] = 255;
X bp[1] = rp[ib];
X bp[2] = rp[ig];
X bp[3] = rp[ir];
X }
X}
X
X
Xstatic void
XConvertRasterARGB(unsigned long *buffer, unsigned char *raster, int pixels,
X int ia, int ir, int ig, int ib)
X{
X int i;
X unsigned char *rp, *bp;
X
X for (i = 0, rp = raster, bp = (unsigned char *)buffer;
X i < pixels;
X i++, rp += 4, bp += sizeof(long))
X {
X bp[0] = rp[ia];
X bp[1] = rp[ib];
X bp[2] = rp[ig];
X bp[3] = rp[ir];
X }
X}
X
X
Xstatic void
XDisplayRaster(unsigned long *buffer, int xres, int yres, int zres)
X /*
X * Display SGI raster and wait for "Q" key to be pressed. When
X * "Q" is pressed, close window and return.
X */
X{
X long winid;
X long dev;
X short val;
X
X prefsize(xres, yres);
X winid = winopen("gl-disp raster display tool");
X if (winid == -1)
X {
X (void)fprintf(stderr, "%s: unable to open a graphics window\n",
X myname);
X exit(EXIT_FAILURE);
X /*NOTREACHED*/
X }
X RGBmode();
X gconfig();
X cpack(0);
X clear();
X
X qreset();
X qdevice(QKEY);
X qdevice(ESCKEY);
X
X if (zres == 1)
X {
X lrectwrite(0, 0, xres-1, yres-1, buffer);
X for (;;)
X {
X dev = qread(&val);
X if (dev == REDRAW)
X lrectwrite(0, 0, xres-1, yres-1, buffer);
X else if (dev == QKEY || dev == ESCKEY)
X break;
X }
X }
X else
X {
X int paused = FALSE;
X unsigned int isize = xres*yres;
X unsigned long *bp = buffer;
X unsigned long *ep = buffer + zres*isize;
X
X qdevice(SPACEKEY);
X qdevice(NKEY);
X qdevice(PKEY);
X
X for (;;)
X {
X lrectwrite(0, 0, xres-1, yres-1, bp);
X if (!paused)
X {
X bp += isize;
X if (bp >= ep)
X bp = buffer;
X }
X
X while (paused || qtest())
X {
X dev = qread(&val);
X if (val == 0)
X continue;
X if (dev == REDRAW)
X lrectwrite(0, 0, xres-1, yres-1, bp);
X else if (dev == QKEY || dev == ESCKEY)
X goto out;
X else if (dev == SPACEKEY)
X paused = !paused;
X else if (paused)
X {
X if (dev == NKEY)
X {
X bp += isize;
X if (bp >= ep)
X bp = buffer;
X break;
X }
X else if (dev == PKEY)
X {
X if (bp == buffer)
X bp = ep;
X bp -= isize;
X break;
X }
X }
X }
X }
X out:
X
X unqdevice(SPACEKEY);
X unqdevice(NKEY);
X unqdevice(PKEY);
X }
X
X unqdevice(QKEY);
X unqdevice(ESCKEY);
X qreset();
X winclose(winid);
X}
END_OF_FILE
if test 7984 -ne `wc -c <'lic.1.3/test/gl-disp.c'`; then
echo shar: \"'lic.1.3/test/gl-disp.c'\" unpacked with wrong size!
fi
# end of 'lic.1.3/test/gl-disp.c'
fi
echo shar: End of archive 5 \(of 9\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 9 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...