Index: trunk/doc/pslib/psLibSDRS.tex
===================================================================
--- trunk/doc/pslib/psLibSDRS.tex	(revision 1092)
+++ trunk/doc/pslib/psLibSDRS.tex	(revision 1207)
@@ -1,4 +1,4 @@
-%%% $Id: psLibSDRS.tex,v 1.59 2004-06-25 03:10:26 eugene Exp $
-\documentclass[panstarrs]{panstarrs}
+%%% $Id: psLibSDRS.tex,v 1.60 2004-07-12 22:18:21 eugene Exp $
+\documentclass[panstarrs,spec]{panstarrs}
 
 % basic document variables
@@ -10,5 +10,5 @@
 \project{Pan-STARRS Image Processing Pipeline}
 \organization{Institute for Astronomy}
-\version{02}
+\version{03}
 \docnumber{PSDC-430-007}
 % note the use of the docnumber & version number:
@@ -132,4 +132,8 @@
 star-www.rl.ac.uk/star/docs/sun67.htx/sun67.html}
 
+\item libTAI will be used for time-related functions:
+
+\href{http://cr.yp.to/libtai.html}{\tt http://cr.yp.to/libtai.html}
+
 \end{itemize}
 
@@ -215,6 +219,7 @@
 special value, \code{P_PS_MEMMAGIC}.  The segment following the
 user-memory block consists of a single \code{void} pointer, and is
-also assigned the special value of \code{P_PS_MEMMAGIC}.  This address
-is pointed to by the structure element \code{endpost}.
+also assigned the special value of \code{P_PS_MEMMAGIC}.  The element
+\code{userMemorySize} specifies the number of bytes allocated in the
+user block and allows the endpost to be found.
 
 In practice, these bounding memory blocks mean that when a user
@@ -245,25 +250,45 @@
 which is also easily recognized in a dump of the memory table.
 
-The PSLib memory management system must maintain a private table of
-the allocated memory blocks.  The table includes a list of pointers to
-structures of type \code{psMemBlock}, defined as follows:
+The structure \code{psMemBlock} specifies additional information
+maintained for each block of allocated memory, and is defined as
+follows:
 %
 \begin{verbatim}
 typedef struct {
-    const void *startblock;             ///< initialised to P_PS_MEMMAGIC
-    const unsigned long id;             ///< a unique ID for this allocation
-    const char *file;                   ///< set from __FILE__ in e.g. p_psAlloc
+    const void* startblock;             ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;   ///< previous block in allocation list
+    struct psMemBlock* nextBlock;       ///< next block allocation list
+    psFreeFcn freeFcn;                  ///< deallocator.  If NULL, use generic deallocation.
+    size_t  userMemorySize;             ///< the size of the user-portion of the memory block
+    const psMemoryId id;                ///< a unique ID for this allocation
+    const char* file;                   ///< set from __FILE__ in e.g. p_psAlloc
     const int lineno;                   ///< set from __LINE__ in e.g. p_psAlloc
-    int refCounter;                     ///< how many times pointer is referenced
-    const void **endpost;               ///< initialised to P_PS_MEMMAGIC
-    const void *endblock;               ///< initialised to P_PS_MEMMAGIC
+    pthread_mutex_t   refCounterMutex;  ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;        ///< how many times pointer is referenced
+    const void* endblock;               ///< initialised to p_psMEMMAGIC
 } psMemBlock;
-\end{verbatim}
-%
-The second element in the structure is a sequential memory block ID.
-The memory management system must maintain an internal memory block ID
-counter from which a new ID may be supplied to each newly allocated
-block of memory and saved in the element \code{id}.  This ID should
-also be the key to the memory block in the memory block table.
+
+typedef void (*psFreeFcn)(void* ptr);
+typedef unsigned long psMemoryId;
+typedef unsigned long psReferenceCount;
+\end{verbatim}
+%
+The PSLib memory management system must maintain the collection of
+allocated memory blocks.  The entries \code{previousBlock} and
+\code{nextBlock} point to the previous and next memory blocks
+allocated by the memory management system (if they exist, or else
+\code{NULL}) and are used to scan through memory blocks as a linked
+list.
+
+The element \code{freeFcn} specifies the deallocator associated with a
+specific block of memory.  If this element is \code{NULL}, the basic
+deallocator is used and the memory block must not be a rich data
+structure which requires additional freeing functionality.
+
+The element \code{id} in the structure is a sequential memory block
+ID.  The memory management system must maintain an internal memory
+block ID counter from which a new ID may be supplied to each newly
+allocated block of memory and saved in the element \code{id}.  This ID
+should also be the key to the memory block in the memory block table.
 
 The two entries \code{file} and \code{lineno} are set to the line
@@ -273,4 +298,7 @@
 below that the basic memory managment functions be implemented as
 preprocessor macros which wrap the intrinsic C level functions.
+
+The element \code{refCounterMutex} is a mutex used to limit access to
+the reference counter (below) to a single thread at a time.
 
 The \code{psMemBlock} structure element \code{refCounter} is provided
@@ -284,8 +312,10 @@
 In order to trace double frees and other memory errors, the memory
 block reference is not automatically deleted when the assocated memory
-is deleted.  Rather, the \code{psMemBlock} data and the \code{endpost}
-data are left behind.  If endpost points to the memory location
-immediately following the \code{psMemBlock} data, then the memory
-block has been freed.  This state must be enforced by \code{psFree}.
+is deleted.  Rather, the \code{psMemBlock} data and the endpost data
+are left behind.  If \code{userMemorySize} is 0, then the memory block
+has been freed.  This state must be enforced by \code{psFree}.  This
+behavior, in which the associated \code{psMemBlock} is retained, is
+only provided if the code is compiled with the preprocessor variable
+\code{PS_MEM_DEBUG} defined.
 
 \subsubsection{APIs for Allocating and Freeing}
@@ -334,5 +364,5 @@
 \code{NULL} pointer. If they are unable to provide the requested
 memory they must attempt to obtain the desired memory by calling the
-routine registered by \code{psMemExhaustedSetCallback} (see
+routine registered by \code{psMemExhaustedCallbackSet} (see
 \S\ref{secMemAdvanced}), and if still unsuccessful, call
 \code{psAbort()}.  The same behavior is true for constructors of rich
@@ -346,4 +376,15 @@
 define the initialization independently since a byte value of 0 is
 usually insufficient.
+
+\begin{verbatim}
+  void p_psSetFreeFcn(void* ptr);     
+  ///< sets the fcn pointer to the appropriate ps*Free function.  If NULL,
+  ///< then a generic free functionality is used (i.e., the old psFree
+  ///< functionality).
+
+  freeFcn p_psGetFreeFcn(void* ptr);
+  ///< retrieves the function pointer to the higher-level free function to be
+  ///< used.  If NULL, then the traditional psFree functionality shall be used.
+\end{verbatim}
 
 \subsubsection{Callback Routines}
@@ -457,6 +498,6 @@
 %
 The callback functions are called with a pointer to the corresponding
-memory block.  The routines \code{psMemFreeIDSet} and
-\code{psMemAllocateIDSet} accept the desired ID value and return the
+memory block.  The routines \code{psMemFreeCallbackIDSet} and
+\code{psMemAllocateCallbackIDSet} accept the desired ID value and return the
 old value to the user.  The return values of the handlers installed by
 \code{psMemAllocateCallbackSet} and \code{psMemFreeCallbackSet} are
@@ -481,5 +522,5 @@
 \begin{verbatim}
 int psMemCheckLeaks(long id0, psMemBlock ***array, FILE *fd);
-int psMemCheckCorruption(int abort_on_error);
+int psMemCheckCorruption(bool abort_on_error);
 \end{verbatim}
 %
@@ -551,8 +592,11 @@
 variety of rich data structures.  The IPP Software Requirements
 Specification states that structures should be defined with
-corresponding constructors and destructors.  Instances of, for
-example, \code{psMyType} should be constructed using
-\code{psMyTypeAlloc()} calls, and destroyed using
-\code{psMyTypeFree()} calls.  The allocator will allocate the required
+corresponding constructors and destructors.  The destructors are
+private functions used only by the memory management system.
+Instances of, for example, \code{psMyType} should be constructed using
+\code{psMyTypeAlloc()} calls, and are destroyed using the basic
+\code{psFree} function, which calls \code{psMyTypeFree()} to free the
+components of the structure, but leaves the task of freeing the
+structure to \code{psFree}.  The allocator will allocate the required
 memory with \code{psAlloc} and increment the appropriate
 \code{refCounter}.
@@ -888,6 +932,6 @@
 that is passed to \code{psLogMsgV} with code \code{PS_LOG_ERROR}.  The
 result of a call to \code{psError} must be to push an error onto a
-stack; this stack is cleared if \code{psErrorStatus} is true, or by a
-call to \code{psErrorClear}.
+stack; this stack is cleared if \code{new} is true, or by a call to
+\code{psErrorClear}.
 
 The errors on the error stack are defined as the following:
@@ -920,6 +964,6 @@
 defined in the next section.  Note that these are also available in
 the \code{psErr} structure. The successive lines of the traceback
-should be indented by an additional space (see example).
-\code{psErrorStackPrintV} must not invoke \code{va_end}.
+should be indented by an additional space.  \code{psErrorStackPrintV}
+must not invoke \code{va_end}.
 %
 \begin{verbatim}
@@ -1113,4 +1157,5 @@
     PS_TYPE_F64,                        ///< Double-precision floating point
     PS_TYPE_C32,                        ///< Complex numbers consisting of floats
+    PS_TYPE_C64,                        ///< Complex numbers consisting of doubles
     PS_TYPE_OTHER,                      ///< Not supported for arithmetic
 } psElemType;
@@ -1119,10 +1164,44 @@
 section~\ref{sec:arithmetic}.  
 
+\subsection{Simple Scalars}
+
+We define a basic scalar data type which includes the type
+information.  This structure allows scalars to be used in functions
+which interpret the data type from the structure when deciding how to
+perform an operation.  The basic scalar structure is:
+\begin{verbatim}
+typedef struct {
+    psType type;                        ///< data type information
+    union {                            
+        psS8   S8;                      ///< bye value entry
+        psS16 S16;                      ///< short int value entry
+        psU8   U8;                      ///< unsigned byte value entry
+        psU16 U16;                      ///< unsigned short int value entry
+        psF32 F32;                      ///< float value entry
+        psF64 F64;                      ///< double value entry
+        psC32 C32;                      ///< complex value entry
+        psC64 C64;                      ///< double complex value entry
+    } data;
+} p_psScalar;
+\end{verbatim}
+
+In addition, we specify two functions for working with \code{psScalar} data:
+\begin{verbatim}
+psScalar *psScalarAlloc (psC64 value, psElemType dataType);
+psScalar *psScalarCopy (psScalar *value);
+\end{verbatim}
+The first creates a \code{psType}-ed structure from a constant value,
+casting it as appropriate based on the \code{dataType}.  The second
+copies the provided \code{psScalar} value.  This latter function is
+necessary to keep a copy of an existing \code{psScalar} value, since
+\code{psBinaryOp} and \code{psUnaryOp} are required to free incoming
+\code{psScalar} data (see \S\ref{sec:arithmetic}).
+
 \subsection{Simple Vectors}
 
 We require several related types of basic one-dimensional arrays:
 arrays of values of type \code{int}, \code{float}, \code{double},
-\code{complex float}, and \code{void *}.  We have defined a single
-structure, \code{psVector} to represent these concepts:
+\code{complex float}, and \code{complex double}.  We have defined a
+single structure, \code{psVector} to represent these concepts:
 %
 \begin{verbatim}
@@ -1132,9 +1211,9 @@
     const int nalloc;                   ///< allocated data block
     union {
-        psS8  *S8;                      ///< Pointers to short-integer data
+        psS8  *S8;                      ///< Pointers to byte data
         psS16 *S16;                     ///< Pointers to short-integer data
         psS32 *S32;                     ///< Pointers to integer data
         psS64 *S64;                     ///< Pointers to long-integer data
-        psU8  *U18;                     ///< Pointers to unsigned-short-integer data
+        psU8  *U18;                     ///< Pointers to unsigned-byte data
         psU16 *U16;                     ///< Pointers to unsigned-short-integer data
         psU32 *U32;                     ///< Pointers to unsigned-integer data
@@ -1142,6 +1221,6 @@
         psF32 *F32;                     ///< Pointers to floating-point data
         psF64 *F64;                     ///< Pointers to double-precision data
-        psF32 *C32;                     ///< Pointers to complex floating-point data
-        void **void;
+        psC32 *C32;                     ///< Pointers to complex floating-point data
+        psC64 *C64;                     ///< Pointers to complex floating-point data
     } data;
 } psVector;
@@ -1161,5 +1240,5 @@
 psVector *psVectorAlloc(int nalloc, psElemType type);
 psVector *psVectorRealloc(const psVector *vector, int nalloc);
-void psVectorFree(psVector *restrict vector, void (*elemFree)(void *));
+void p_psVectorFree(psVector *restrict vector);
 \end{verbatim}
 %
@@ -1173,13 +1252,6 @@
 and the extra elements are lost.  If \code{nalloc} is larger than the
 current value of \code{psVector.n}, \code{psVector.n} is left intact.
-If the value of \code{myArray} is \code{NULL}, then
-\code{psVectorRealloc} must return an error.  In \code{psVectorFree},
-the function \code{elemFree} is required for arrays of pointer types;
-it is the destructor appropriate to the data pointed to by the
-pointers.  This function, which may be \code{NULL}, is called for each
-existing element of the array before the array itself is freed.  If
-the function is \code{NULL}, the elements are are not freed.  This
-function must not be defined for any data type except the \code{void}
-pointer array.
+If the value of \code{vector} is \code{NULL}, then
+\code{psVectorRealloc} must return an error.
 
 \subsection{Simple Images}
@@ -1206,4 +1278,5 @@
         psF64 **F64;                    ///< Pointers to double-precision data
         psC32 **C32;                    ///< Pointers to complex floating-point data
+        psC64 **C64;                    ///< Pointers to complex floating-point data
     } data;
     const struct psImage *parent;       ///< parent, if a subimage 
@@ -1227,8 +1300,9 @@
 starting row number.  The structure may include references to
 subrasters (\code{children, Nchildren}) and/or to a containing array
-(\code{parent}).  Unless this is image is a child of another image
+(\code{parent}).  Unless this image is a child of another image
 (represents a subset of the pixels of another image), the image data
 is allocated in a contiguous block.  We define the following
-supporting functions:
+supporting functions, which are valid for data types \code{psS8,
+psS16, psU8, psU16, psF32, psF64, psC32, psC64}.
 
 \begin{verbatim}
@@ -1238,12 +1312,60 @@
 \code{type}.  This function must allow any of the valid image data
 types and not restrict to the valid FITS BITPIX types.  The image
-dimensionality must be 2.
-
-\begin{verbatim}
-void psImageFree(psImage *image);
+dimensionality must be 2.  
+
+\begin{verbatim}
+void p_psImageFree(psImage *restrict image);
 \end{verbatim}
 Free the memory associated with a specific image, including the pixel
 data. Free the children of the image if they exist.
 
+\subsection{Simple Arrays}
+
+\tbd{fill out this section}
+
+We require an order collection of unspecified data elements.  We
+define \code{psArray} to carry such a collection:
+%
+\begin{verbatim}
+typedef struct {
+    const int n;                        ///< size of array 
+    const int nalloc;                   ///< allocated data block
+    void **data;                        ///< pointer to data block
+} psArray;
+\end{verbatim}
+%
+In this structure, the argument \code{n} is the length of the array
+(the number of elements); \code{nalloc} is the number of elements
+allocated ($nalloc \ge n$).  The allocated memory is pointed to by
+\code{data}.  The structure is associated with a constructor and a
+destructor:
+%
+\begin{verbatim}
+psArray *psArrayAlloc(int nalloc, psElemType type);
+psArray *psArrayRealloc(const psArray *array, int nalloc);
+void p_psArrayFree(psArray *restrict array);
+\end{verbatim}
+%
+In these functions, \code{nalloc} is the number of elements to
+allocate.  For \code{psArrayAlloc}, the value of \code{psArray.n} is
+set to \code{nalloc}.  Users may choose to restrict the data range
+after the \code{psArrayAlloc} function is called.  For
+\code{psArrayRealloc}, if the value of \code{nalloc} is smaller than
+the current value of \code{psArray.n}, then \code{psArray.n} is set to
+\code{nalloc}, the array is adjusted down to match \code{nalloc}, and
+the extra elements are dropped and freed if necesitated by the
+reference counter.  If \code{nalloc} is larger than the current value
+of \code{psArray.n}, \code{psArray.n} is left intact.  If the value of
+\code{array} is \code{NULL}, then \code{psArrayRealloc} must return an
+error.
+
+\begin{verbatim}
+psArray *psArraySort(psArray *array, int (*compare)(const void **a, const void **b) );
+\end{verbatim}
+An array may be sorted using \code{psArraySort}, which requires the
+specification of a comparison function to specify how the objects on
+the list should be sorted.  The motivation is primarily to be able to
+iterate on a sorted list of keys from a hash.
+
 \subsection{Doubly-linked lists}
 \label{sec:psList}
@@ -1253,8 +1375,10 @@
 \begin{verbatim}
 typedef struct {
-   int n;                               ///< number of elements on list
+   unsigned int size;                  ///< number of elements on list
    psListElem *head;                   ///< first element on list (may be NULL)
    psListElem *tail;                   ///< last element on list (may be NULL)
    psListElem *iter;                   ///< iteration cursor
+   unsigned int iterIndex;             ///< the numeric position of the iteration cursor in the list
+   pthread_mutex_t lock;               ///< mutex to lock a node during changes
 } psList;
 \end{verbatim}
@@ -1334,17 +1458,15 @@
 
 \begin{verbatim}
-void psListFree(psList *list, void (*elemFree)(void *));
-\end{verbatim}
-A complete list may be freed with this destructor.  If the element
-destructor (\code{elemFree}) is \code{NULL}, the list should be
-deleted, but not the elements, although their \code{refcounter}s
-should be decremented.
-
-\begin{verbatim}
-psVector *psListToVector(psList *list);
-psList *psVectorToList(psVector *vector);
+void p_psListFree(psList *list);
+\end{verbatim}
+This function frees the data associated with the entire list.  This
+function is used by psFree to free a list with its associated data.
+
+\begin{verbatim}
+psArray *psListToArray(psList *list);
+psList  *psArrayToList(psArray *array);
 \end{verbatim}
 These two functions are available to convert between the
-\code{psList} and \code{psVector} containers.  These functions do not
+\code{psList} and \code{psArray} containers.  These functions do not
 free the elements or destroy the input collection.  Rather, they
 increment the reference counter for each of the elements.
@@ -1367,5 +1489,5 @@
 
 \begin{verbatim}
-psList *psListSort(psList *list, int (*compare)(const void *a, const void *b) );
+psList *psListSort(psList *list, int (*compare)(const void **a, const void **b) );
 \end{verbatim}
 A list may be sorted using \code{psListSort}, which requires the
@@ -1445,20 +1567,17 @@
 a specific key may be removed (deleted) with the function:
 \begin{verbatim}
-void *psHashRemove(psHash *table, char *key);
+bool psHashRemove(psHash *table, char *key);
 \end{verbatim}
 The function returns a value of \code{true} if the operation was
 successfull, and \code{false} otherwise.
 
-A complete hash table may be freed by calling:
-\begin{verbatim}
-void psHashFree(psHash *table, void (*itemFree)(void *item));
-\end{verbatim}
-where the function \code{itemFree} is provided to delete the
-individual elements in the table.  If it is NULL it is the
-responsibility of the caller to free the elements.
+The data associated with a complete hash table may be freed by calling:
+\begin{verbatim}
+void p_psHashFree(psHash *table);
+\end{verbatim}
 
 The function
 \begin{verbatim}
-psList *psHashKeylist(psHast *table);
+psList *psHashKeyList(psHash *table);
 \end{verbatim}
 returns the complete list of defined keys associated with the
@@ -1504,5 +1623,5 @@
 \begin{verbatim}
 psBitSet *psBitSetAlloc(int n);
-void psBitSetFree(psBitSet *restrict myBits);
+void p_psBitSetFree(psBitSet *restrict myBits);
 \end{verbatim}
 where \code{n} is the requested number of bits.
@@ -1553,9 +1672,9 @@
 value in the last element.  The input vector, \code{in}, may be sorted
 in-place if it is also specified as the \code{out} vector. This
-function is specified for input types \code{psU8, psU16, psF32,
+function is specified for input types \code{psS8, psU16, psF32,
 psF64}.  The input and output vectors must have the same type.
 
 \begin{verbatim}
-psVector *psSort(psVector *out, const psVector *restrict in);
+psVector *psVectorSort(psVector *out, const psVector *restrict in);
 \end{verbatim}
 
@@ -1568,17 +1687,18 @@
 largest (i.e.\ most positive) value in the last element.  The output
 vector must be of type \code{psU32}.  This function is specified for
-input types \code{psU8, psU16, psF32, psF64}.
-
-\begin{verbatim}
-psVector *psSortIndex(psVector *restrict out; const psVector *restrict in);
+input types \code{psS8, psU16, psF32, psF64}.
+
+\begin{verbatim}
+psVector *psVectorSortIndex(psVector *restrict out; const psVector *restrict in);
 \end{verbatim}
 
 The sorted vectors may be accessed in the following manner:
 \begin{verbatim}
-indexVector = psSortIndex(NULL, x);
+indexVector = psVectorSortIndex(NULL, x);
 for (int i = 0; i < indexVector.n; i++) {
     doMyFunc(x[indexVector.arr.arr_U32[i]], y[indexVector[i].arr.arr_U32]);
 }
 \end{verbatim}
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1634,15 +1754,8 @@
 The defaults for these two numbers is both 3.  Since the sample
 statistics scale like $N\log N$, for large numbers of input data
-points, it is faster to use the robust statistics.  If the number of
-data points is large, \code{psStats} must revert to the robust
-calculation even if the user requested sample statistics.  The values
-should be returned in the \code{sample} fields, but the bit
-\code{PS_STAT_ROBUST_FOR_SAMPLE} in \code{options} must be set in this
-case.  The cutoff for this decision must be made on the basis of the
-value in \code{sampleLimit}, which should have a default of $3 \times
-10^{5}$.  Default input field values must be set by the \code{psStats}
-constructor.  The input vector may be of type \code{psU8},
-\code{psU16}, \code{psF32}, \code{psF64}; the mask must be of type
-\code{psU8}.
+points, it is faster to use the robust statistics.  Default input
+field values must be set by the \code{psStats} constructor.  The input
+vector may be of type \code{psU8}, \code{psU16}, \code{psF32},
+\code{psF64}; the mask must be of type \code{psU8}.
 
 The \code{psStats} structure is defined with entries for each of the
@@ -1698,5 +1811,4 @@
     PS_STAT_USE_RANGE             = 0x002000,
     PS_STAT_USE_BINSIZE           = 0x004000
-    PS_STAT_ROBUST_FOR_SAMPLE     = 0x008000
 } psStatsOptions;                         
 \end{verbatim}
@@ -1706,5 +1818,5 @@
 \begin{verbatim}
 psStats *psStatsAlloc(psStatsOptions options);
-void psStatsFree(psStats *restrict stats);
+void p_psStatsFree(psStats *restrict stats);
 \end{verbatim}
 
@@ -1720,5 +1832,5 @@
     psVector *nums;                     ///< Number in each of the bins
     int minNum, maxNum;                 ///< Number below minimum / above maximum
-    int uniform;                        ///< Is it a uniform distribution?
+    bool uniform;                        ///< Is it a uniform distribution?
 } psHistogram;
 \end{verbatim}
@@ -1755,5 +1867,5 @@
 A histogram is free with the destructor:
 \begin{verbatim}
-void psHistogramFree(psHistogram *restrict myHist);
+void p_psHistogramFree(psHistogram *restrict myHist);
 \end{verbatim}
 
@@ -1833,5 +1945,5 @@
 \begin{verbatim}
 psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY);
-void psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
+void p_psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
 \end{verbatim}
 where \code{nX} and \code{nY} are the number of terms in x and y
@@ -1853,5 +1965,5 @@
 The Gaussian evaluation is provide by:
 \begin{verbatim}
-float psGaussian(float x, float mean, float sigma, int normal);
+float psGaussian(float x, float mean, float sigma, bool normal);
 \end{verbatim}
 which evaluates a Gaussian with the given \code{mean} and \code{sigma}
@@ -1906,5 +2018,6 @@
 Note that \code{paramMask} must be of type \code{psU8}, while
 \code{params} must be of type \code{psF32}.  The optional function,
-\code{myFuncDeriv} returns the derivative of the function.
+\code{myFuncDeriv} returns the derivative of the function.  This
+function must be valid only for types \code{psF32}, \code{psF64}.
 
 \begin{verbatim}
@@ -1918,5 +2031,5 @@
 \end{verbatim}
 \code{psMinimizeChi2} fits a model to observations by minimizing
-$\chi^2$, returing the best-fit parameters.  The input parameters are
+$\chi^2$, returning the best-fit parameters.  The input parameters are
 a function that evaluates the model for a specified domain, given the
 parameters, \code{evalModel}; a list of observations, (\code{domain},
@@ -1925,5 +2038,6 @@
 parameters, and an optional mask specifying which parameters are to be
 fit, \code{paramMask}, which must be of type \code{psU8}.  All
-parameters are fit if this vector is \code{NULL}.
+parameters are fit if this vector is \code{NULL}.  This
+function must be valid only for types \code{psF32}, \code{psF64}.
 
 \begin{verbatim}
@@ -1933,5 +2047,5 @@
                                      const psVector *restrict yErr);
 \end{verbatim}
-\code{psVectorFitPolynomial} returns the polynomial that best fits the
+\code{psVectorFitPolynomial1d} returns the polynomial that best fits the
 observations.  The input parameters are a polynomial that specifies
 the fit order, \code{myPoly}, which will be altered and returned with
@@ -1941,6 +2055,5 @@
 variable error, \code{yErr} may be null, in which case the solution is
 determined in the assumption that all data errors are equal.  This
-function must be valid for types \code{psU8}, \code{psU16},
-\code{psF32}, \code{psF64}.
+function must be valid only for types \code{psF32}, \code{psF64}.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1959,13 +2072,13 @@
 \end{verbatim}
 Define a subimage of the specified area of the given image.  This
-function must return an error if the requested subset area lies
-outside of the parent image.  The argument \code{image} is the parent
-image, \code{nx,ny} specify the dimensions of the desired subraster,
-and \code{x0, y0} specify the starting pixel of the subraster.  The
-entire subraster must be contained within the raster of the parent
-image.  Note that the \code{refCounter} for the parent should be
-incremented.  This function must be defined for the following types:
-\code{psU8}, \code{psU16}, \code{psS8}, \code{psS16}, \code{psF32},
-\code{psF64}, \code{psC32}, \code{psC64}.
+function must raise an error if the requested subset area lies outside
+of the parent image and return \code{NULL}.  The argument \code{image}
+is the parent image, \code{nx,ny} specify the dimensions of the
+desired subraster, and \code{x0, y0} specify the starting pixel of the
+subraster.  The entire subraster must be contained within the raster
+of the parent image.  Note that the \code{refCounter} for the parent
+should be incremented.  This function must be defined for the
+following types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
+\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
 
 \begin{verbatim}
@@ -1973,17 +2086,16 @@
 \end{verbatim}
 Create a copy of the specified image, converting the type in the
-process.  If the output target pointer is not NULL, place the result
-in the specified structure.  The output image data must be allocated
-as a single, contiguous block of memory.  The output image may not be
-the input image.  This function must be defined for the following
-types: \code{psU8}, \code{psU16}, \code{psS8}, \code{psS16},
-\code{psF32}, \code{psF64}, \code{psC32}, \code{psC64}.
+process.  If the output target pointer is not \code{NULL}, place the
+result in the specified structure.  If the output target pointer is
+\code{NULL}, the original data type must be maintained.  The output
+image data must be allocated as a single, contiguous block of memory.
+The output image may not be the input image.  This function must be
+defined for the following types: \code{psU8}, \code{psU16},
+\code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
+\code{psC64}.
 
 \subsubsection{Image Pixel Extractions}
 
 \begin{verbatim}
-psVector *psImageSlice(psVector *out, const psImage *input, 
-                       int x, int y, int nx, int ny, 
-                       int direction, const psStats *stats);
 typedef enum {
     PS_CUT_X_POS;
@@ -1992,4 +2104,10 @@
     PS_CUT_Y_NEG;
 } psImageCutDirection;
+
+psVector *psImageSlice(psVector *out, const psImage *input, 
+                       const psImage *restrict mask, 
+                       unsigned int maskVal,
+                       int x, int y, int nx, int ny, 
+                       psImageCutDirection direction, const psStats *stats);
 \end{verbatim}
 Extract pixels from rectlinear region to a vector (array of floats).
@@ -2002,9 +2120,11 @@
 value is specified by \code{stats}.  Only one of the statistics
 choices may be specified, otherwise the function must return an error.
-This function must be defined for the following types: \code{psU8},
+This function must be defined for the following types: \code{psS8},
 \code{psU16}, \code{psF32}, \code{psF64}.
 
 \begin{verbatim}
 psVector *psImageCut(psVector *out, const psImage *input, 
+                     const psImage *restrict mask, 
+                     unsigned int maskVal,
                      float xs, float ys, float xe, float ye, 
                      float dw, const psStats *stats);
@@ -2021,9 +2141,12 @@
 vector value is specified by \code{stats}.  Only one of the statistics
 choices may be specified, otherwise the function must return an error.
-This function must be defined for the following types: \code{psU8},
+This function must be defined for the following types: \code{psS8},
 \code{psU16}, \code{psF32}, \code{psF64}
 
 \begin{verbatim}
-psVector *psImageRadialCut(psVector *out, const psImage *input, float x, float y,
+psVector *psImageRadialCut(psVector *out, const psImage *input, 
+                           const psImage *restrict mask, 
+                           unsigned int maskVal,
+                           float x, float y,
                            const psVector *radii, const psStats *stats);
 \end{verbatim}
@@ -2037,5 +2160,5 @@
 \code{stats}.  Only one of the statistics choices may be specified,
 otherwise the function must return an error.  This function must be
-defined for the following types: \code{psU8}, \code{psU16},
+defined for the following types: \code{psS8}, \code{psU16},
 \code{psF32}, \code{psF64}.
 
@@ -2044,21 +2167,43 @@
 \begin{verbatim}
 psImage *psImageRebin(psImage *out, const psImage *in, 
-                      float scale, const psStats *stats);
+                      const psImage *restrict mask, 
+                      unsigned int maskVal,
+                      int scale, const psStats *stats);
 \end{verbatim}
 Rebin image to new scale.  A new image is constructed in which the
-dimensions are reduced by a factor of \code{scale} $\le 1$ (it is an
-error for \code{scale} $> 1$).  The \code{scale} is equal in each
-dimension.  The output image is generated from all input image pixels.
+dimensions are reduced by a factor of \code{1 / scale}.  The
+\code{scale}, always a positive number, is equal in each dimension and
+specified the number of pixels used to define a new pixel in the
+output image.  The output image is generated from all input image
+pixels.  Care must be taken on the image boundary if the image
+dimensions are not divisible by the scaling factor.  In those regions,
+the output pixel must be constructed from the available input pixels.
 Each pixel in the output image is derived from the statistics of the
 corresponding set of input image pixels based on the statistics
 specified by \code{stats}.  Only one of the statistics choices may be
 specified, otherwise the function must return an error.  This function
-must be defined for the following types: \code{psU8}, \code{psU16},
+must be defined for the following types: \code{psS8}, \code{psU16},
 \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
 \code{psC64}.
 
 \begin{verbatim}
-psImage *psImageRotate(psImage *out, const psImage *input, float
-angle, float exposed);
+psImage *psImageResample(psImage *out, const psImage *in, 
+                         int scale, psImageResampleMode mode);
+typedef enum {
+    PS_RESAMPLE_FLAT, 
+    PS_RESAMPLE_BILINEAR, 
+    PS_RESAMPLE_BICUBIC, 
+    PS_RESAMPLE_SINC 
+} psImageResampleMode mode;
+\end{verbatim}
+Resample image to new scale.  A new image is constructed in which the
+dimensions are increased by a factor of \code{scale}.  The
+\code{scale}, always a positive number, is equal in each dimension.
+The output image is generated from all input image pixels.  Each pixel
+in the output image is derived by interpolating between neighboring
+pixels using the specified interpolation method (\code{mode}).
+
+\begin{verbatim}
+psImage *psImageRotate(psImage *out, const psImage *input, float angle, float exposed);
 \end{verbatim}
 Rotate the input image by given angle, specified in degrees.  The
@@ -2108,5 +2253,5 @@
 pixels to be excluded if their corresponding mask pixel value matches
 the value of \code{maskVal}.  This function must be defined for the
-following types: \code{psU8}, \code{psU16}, \code{psF32},
+following types: \code{psS8}, \code{psU16}, \code{psF32},
 \code{psF64}.
 
@@ -2120,5 +2265,5 @@
 generate is specified by \code{psHistogram hist} (see
 section~\ref{sec:histograms}).  This function must be defined for the
-following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
+following types: \code{psS8}, \code{psU16}, \code{psF32}, \code{psF64}.
 
 \begin{verbatim}
@@ -2128,5 +2273,5 @@
 structure \code{coeffs} contains the desired order and terms of
 interest.  This function must be defined for the
-following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
+following types: \code{psS8}, \code{psU16}, \code{psF32}, \code{psF64}.
 
 \begin{verbatim}
@@ -2136,5 +2281,5 @@
 input polynomial coefficients, set the image pixel values on the basis
 of the polynomial function.  This function must be defined for the
-following types: \code{psU8}, \code{psU16}, \code{psF32}, \code{psF64}.
+following types: \code{psS8}, \code{psU16}, \code{psF32}, \code{psF64}.
 
 \subsubsection{Image I/O Functions}
@@ -2158,9 +2303,13 @@
 slice of the image.  The data is read from the extension specified by
 extname (matching the EXTNAME keyword) or by the extnum value (with 0
-representing the PHU, 1 the first extension, etc).  This function must
-call \code{psError} and return \code{NULL} if any of the specified
-parameters are out of range for the data in the image file, if the
-specified image file does not exist, or the image on disk is zero- or
-one-dimensional.
+representing the primary header unit (PHU), 1 the first extension,
+etc).  This function must call \code{psError} and return \code{NULL}
+if any of the specified parameters are out of range for the data in
+the image file, if the specified image file does not exist, or the
+image on disk is zero- or one-dimensional.  This function will only
+read images of the native FITS image types (\code{psU8}, \code{psU16},
+\code{psU32}, \code{psF32}, \code{psF64}).  The user is expected to
+convert the data type as needed with \code{psImageCopy}.  The return
+value must be 0 for a successful operation and 1 for an error.
  
 \begin{verbatim}
@@ -2180,10 +2329,14 @@
 the image, return an error (ie, if x + image.nx >= NAXIS1, y +
 image.ny >= NAXIS2, or z >= NAXIS3).  If the image does not exist,
-require x,y,z to be zero.
+require x,y,z to be zero.  This function will only write images of the
+native FITS image types (\code{psU8}, \code{psU16}, \code{psU32},
+\code{psF32}, \code{psF64}).  The user is expected to convert the data
+type as needed with \code{psImageCopy}.  The return value must be 0
+for a successful operation and 1 for an error.
 
 \subsubsection{Image Pixel Manipulations}
 
 \begin{verbatim}
-int psImageClip(psImage *input, float min, float vmin, float max, float vmax);
+int psImageClip(psImage *input, double min, double vmin, double max, double vmax);
 \end{verbatim}
 Clip image values outside of range to given values.  All pixels with
@@ -2204,4 +2357,21 @@
 
 \begin{verbatim}
+int psImageClipComplexRegion(psImage *input, complex double min, complex double vmin, complex double max, complex double vmax);
+\end{verbatim}
+Clip image values outside of range to given values.  All pixels with
+values \code{< min} are set to the value \code{vmin}. All pixels with
+values \code{> max} are set to the value \code{vmax}. Returns the
+number of clipped pixels.  This function must be defined for the
+following types: \code{psC32}, \code{psC64}.  The arguments
+(\code{min}, \code{max}, etc) define a rectangular region in complex
+space; data values inside this regions are unchanged while those
+outside are set to either \code{vmax} (if either their real or
+imaginary portions are greater than the corresponding values of
+\code{max}) or \code{vmin} (in all other cases).  If the input
+parameters \code{vmin} or \code{vmax} are out of bounds for the image
+pixel type, the function must raise an error.  It is not an error for
+\code{min} or \code{max} to be out of range.
+
+\begin{verbatim}
 int psImageClipNaN(psImage *input, float value);
 \end{verbatim}
@@ -2249,5 +2419,5 @@
 their \code{psType} elements, which always are the first elements.
 Note that these functions return a pointer to the appropriate type for
-the operation.  Since the result may is cast to \code{psType}, the
+the operation.  Since the result may be cast to \code{psType}, the
 resulting type may be determined by examining the return value.  It is
 expected that the implementation of these functions will employ
@@ -2260,5 +2430,8 @@
 Operations between data structures with incompatible sizes are not
 allowed.  However, operations between data elements of different rank
-(scalar, vector, image) are allowed, and defined below.
+(scalar, vector, image) are allowed, and defined below.  These
+functions are valid for all data types \code{psU8}, \code{psU16},
+\code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
+\code{psC64}.
 
 Binary operations between an image and a vector have a potential
@@ -2270,39 +2443,17 @@
 a ``transposed vector'' in the same context acts on all columns.
 Vectors, when created, will be created as ``vectors'', but may be
-converted to ``transposed vectors'' using the following function:
-\begin{verbatim}
-psVector *psVectorTranspose(psVector *out, psVector *myVector);
-\end{verbatim}
+converted to ``transposed vectors'' by setting
+\code{vector->type.dimen = PS_DIMEN_TRANSV}.
 
 It is further desirable to allow scalar values to be used within these
-functions, which requires the following additions:
-\begin{verbatim}
-p_ps_Scalar *psScalar (double value);
-p_ps_Scalar *psScalarType (char *mode, ...);
-\end{verbatim}
-The first creates a psType-ed structure from a constant value, while
-the second creates a psType-ed structure for a specified type.  The
-structure which carries a scalar value is specified as the following
-private type, and is analogous to the \code{psVector} and
-\code{psImage} structures:
-\begin{verbatim}
-typedef struct {
-    psType type;                        ///< data type information
-    union {                            
-        psS32 S32;                      ///< integer value entry
-        psF32 F32;                      ///< float value entry
-        psF64 F64;                      ///< double value entry
-        psC32 C32;                      ///< complex value entry
-    } data;
-} p_psScalar;
-\end{verbatim}
-
-This allows one to write the following to take the sine of the square
-of all pixels in an image:
+functions.  These functions may take a pointer to type
+\code{psScalar}, which is freed by the function. This allows one to
+write the following lines to take the sine of the square of all pixels
+in an image:
 \begin{verbatim}
 psImage A,B;
 
-B = psBinaryOp (NULL, A, "^", psScalar(2));
-(void) psUnaryOp(B, B, "sin");
+B = psBinaryOp (NULL, A, "^", psScalarAlloc(2)); 
+psUnaryOp(B, B, "sin");
 \end{verbatim}
 
@@ -2677,5 +2828,5 @@
 being represented, given by the enumerated type \code{psMetadataType}:
 \begin{verbatim}
-typedef enum {                          ///< type of val is:
+typedef enum {                          ///< type of data.item is:
     PS_META_ITEM_SET = 0,               ///< NULL; metadata is in psMetadataType.items
     PS_META_S32,                        ///< int (.S32)
@@ -2749,10 +2900,10 @@
 The \code{psMetadataItem} destructor is specified below.  Note that
 the destructor for \code{psMetadataItem} must call the appropriate
-destructor for the \code{val} (recall that it is the duty of the
+destructor for the \code{data.item} (recall that it is the duty of the
 \code{psMyTypeFree}s to decrement the \code{refCounter} and free the
 memory if and only if the \code{refCounter == 1} --- see
 \S\ref{sec:free}).
 \begin{verbatim}
-void psMetadataItemFree(psMetadataItem *item);
+void p_psMetadataItemFree(psMetadataItem *item);
 \end{verbatim}
 
@@ -2763,5 +2914,5 @@
 \begin{verbatim}
 psMetadata *psMetadataAlloc(void);
-void psMetadataFree(psMetadata *md);
+void p_psMetadataFree(psMetadata *md);
 \end{verbatim}
 
@@ -2771,17 +2922,17 @@
 be appended.  In both cases, the return value defines the success
 (\code{true}) or failure of the operation.  The second function,
-\code{psMetadataAdd} takes a pointer or value which is interpretted
-by the \code{va_list} operators in the function.  Both functions take
-an parameter \code{where} which specifies where in the list to place
-the element, following the conventions for the \code{psList}.  Care
-should be taken not to leak memory when appending an item for which
-the key already exists in the metadata (and is not
+\code{psMetadataAdd} takes a pointer or value which is interpreted by
+the function using variadic argument interpretation.  Both functions
+take an parameter \code{where} which specifies where in the list to
+place the element, following the conventions for the \code{psList}.
+Care should be taken not to leak memory when appending an item for
+which the key already exists in the metadata (and is not
 \code{PS_META_NON_UNIQUE}).
 %
 \begin{verbatim}
 bool psMetadataAddItem(psMetadata *restrict md, int where,
-                                     psMetadataItem *restrict item);
+                       psMetadataItem *restrict item);
 bool psMetadataAdd(psMetadata *restrict md, int where, 
-                                 const char *name, int format, const char *comment, ...);
+                   const char *name, int format, const char *comment, ...);
 \end{verbatim}
 
@@ -2829,9 +2980,14 @@
 \end{verbatim}
 
-Metadata items may be printed to an open file descriptor, optionally
-pre-pending a specified string.
-\begin{verbatim}
-void psMetadataItemPrint(FILE *fd, const psMetadataItem *restrict md, 
-                         const char *prefix);
+Metadata items may be printed to an open file descriptor based on a
+provided format.  The format string is an sprintf format statement
+with exactly one \% formatting command.  If the metadata item type is
+a numeric type, this formatting command must also be numeric, and type
+conversion performed to the value to match the format type.  If the
+metadata item type is a string, the formatting command must also be
+for a string (\%s type of command).  If the metadata type is any other
+data type, printing is not allowed.
+\begin{verbatim}
+void psMetadataItemPrint(FILE *fd, const char *format, const psMetadataItem *restrict md);
 \end{verbatim}
 
@@ -2937,5 +3093,5 @@
 the mask: \code{T.x->mask[1][1] = 0; T.y->mask[1][1] = 0;}
 
-The \code{psPlaneDistortion} represents an optical distortion.  The
+The \code{psPlaneDistort} represents an optical distortion.  The
 lowest two terms are the $x$ and $y$ axis of the target system.  The
 higher two terms may represent magnitude and color terms.
@@ -2956,5 +3112,5 @@
 CCD, of an object with magnitude and color ($m,c$) to a second frame
 ($p,q$), e.g., the focal plane. If we have only first order terms in
-the transformation \code{psPlaneTransform T}, the new coordinates
+the transformation \code{psPlaneDistort T}, the new coordinates
 would be represented by the terms:
 %
@@ -3013,5 +3169,5 @@
 \begin{verbatim}
 psSphereTransform *psSphereTransformAlloc(double NPlon, double NPlat, double ZP);
-void psSphereTransformFree(psSphereTransform *trans);
+void p_psSphereTransformFree(psSphereTransform *trans);
 \end{verbatim}
 where \code{NPlon} and \code{NPlat} define the coordinates in the
@@ -3019,4 +3175,5 @@
 defines the longitude in the input system of the equatorial
 intersection between the two systems (e.g, the first point of Ares).
+The constructor must calculate the sines and cosines above.
 
 Spherical coordinates may be transformed by providing the
@@ -3031,5 +3188,6 @@
 The following functions simply return the appropriate
 \code{psSphereTransform} to convert between predefined spherical
-coordinate systems (i.e., ICRS, Ecliptic and Galactic).
+coordinate systems (i.e., ICRS, Ecliptic and Galactic).  These are
+constructors as well as the above \code{psSphereTransformAlloc}.
 %
 \begin{verbatim}
@@ -3087,14 +3245,35 @@
 the sky, as well as a function to apply an offset to a position.  The
 first determines the offset (RA,Dec) on the sky between two positions.
-The second applies the given offset to the coordinate. The offsets may
-be of type: \tbd{Linear, Spherical/Arcsec, Spherical/Degreees, etc.}
+The second applies the given offset to the coordinate.  Both an offset
+mode and an offset unit may be defined.  The mode may be either
+\code{PS_SPHERICAL}, in which case the specified offset corresponds to
+an offset in angles, or it may be \code{PS_LINEAR}, in which case the
+offset corresponds to a linear offset in a local projection.  The
+offset unit may be in one of \code{PS_ARCSEC}, \code{PS_ARCMIN},
+\code{PS_DEGREE}, and \code{PS_RADIAN}, which specifies the units of
+the offset only.
 
 \begin{verbatim}
 psSphere *psSphereGetOffset(const psSphere *restrict position1, 
                             const psSphere *restrict position2, 
-                            const char *type);
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit);
+
 psSphere *psSphereSetOffset(const psSphere *restrict position,
                             const psSphere *restrict offset,
-                            const char *type);
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit);
+
+typedef enum {
+ PS_SPHERICAL;
+ PS_LINEAR;
+} psSphereOffsetMode;
+
+typedef enum {
+ PS_ARCSEC;
+ PS_ARCMIN;
+ PS_DEGREE;
+ PS_RADIAN;
+} psSphereOffsetUnit;
 \end{verbatim}
 Note that these should propagate the errors appropriately.
@@ -3412,5 +3591,5 @@
 \begin{verbatim}
 psGrommit *psGrommitAlloc(const psExposure *exp);
-void psGrommitFree(psGrommit *grommit);
+void p_psGrommitFree(psGrommit *grommit);
 \end{verbatim}
 
