Index: /tags/ipp-1-X/rel5_1/psModules/.cvsignore
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/.cvsignore	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/.cvsignore	(revision 22108)
@@ -0,0 +1,18 @@
+autom4te.cache
+Makefile
+config.log
+config.status
+libtool
+Makefile.in
+aclocal.m4
+configure
+Doxyfile
+DoxygenLog
+docs
+man
+psmodule-config
+psmodule.pc
+bin
+include
+lib
+
Index: /tags/ipp-1-X/rel5_1/psModules/AUTHORS
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/AUTHORS	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/AUTHORS	(revision 22108)
@@ -0,0 +1,1 @@
+Maui High Performance Computing Center, University of Hawai'i
Index: /tags/ipp-1-X/rel5_1/psModules/COPYING
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/COPYING	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/COPYING	(revision 22108)
@@ -0,0 +1,6 @@
+(C) 2004 University of Hawai'i
+
+Permission to copy/distribute to be governed by:
+    Institute for Astronomy
+    2680 Woodlawn Drive
+    Honolulu, HI 96822-1897
Index: /tags/ipp-1-X/rel5_1/psModules/ChangeLog
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/ChangeLog	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/ChangeLog	(revision 22108)
@@ -0,0 +1,1 @@
+ 
Index: /tags/ipp-1-X/rel5_1/psModules/Doxyfile.in
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/Doxyfile.in	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/Doxyfile.in	(revision 22108)
@@ -0,0 +1,1079 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Pan-STARRS Module Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = @VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = @prefix@/docs/psmodule
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = DoxygenLog
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = src
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.h *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = *_wrap.c
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 10
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = times
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED             = DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
Index: /tags/ipp-1-X/rel5_1/psModules/INSTALL
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/INSTALL	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/INSTALL	(revision 22108)
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Type `make install' to install the programs and any data files and
+     documentation.
+
+  4. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
Index: /tags/ipp-1-X/rel5_1/psModules/Makefile.am
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/Makefile.am	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/Makefile.am	(revision 22108)
@@ -0,0 +1,27 @@
+
+SUBDIRS = src test
+
+bin_SCRIPTS = psmodule-config
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA= psmodule.pc
+
+EXTRA_DIST = Doxyfile.in psmodule-config.in psmodule.pc.in
+
+docs: Doxyfile $(prefix)/docs/psmodule $(mandir)/man3
+	$(DOXYGEN)
+	mv -f $(prefix)/docs/psmodule/man/man3/* $(mandir)/man3
+	rm -rf $(prefix)/docs/psmodule/man
+
+$(prefix)/docs/psmodule:
+	mkdir -p $(prefix)/docs/psmodule
+
+$(mandir)/man3:
+	mkdir -p $(mandir)/man3
+
+uninstall-hook:
+	rm -rf $(prefix)/docs/psmodule/*
+
+CLEANFILES = $(prefix)/docs/psmodule/*
+
+test: check
Index: /tags/ipp-1-X/rel5_1/psModules/Makefile.cvs
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/Makefile.cvs	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/Makefile.cvs	(revision 22108)
@@ -0,0 +1,9 @@
+default: all
+
+all:
+	if [ "`which glibtoolize`" != "" ] ; then glibtoolize --force ; else libtoolize --force ; fi
+	aclocal
+	autoheader
+	automake
+	autoconf
+
Index: /tags/ipp-1-X/rel5_1/psModules/NEWS
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/NEWS	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/NEWS	(revision 22108)
@@ -0,0 +1,1 @@
+ 
Index: /tags/ipp-1-X/rel5_1/psModules/README
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/README	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/README	(revision 22108)
@@ -0,0 +1,1 @@
+
Index: /tags/ipp-1-X/rel5_1/psModules/TODO
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/TODO	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/TODO	(revision 22108)
@@ -0,0 +1,1 @@
+ 
Index: /tags/ipp-1-X/rel5_1/psModules/config.guess
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/config.guess	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/config.guess	(revision 22108)
@@ -0,0 +1,1411 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-06-17'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+## for Red Hat Linux
+if test -f /etc/redhat-release ; then
+    VENDOR=redhat ;
+else
+    VENDOR= ;
+fi
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /tags/ipp-1-X/rel5_1/psModules/config.sub
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/config.sub	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/config.sub	(revision 22108)
@@ -0,0 +1,1500 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-06-18'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| s390 | s390x \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| s390-* | s390x-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /tags/ipp-1-X/rel5_1/psModules/configure.ac
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/configure.ac	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/configure.ac	(revision 22108)
@@ -0,0 +1,61 @@
+AC_INIT([psmodule],[0.5.1],[http://www.pan-starrs.org/bugzilla])
+
+AM_CONFIG_HEADER(src/config.h)
+AM_INIT_AUTOMAKE(psmodule, 0.5.1)
+
+AC_LANG(C)
+AC_PROG_CC
+
+dnl AC_SUBST(LDFLAGS)
+AC_SUBST(CFLAGS)
+
+AC_MSG_CHECKING([C99 flag])
+if test "$GCC" == "yes"
+then
+CFLAGS="${CFLAGS=} -std=gnu99"
+AC_MSG_RESULT([-std=gnu99])
+else
+CFLAGS="${CFLAGS=} -std=c99"
+AC_MSG_RESULT([-std=c99])
+fi
+
+AC_GNU_SOURCE
+
+AC_PROG_INSTALL
+AM_PROG_LIBTOOL
+
+AC_PREFIX_DEFAULT([`pwd`])
+test "$prefix" = NONE && prefix=`pwd`
+
+DOXYGEN="doxygen Doxyfile"
+AC_CHECK_PROG(DOXYGEN,doxygen,[echo Doxygen not detected in configure stage.])
+AC_SUBST(DOXYGEN,$DOXYGEN)
+
+AC_ARG_WITH(pslib-config,
+[  --with-pslib-config=FILE  Specify location of psLib-config script],
+[PSLIB_CONFIG=$withval],
+[PSLIB_CONFIG=`which pslib-config`])
+AC_CHECK_FILE($PSLIB_CONFIG,[],
+    [AC_MSG_ERROR([psLib is required.  If not in path, use --with-pslib-config to specify pslib-config script location.])])
+AC_MSG_CHECKING([PSLIB cflags])
+PSLIB_CFLAGS="`${PSLIB_CONFIG} --cflags`"
+AC_MSG_RESULT([${PSLIB_CFLAGS}])
+AC_MSG_CHECKING([PSLIB libs])
+PSLIB_LIBS="`${PSLIB_CONFIG} --libs`"
+AC_MSG_RESULT([${PSLIB_LIBS}])
+CFLAGS="${CFLAGS=} ${PSLIB_CFLAGS}"
+LDFLAGS="${LDFLAGS=} ${PSLIB_LIBS}"
+
+dnl Check the libraries to see if they exist, etc.
+AC_CHECK_LIB(pslib,main,,AC_MSG_ERROR(psLib library required))
+
+CFLAGS="${CFLAGS=} -Wall -Werror"
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([src/Makefile])
+AC_CONFIG_FILES([test/Makefile])
+AC_CONFIG_FILES([Doxyfile])
+AC_CONFIG_FILES([psmodule-config])
+AC_CONFIG_FILES([psmodule.pc])
+
+AC_OUTPUT
Index: /tags/ipp-1-X/rel5_1/psModules/depcomp
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/depcomp	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/depcomp	(revision 22108)
@@ -0,0 +1,441 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  This file always lives in the current directory.
+  # Also, the AIX compiler puts `$object:' at the start of each line;
+  # $object doesn't have directory information.
+  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  outname="$stripped.o"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Must come before tru64.
+
+  # Intel's C compiler understands `-MD -MF file'.  However
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 AIX compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put 
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+
+   tmpdepfile1="$object.d"
+   tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` 
+   if test "$libtool" = yes; then
+      "$@" -Wc,-MD
+   else
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   else
+      tmpdepfile="$tmpdepfile2"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a space and a tab in the [].
+      sed -e 's,^.*\.[a-z]*:[ 	]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  test -z "$dashmflag" && dashmflag=-M
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*) # this is libtool, let us make it quiet
+      for arg
+      do # cycle over the arguments
+        case "$arg" in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" $dashmflag | sed 's:^[^:]*\:[ 	]*:'"$object"'\: :' > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  # X makedepend
+  (
+    shift
+    cleared=no
+    for arg in "$@"; do
+      case $cleared in no)
+        set ""; shift
+	cleared=yes
+      esac
+      case "$arg" in
+        -D*|-I*)
+	  set fnord "$@" "$arg"; shift;;
+	-*)
+	  ;;
+	*)
+	  set fnord "$@" "$arg"; shift;;
+      esac
+    done
+    obj_suffix="`echo $object | sed 's/^.*\././'`"
+    touch "$tmpdepfile"
+    ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tail +3 "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*)
+      for arg
+      do # cycle over the arguments
+        case $arg in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*)
+      for arg
+      do # cycle over the arguments
+        case $arg in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" -E |
+    sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
Index: /tags/ipp-1-X/rel5_1/psModules/install-sh
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/install-sh	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/install-sh	(revision 22108)
@@ -0,0 +1,276 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd=$cpprog
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd=$stripprog
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "$0: no input file specified" >&2
+	exit 1
+else
+	:
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+
+	if [ -d "$dst" ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=$mkdirprog
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f "$src" ] || [ -d "$src" ]
+	then
+		:
+	else
+		echo "$0: $src does not exist" >&2
+		exit 1
+	fi
+
+	if [ x"$dst" = x ]
+	then
+		echo "$0: no destination specified" >&2
+		exit 1
+	else
+		:
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d "$dst" ]
+	then
+		dst=$dst/`basename "$src"`
+	else
+		:
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+	'
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp=$pathcomp$1
+	shift
+
+	if [ ! -d "$pathcomp" ] ;
+        then
+		$mkdirprog "$pathcomp"
+	else
+		:
+	fi
+
+	pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd "$dst" &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		dstfile=`basename "$dst" $transformbasename |
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		:
+	fi
+
+# Make a couple of temp file names in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+	rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+	trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+	if [ -f "$dstdir/$dstfile" ]
+	then
+		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+		{
+		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		  (exit 1); exit
+		}
+	else
+		:
+	fi
+} &&
+
+# Now rename the file to the real destination.
+
+	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+	(exit 0); exit
+}
Index: /tags/ipp-1-X/rel5_1/psModules/missing
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/missing	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/missing	(revision 22108)
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
Index: /tags/ipp-1-X/rel5_1/psModules/mkinstalldirs
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/mkinstalldirs	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/mkinstalldirs	(revision 22108)
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage" 1>&2
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+case $dirmode in
+  '')
+    if mkdir -p -- . 2>/dev/null; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+  	errstatus=$lasterr
+      else
+  	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+    	  lasterr=""
+  	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+  	  if test ! -z "$lasterr"; then
+  	    errstatus=$lasterr
+  	  fi
+  	fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
Index: /tags/ipp-1-X/rel5_1/psModules/psmodule-config.in
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/psmodule-config.in	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/psmodule-config.in	(revision 22108)
@@ -0,0 +1,75 @@
+#! /bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+
+usage()
+{
+    cat <<EOF
+Usage: pslib-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix		print psLib installation prefix
+  --libs		print library linking information
+  --cflags		print pre-processor and compiler flags
+  --help		display this help and exit
+  --version		output version information
+
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+cflags=false
+libs=false
+
+while test $# -gt 0; do
+    case "$1" in
+    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) optarg= ;;
+    esac
+
+    case "$1" in
+    --prefix=*)
+	prefix=$optarg
+	;;
+
+    --prefix)
+	echo $prefix
+	;;
+
+    --version)
+	echo @VERSION@
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+       	echo @CFLAGS@
+       	;;
+
+    --libs)
+       	echo -L@libdir@ -lpsmodule @LDFLAGS@
+       	;;
+
+    --deps)
+       	echo @LDFLAGS@
+       	;;
+    *)
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+
+exit 0
Index: /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevelop
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevelop	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevelop	(revision 22108)
@@ -0,0 +1,180 @@
+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>Robert Daniel DeSonia</author>
+    <email>desonia@mhpcc.hawaii.edu</email>
+    <version>0.1</version>
+    <projectmanagement>KDevAutoProject</projectmanagement>
+    <primarylanguage>C</primarylanguage>
+    <keywords>
+      <keyword>C</keyword>
+      <keyword>Code</keyword>
+    </keywords>
+    <projectdirectory>.</projectdirectory>
+    <absoluteprojectpath>false</absoluteprojectpath>
+    <description/>
+    <ignoreparts/>
+    <secondaryLanguages/>
+  </general>
+  <kdevautoproject>
+    <general>
+      <activetarget>src/psmodule</activetarget>
+      <useconfiguration>debug</useconfiguration>
+    </general>
+    <run>
+      <mainprogram>src/tst_pmFlatField</mainprogram>
+      <terminal>true</terminal>
+      <directoryradio>executable</directoryradio>
+      <customdirectory>/</customdirectory>
+      <programargs/>
+      <autocompile>true</autocompile>
+      <envvars/>
+    </run>
+    <configurations>
+      <optimized>
+        <builddir>optimized</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cflags>-O2 -g0</cflags>
+      </optimized>
+      <debug>
+        <configargs>--enable-debug=full</configargs>
+        <builddir>debug</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cflags>-O0 -g3</cflags>
+      </debug>
+    </configurations>
+    <make>
+      <envvars>
+        <envvar value="1" name="WANT_AUTOCONF_2_5" />
+        <envvar value="1" name="WANT_AUTOMAKE_1_6" />
+      </envvars>
+      <abortonerror>false</abortonerror>
+      <numberofjobs>1</numberofjobs>
+      <dontact>false</dontact>
+      <makebin/>
+    </make>
+  </kdevautoproject>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>clanlib</toc>
+      <toc>w3c-dom-level2-html</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>libstdc++</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>php</toc>
+      <toc>php_bugs</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>stl</toc>
+      <toc>w3c-svg</toc>
+      <toc>sw</toc>
+      <toc>w3c-uaag10</toc>
+      <toc>wxwidgets_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+    <projectdoc>
+      <userdocDir>html/</userdocDir>
+      <apidocDir>html/</apidocDir>
+    </projectdoc>
+    <ignorekdocs/>
+    <ignoredevhelp/>
+  </kdevdoctreeview>
+  <kdevfilecreate>
+    <filetypes/>
+    <useglobaltypes>
+      <type ext="c" />
+      <type ext="h" />
+    </useglobaltypes>
+  </kdevfilecreate>
+  <kdevfileview>
+    <groups>
+      <group pattern="*.h" name="Header files" />
+      <group pattern="*.c" name="Source files" />
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <showvcsfields>false</showvcsfields>
+    </tree>
+  </kdevfileview>
+  <kdevcppsupport>
+    <references/>
+    <codecompletion>
+      <includeGlobalFunctions>true</includeGlobalFunctions>
+      <includeTypes>true</includeTypes>
+      <includeEnums>true</includeEnums>
+      <includeTypedefs>false</includeTypedefs>
+      <automaticCodeCompletion>true</automaticCodeCompletion>
+      <automaticArgumentsHint>true</automaticArgumentsHint>
+      <automaticHeaderCompletion>true</automaticHeaderCompletion>
+      <codeCompletionDelay>250</codeCompletionDelay>
+      <argumentsHintDelay>400</argumentsHintDelay>
+      <headerCompletionDelay>250</headerCompletionDelay>
+    </codecompletion>
+  </kdevcppsupport>
+  <cppsupportpart>
+    <filetemplates>
+      <interfacesuffix>.h</interfacesuffix>
+      <implementationsuffix>.cpp</implementationsuffix>
+    </filetemplates>
+  </cppsupportpart>
+  <kdevdebugger>
+    <general>
+      <programargs/>
+      <gdbpath/>
+      <dbgshell/>
+      <configGdbScript/>
+      <runShellScript/>
+      <runGdbScript/>
+      <breakonloadinglibs>true</breakonloadinglibs>
+      <separatetty>false</separatetty>
+      <floatingtoolbar>false</floatingtoolbar>
+    </general>
+    <display>
+      <staticmembers>false</staticmembers>
+      <demanglenames>true</demanglenames>
+    </display>
+  </kdevdebugger>
+  <kdevcvsservice>
+    <recursivewhenupdate>true</recursivewhenupdate>
+    <prunedirswhenupdate>true</prunedirswhenupdate>
+    <createdirswhenupdate>true</createdirswhenupdate>
+    <recursivewhencommitremove>true</recursivewhencommitremove>
+    <revertoptions>-C</revertoptions>
+  </kdevcvsservice>
+</kdevelop>
Index: /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevses
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevses	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/psmodule.kdevses	(revision 22108)
@@ -0,0 +1,26 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE KDevPrjSession>
+<KDevPrjSession>
+ <DocsAndViews NumberOfDocuments="2" >
+  <Doc0 NumberOfViews="1" URL="file:///home/desonia/panstarrs/psModule/src/pmSubtractSky.h" >
+   <View0 line="24" Type="Source" />
+  </Doc0>
+  <Doc1 NumberOfViews="1" URL="file:///home/desonia/panstarrs/psModule/configure.ac" >
+   <View0 line="10" Type="Source" />
+  </Doc1>
+ </DocsAndViews>
+ <pluginList>
+  <kdevdebugger>
+   <breakpointList/>
+  </kdevdebugger>
+  <kdevbookmarks>
+   <bookmarks/>
+  </kdevbookmarks>
+  <kdevvalgrind>
+   <executable path="" params="" />
+   <valgrind path="" params="" />
+   <calltree path="" params="" />
+   <kcachegrind path="" />
+  </kdevvalgrind>
+ </pluginList>
+</KDevPrjSession>
Index: /tags/ipp-1-X/rel5_1/psModules/psmodule.pc.in
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/psmodule.pc.in	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/psmodule.pc.in	(revision 22108)
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: psLib
+Description: Pan-STARRS Library
+Version: @VERSION@
+Libs: -L@libdir@ -lpsmodule @LDFLAGS@
+Cflags: @CFLAGS@
Index: /tags/ipp-1-X/rel5_1/psModules/src/.cvsignore
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/.cvsignore	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/.cvsignore	(revision 22108)
@@ -0,0 +1,7 @@
+.deps
+Makefile
+config.h
+stamp-h1
+Makefile.in
+config.h.in
+
Index: /tags/ipp-1-X/rel5_1/psModules/src/Makefile.am
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/Makefile.am	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/Makefile.am	(revision 22108)
@@ -0,0 +1,12 @@
+lib_LIBRARIES = libpsmodule.a
+
+libpsmodule_a_SOURCES = pmFlatField.c pmMaskBadPixels.c pmSubtractBias.c \
+  pmSubtractBias.c pmNonLinear.c pmReadoutCombine.c pmSubtractSky.c pmObjects.c
+
+libpsmodule_a_HEADERS = pmFlatFieldErrors.h pmMaskBadPixelsErrors.h \
+  pmFlatField.h pmMaskBadPixels.h pmSubtractBias.h pmSubtractBias.h \
+  pmNonLinear.h pmReadoutCombine.h pmSubtractSky.h pmObjects.h
+
+EXTRA_DIST = psErrorCodes.dat
+
+libpsmodule_adir = $(includedir)
Index: /tags/ipp-1-X/rel5_1/psModules/src/mainpage.dox
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/mainpage.dox	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/mainpage.dox	(revision 22108)
@@ -0,0 +1,111 @@
+/** @mainpage psModule Image Processing Library
+
+
+@section intro Introduction
+This library contains the Pan-STARRS Image Processing Pipeline (IPP) modules (psModule). These modules
+use the functionality of the Pan-STARRS Library (psLib) to perform more complex tasks associated with image
+processing. Modules were constructed to support each of the required processing stages and are listed according
+to the particular processing stage for which they will primarily be used. To preserve namespace, globally-visible
+structures and functions are prefixed with pm, an abbreviation for Pan-STARRS Modules.
+
+Modules in this release include:
+
+ - Subtract bias (pmSubtractBias)
+ - Correct for non-linearity (pmNonLinear)
+ - Flat-field (pmFlatField)
+ - Mask bad pixels (pmMaskBadPixels)
+ - Combine readouts (pmReadoutCombine)
+ - Subtract sky (pmSubtractSky)
+ - Object detection (pmObjects)
+
+The installed code for psModule consists of header files and a binary library.
+
+@section extinstall Required external Libraries
+
+Before building psLib from source, several external software libraries must
+be installed. These include:
+ - Pan-STARRS Library (psLib)
+     - Available from the Maui High Performance Computiong Center (MHPCC) at https://mhpcc.pan-starrs.org/code/releases
+     - Compatibility tested with rel5
+     - Note, psLib itself has many external library dependencies.
+ - Doxygen Documentation System
+     - Only needed if code documentation is to be made
+     - Available at http://www.doxygen.org
+     - Compatibility tested with version 1.3.6
+     - The optional companion package, GraphViz (a.k.a., the 'dot' command), is recommended to enable header-file dependency diagrams
+
+We recommend using the particular versions listed as compatibility tested, as
+that is the only versions of the external libraries tested to work well with psLib
+and psModule.  Though it is quite possible that later versions of the libraries
+listed will also work, care must be taken when upgrading these libraries to verify
+that its functionality is compatible with the tested version.
+
+@section install How to Build from Source
+
+Tested versions of psModule are put into a tar file and can be downloaded from:
+
+https://mhpcc.pan-starrs.org/code/releases
+
+Though MHPCC recommends using the released packaged tar files descibed above,
+both daily development snapshots and direct CVS access is available.  The daily
+snapshots are available at
+
+https://mhpcc.pan-starrs.org/code/snapshots
+
+These snapshots represents development code as found in CVS on the day
+specified in the filename.  This code set may not be functional, vary in
+testing, etc.  Reasonable efforts are made to ensure that the code does
+actually compile, but given the nature of code development, even that is not
+always the case.  Use snapshots with great caution.
+
+If one has a login account on mhpcc.pan-starrs.org, direct CVS access is
+possible.  Example of the commands required for direct CVS retrieval are
+as follows:
+<pre>
+$ cvs -d:ext:USERNAME@mhpcc.pan-starrs.org:/data/panstarrs/cvsroot co -r RELEASEBRANCH psModule
+</pre>
+where:
+  - USERNAME is your login name on the server
+  - RELEASEBRANCH is the desired release branch, e.g. rel5.
+
+
+@section build How to Build and Test the psModule Library.
+
+The psModule library and associated tests are made via the GNU autoconf/automake system.
+
+The source should build using the configure script in the psModule directory.  The
+recommended steps are:
+<pre>
+$ cd psModule
+$ ./configure
+$ make
+$ make check
+$ make install
+</pre>
+<i>Unless otherwise specified, the library is installed with PREFIX of the current directory.</i>
+
+Other configuration options, such as location of external libraries, are also available.
+To get a list of options, type the following in the top psModule directory.
+<pre>
+$ configure --help
+</pre>
+A likely option needed is '--with-pslib-config', which specifies the location of
+the configuration script for psLib.  By default, iconfigure searches for it using PATH, but that
+is often not sufficient.
+
+@section doc How to Create Code Documentation
+
+Both HTML and man page documentation may be generated from the inline
+documentation embedded in the code using the following commands:
+<pre>
+$ cd psModule
+$ make docs
+</pre>
+<i>This places documentation in PREFIX/docs.</i>
+
+Also, a prebuilt set of code documentation for both the releases and last
+CVS snapshot can be found at:
+
+https://mhpcc.pan-starrs.org/docs/
+
+*/
Index: /tags/ipp-1-X/rel5_1/psModules/src/parseErrorCodes.pl
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/parseErrorCodes.pl	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/parseErrorCodes.pl	(revision 22108)
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+my @ErrorCodes        = ();
+my @ErrorDescriptions = ();
+
+my $data = "psErrorCodes.dat";
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "data=s"  => \$data,
+    "verbose" => \$verbose,
+    "help"    => \$help
+);
+
+if ($help) {
+    print "Usage: parseErrorCodes ", "[--data=$data] ", "[--help] ",
+      "[--verbose] filename [filename ...]\n\n";
+    exit(0);
+}
+
+print "Using data file '$data'\n" if $verbose;
+unless ( open( DATAFILE, "<", $data ) ) {
+    die "Can not open data file $data.";
+}
+
+print "Datafile:\n" if $verbose;
+while (<DATAFILE>) {
+    chop;
+    if (/^\s*\#/) {
+        print "C $_\n" if $verbose;
+    }
+    else {
+        if (/^\s*(\w+)\s+([\%\w].*)/) {
+            my $ErrorCode        = $1;
+            my $ErrorDescription = $2;
+            print "  $ErrorCode: '$ErrorDescription'\n" if $verbose;
+            push( @ErrorCodes,        $ErrorCode );
+            push( @ErrorDescriptions, $ErrorDescription );
+        } else {
+            print "I $_\n" if $verbose;
+        }
+    }
+}
+close(DATAFILE);
+
+my $found = $#ErrorCodes + 1;
+print "\nFound $found error codes.\n" if $verbose;
+
+foreach (@ARGV) {
+    my $filename = $_;
+    my @result   = ();
+
+    die "Failed to open input file"
+      if !open( INFILE, "<", $filename );
+
+    print "\nOutput File:\n" if $verbose;
+    while (<INFILE>) {
+        chop;
+        push( @result, $_ );
+        if (/^\s*\/\/~Start(.*)$/) {
+            $line = $1;
+            for ( $n = 0 ; $n < $found ; $n++ ) {
+                $_ = $line;
+                s/\$1/$ErrorCodes[$n]/g;
+                s/\$2/$ErrorDescriptions[$n]/g;
+                s/\$n/$n/g;
+                push( @result, $_ );
+                print "$_\n" if $verbose;
+            }
+
+            $break = 0;
+            while ( ( $break == 0 ) && ( $_ = <INFILE> ) ) {
+                if (/^\s*\/\/~End/) {
+                    $break = 1;
+                }
+            }
+            chop;
+            push( @result, $_ );
+        }
+    }
+
+    close(INFILE);
+
+    die "Failed to overwrite input file"
+      if !open( OUTFILE, ">", $filename );
+
+    foreach (@result) {
+        print OUTFILE "$_\n";
+        print "$_\n" if $verbose;
+    }
+
+    close(OUTFILE);
+
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.c	(revision 22108)
@@ -0,0 +1,181 @@
+/** @file  pmFlatField.c
+ *
+ *  @brief Given an input image and a flat field image, pmFlatField shall divide the input image by the flat
+ *  field image.
+ *
+ *  The input image, in, and the flat field image, flat, need not be the same size, since the input image may
+ *  already have been trimmed (following overscan subtraction), but the function shall use the offsets in the
+ *  image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct pixel on the flat
+ *  field. In the event that the flat image is too small (i.e., pixels on the input image refer to pixels
+ *  outside the range of the flat image), the function shall generate an error. Pixels which are negative or
+ *  zero in the flat shall be masked in the input image with the value PM_MASK_FLAT. Negative pixels in the
+ *  flat may be set to zero so that they are treated identically to zeroes. Any pixels masked in the flat
+ *  shall be masked with corresponding values in the output. The function shall not normalize the flat; this
+ *  responsibility is left to the caller. This function is basically equivalent to a divide (with psImageOp),
+ *  but with care for the region that is divided, checking for negative pixels, and copying of the mask from
+ *  the flat to the output.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-06 02:42:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include <string.h>
+
+#include "pslib.h"
+#include "pmFlatField.h"
+#include "pmMaskBadPixels.h"
+#include "pmFlatFieldErrors.h"
+
+
+bool pmFlatField(psReadout *in, const psReadout *flat)
+{
+    int i = 0;
+    int j = 0;
+    int totOffCol = 0;
+    int totOffRow = 0;
+    psElemType inType;
+    psElemType flatType;
+    psElemType maskType;
+    psImage *inImage = NULL;
+    psImage *inMask = NULL;
+    psImage *flatImage = NULL;
+
+
+    // Check for nulls
+    if (in == NULL) {
+        return true;       // Readout may not have data in it
+    } else if(flat==NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmFlatField_NULL_FLAT_READOUT);
+        return false;
+    }
+
+    inImage = in->image;
+    flatImage = flat->image;
+    if (inImage == NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmFlatField_NULL_INPUT_IMAGE);
+        return false;
+    } else if(flatImage == NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmFlatField_NULL_FLAT_IMAGE);
+        return false;
+    } else if(in->mask == NULL) {
+        in->mask = psImageAlloc(inImage->numCols, inImage->numRows, PS_TYPE_MASK);
+        memset(in->mask->data.V[0], 0, inImage->numCols*inImage->numRows*PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
+    }
+    inMask = in->mask;
+
+    // Check input image and its mask are not larger than flat image
+    if(inImage->numRows>flatImage->numRows || inImage->numCols>flatImage->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmFlatField_SIZE_INPUT_IMAGE,
+                 inImage->numRows, inImage->numCols, flatImage->numRows, flatImage->numCols);
+        return false;
+    } else if(inMask->numRows>flatImage->numRows || inMask->numCols > flatImage->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmFlatField_SIZE_MASK_IMAGE,
+                 inMask->numRows, inMask->numCols, flatImage->numRows, flatImage->numCols);
+        return false;
+    }
+
+    // Determine total offset based on image offset with chip offset
+    totOffCol = inImage->col0 + in->col0;
+    totOffRow = inImage->row0 + in->row0;
+
+    // Check that offsets are within image limits
+    if(totOffRow>=flatImage->numRows || totOffCol>=flatImage->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmFlatField_OFFSET_FLAT_IMAGE,
+                 totOffRow, totOffCol, flatImage->numRows, flatImage->numCols);
+        return false;
+    } else if(totOffRow>=inImage->numRows || totOffCol>=inImage->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmFlatField_OFFSET_INPUT_IMAGE,
+                 totOffRow, totOffCol, inImage->numRows, inImage->numCols);
+        return false;
+    } else if(totOffRow>=inMask->numRows || totOffCol>=inMask->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmFlatField_OFFSET_MASK_IMAGE,
+                 totOffRow, totOffCol, inMask->numRows, inMask->numCols);
+        return false;
+    }
+
+    // Check for incorrect types
+    inType = inImage->type.type;
+    flatType = flatImage->type.type;
+    maskType = inMask->type.type;
+    if(PS_IS_PSELEMTYPE_COMPLEX(inType)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_INPUT_IMAGE,
+                 inType);
+        return false;
+    } else if(PS_IS_PSELEMTYPE_COMPLEX(flatType)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_FLAT_IMAGE,
+                 flatType);
+        return false;
+    } else if(maskType != PS_TYPE_MASK) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_MASK_IMAGE,
+                 maskType);
+        return false;
+    } else if(inType != flatType) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_MISMATCH,
+                 inType, flatType);
+        return false;
+    }
+
+    // Macro for all PS types
+    #define PM_FLAT_DIVISION(TYPE)                                                                           \
+case PS_TYPE_##TYPE:                                                                                         \
+    /* Per Eugene's request, use two sets of loops: first to fill mask, second to avoid div with bad pix */  \
+    for(j = totOffRow; j < inImage->numRows; j++) {                                                          \
+        for(i = totOffCol; i < inImage->numCols; i++) {                                                      \
+            if(flatImage->data.TYPE[j][i] <= 0.0) {                                                          \
+                /* Negative or zero flat pixels shall be masked in input image as  PM_MASK_FLAT */           \
+                inMask->data.PS_TYPE_MASK_DATA[j][i] |= PM_MASK_FLAT;                                        \
+                flatImage->data.TYPE[j][i] = 0.0;                                                            \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    for(j = totOffRow; j < inImage->numRows; j++) {                                                          \
+        for(i = totOffCol; i < inImage->numCols; i++) {                                                      \
+            if(!inMask->data.PS_TYPE_MASK_DATA[j][i]) {                                                      \
+                /* Module shall divide the input image by the flat-fielded image */                          \
+                inImage->data.TYPE[j][i] /= flatImage->data.TYPE[j][i];                                      \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    break;
+
+    switch(inType) {
+        PM_FLAT_DIVISION(U8);
+        PM_FLAT_DIVISION(U16);
+        PM_FLAT_DIVISION(U32);
+        PM_FLAT_DIVISION(U64);
+        PM_FLAT_DIVISION(S8);
+        PM_FLAT_DIVISION(S16);
+        PM_FLAT_DIVISION(S32);
+        PM_FLAT_DIVISION(S64);
+        PM_FLAT_DIVISION(F32);
+        PM_FLAT_DIVISION(F64);
+    default:
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_UNSUPPORTED,
+                 inType);
+    }
+
+    return true;
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmFlatField.h	(revision 22108)
@@ -0,0 +1,37 @@
+/** @file  pmFlatField.h
+ *
+ *  @brief Given an input image and a flat field image, pmFlatField shall divide the input image by the flat
+ *  field image.
+ *
+ *  The input image, in, and the flat field image, flat, need not be the same size, since the input image may
+ *  already have been trimmed (following overscan subtraction), but the function shall use the offsets in the
+ *  image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct pixel on the flat
+ *  field. In the event that the flat image is too small (i.e., pixels on the input image refer to pixels
+ *  outside the range of the flat image), the function shall generate an error. Pixels which are negative or
+ *  zero in the flat shall be masked in the input image with the value PM_MASK_FLAT. Negative pixels in the
+ *  flat may be set to zero so that they are treated identically to zeroes. Any pixels masked in the flat
+ *  shall be masked with corresponding values in the output. The function shall not normalize the flat; this
+ *  responsibility is left to the caller. This function is basically equivalent to a divide (with psImageOp),
+ *  but with care for the region that is divided, checking for negative pixels, and copying of the mask from
+ *  the flat to the output.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-22 19:58:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/** Execute flat field module.
+ *
+ *  Given an input image and a flat-field image, pmFlatField shall divide the input image by the flat field
+ *  image.
+ *
+ *  @return  bool: True or false for success or failure
+ */
+bool pmFlatField(
+    psReadout *in,          ///< Redout with input image and mask
+    const psReadout *flat   ///< Readout with flat image
+);
+
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.dat
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.dat	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.dat	(revision 22108)
@@ -0,0 +1,22 @@
+#
+#  This file is used to generate pmFlatFieldErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+pmFlatField_NULL_FLAT_READOUT          Null not allowed for flat readout.
+pmFlatField_NULL_INPUT_IMAGE           Null not allowed for input image.
+pmFlatField_NULL_FLAT_IMAGE            Null not allowed for flat image.
+pmFlatField_SIZE_INPUT_IMAGE           Input image size exceeds that of flat image: (%d, %d) vs (%d, %d)
+pmFlatField_SIZE_MASK_IMAGE            Input image mask size exceeds that of flat image: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_FLAT_IMAGE          Total offset >= flat image size: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_INPUT_IMAGE         Total offset >= input image: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_MASK_IMAGE          Total offset >= input image mask: (%d, %d) vs (%d, %d)
+pmFlatField_TYPE_INPUT_IMAGE           Complex types not allowed for input image. Type: %d
+pmFlatField_TYPE_FLAT_IMAGE            Complex types not allowed for flat image. Type: %d
+pmFlatField_TYPE_MASK_IMAGE            Mask must be PS_TYPE_MASK type. Type: %d
+pmFlatField_TYPE_MISMATCH              Input and flat image types differ: (%d vs %d)
+pmFlatField_TYPE_UNSUPPORTED           Unsupported image datatype. Type: %d
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmFlatFieldErrors.h	(revision 22108)
@@ -0,0 +1,47 @@
+/** @file  pmFlatFieldErrors.h
+ *
+ *  @brief Contains the error text for the flat field module
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 18:15:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PM_FLATFIELD_ERRORS_H
+#define PM_FLATFIELD_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psDataManipErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psFlatFieldErrors.h lines)
+ *     $2  The error text (rest of the line in psFlatFieldErrors.h)
+ *     $n  The order of the source line in psFlatFieldErrors.h (comments excluded)
+ *
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psModule.src."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_pmFlatField_NULL_FLAT_READOUT "Null not allowed for flat readout."
+#define PS_ERRORTEXT_pmFlatField_NULL_INPUT_IMAGE "Null not allowed for input image."
+#define PS_ERRORTEXT_pmFlatField_NULL_FLAT_IMAGE "Null not allowed for flat image."
+#define PS_ERRORTEXT_pmFlatField_SIZE_INPUT_IMAGE "Input image size exceeds that of flat image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_SIZE_MASK_IMAGE "Input image mask size exceeds that of flat image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_FLAT_IMAGE "Total offset >= flat image size: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_INPUT_IMAGE "Total offset >= input image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_MASK_IMAGE "Total offset >= input image mask: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_TYPE_INPUT_IMAGE "Complex types not allowed for input image. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_FLAT_IMAGE "Complex types not allowed for flat image. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_MASK_IMAGE "Mask must be PS_TYPE_MASK type. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_MISMATCH "Input and flat image types differ: (%d vs %d)"
+#define PS_ERRORTEXT_pmFlatField_TYPE_UNSUPPORTED "Unsupported image datatype. Type: %d"
+//~End
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.c	(revision 22108)
@@ -0,0 +1,183 @@
+/** @file  pmMaskBadPixels.c
+ *
+ *  @brief Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  Given an input image, in, a bad pixel mask, a corresponding value in the bad pixel mask to mask in the
+ * input image, maskVal, a saturation level, and a growing radius, pmMaskBadPixels shall mask in the input
+ * image those pixels in the bad pixel mask that match the value to mask. Note that the input image, in, is
+ * modified in-place. All pixels in the mask which satisfy the maskVal shall have their corresponding pixels
+ * masked in the input image, in. All pixels which satisfy the growVal shall have their corresponding
+ * pixels, along with all pixels within the grow radius masked. Pixels which have flux greater than sat shall
+ * also be masked, but not grown. Note that the input image, in, and the mask need not be the same size, since
+ * the input image may already have been trimmed (following overscan subtraction), but the function shall use
+ * the offsets in the image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct
+ * pixel on the mask. In the event that the mask image is too small (i.e., pixels on the input image refer to
+ * pixels outside the range of the mask image), the function shall generate an error.
+ 
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 02:02:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include<string.h>
+
+#include "pmMaskBadPixels.h"
+#include "pmMaskBadPixelsErrors.h"
+
+bool pmMaskBadPixels(psReadout *in, const psImage *mask, unsigned int maskVal, float sat,
+                     unsigned int growVal, int grow)
+{
+    int i = 0;
+    int j = 0;
+    int jj = 0;
+    int ii = 0;
+    int rRound = 0;
+    int rowMin = 0;
+    int rowMax = 0;
+    int colMin = 0;
+    int colMax = 0;
+    int totOffCol = 0;
+    int totOffRow = 0;
+    float r = 0.0f;
+    psElemType inType;
+    psElemType maskType;
+    psImage *inImage = NULL;
+    psImage *inMask = NULL;
+
+
+    // Check for nulls
+    if (in == NULL) {
+        return true;   // Readout may not have data in it
+    } else if(mask==NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE);
+        return false;
+    }
+
+    inImage = in->image;
+    if (inImage == NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_NULL_INPUT_IMAGE);
+        return false;
+    } else if(in->mask == NULL) {
+        in->mask = psImageAlloc(inImage->numCols, inImage->numRows, PS_TYPE_MASK);
+        memset(in->mask->data.V[0], 0, inImage->numCols*inImage->numRows*PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
+    }
+    inMask = in->mask;
+
+    // Check input image and its mask are not larger than mask
+    if(inImage->numRows > mask->numRows || inImage->numCols > mask->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_SIZE_INPUT_IMAGE,
+                 inImage->numRows, inImage->numCols, mask->numRows, mask->numCols);
+        return false;
+    } else if(inMask->numRows>mask->numRows || inMask->numCols>mask->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_SIZE_MASK_IMAGE,
+                 inMask->numRows, inMask->numCols, mask->numRows, mask->numCols);
+        return false;
+    }
+
+    // Determine total offset based on image offset with chip offset
+    totOffCol = inImage->col0 + in->col0;
+    totOffRow = inImage->row0 + in->row0;
+
+    // Check that offsets are within image limits
+    if(totOffRow>=mask->numRows || totOffCol>=mask->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_OFFSET_MASK_IMAGE,
+                 totOffRow, totOffCol, mask->numRows, mask->numCols);
+        return false;
+    } else if(totOffRow>=inImage->numRows || totOffCol>=inImage->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE,
+                 totOffRow, totOffCol, inImage->numRows, inImage->numCols);
+        return false;
+    } else if(totOffRow>=inMask->numRows || totOffCol>=inMask->numCols) {
+        psError( PS_ERR_BAD_PARAMETER_SIZE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK,
+                 totOffRow, totOffCol, inMask->numRows, inMask->numCols);
+        return false;
+    }
+
+    // Check for incorrect types
+    inType = inImage->type.type;
+    maskType = mask->type.type;
+    if(PS_IS_PSELEMTYPE_COMPLEX(inType)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_INPUT_IMAGE,
+                 inType);
+        return false;
+    } else if(maskType!=PS_TYPE_MASK) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_MASK_IMAGE,
+                 maskType);
+        return false;
+    }
+
+    // Macro for all PS types
+    #define PM_BAD_PIXELS(TYPE)                                                                              \
+case PS_TYPE_##TYPE:                                                                                         \
+    for(j=totOffRow; j<inImage->numRows; j++) {                                                              \
+        for(i=totOffCol; i<inImage->numCols; i++) {                                                          \
+            \
+            /* Pixels with flux greater than sat shall be masked */                                          \
+            if(inImage->data.TYPE[j][i] > sat) {                                                             \
+                inMask->data.PS_TYPE_MASK_DATA[j][i] |= PM_MASK_SAT;                                         \
+            }                                                                                                \
+            \
+            /* Pixels which satisfy maskVal shall be masked */                                               \
+            inMask->data.PS_TYPE_MASK_DATA[j][i] |= (mask->data.PS_TYPE_MASK_DATA[j][i]&maskVal);            \
+            \
+            /* Pixels which satisfy growVal and within the grow radius shall be masked */                    \
+            if(mask->data.PS_TYPE_MASK_DATA[j][i] & growVal) {                                               \
+                rowMin = MAX(j-grow, 0);                                                                     \
+                rowMax = MIN(j+grow+1, inImage->numRows);                                                    \
+                colMin = MAX(i-grow, 0);                                                                     \
+                colMax = MIN(i+grow+1, inImage->numCols);                                                    \
+                for(jj=rowMin; jj<rowMax; jj++) {                                                            \
+                    for(ii=colMin; ii<colMax; ii++) {                                                        \
+                        r = sqrtf((ii-i)*(ii-i)+(jj-j)*(jj-j));                                              \
+                        rRound = r + 0.5;                                                                    \
+                        if(rRound <= grow) {                                                                 \
+                            inMask->data.PS_TYPE_MASK_DATA[jj][ii] |=                                        \
+                                    (mask->data.PS_TYPE_MASK_DATA[j][i]&growVal);                            \
+                        }                                                                                    \
+                    }                                                                                        \
+                }                                                                                            \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    break;
+
+    // Switch to call bad pixel masking macro defined above
+    switch(inType) {
+        PM_BAD_PIXELS(U8);
+        PM_BAD_PIXELS(U16);
+        PM_BAD_PIXELS(U32);
+        PM_BAD_PIXELS(U64);
+        PM_BAD_PIXELS(S8);
+        PM_BAD_PIXELS(S16);
+        PM_BAD_PIXELS(S32);
+        PM_BAD_PIXELS(S64);
+        PM_BAD_PIXELS(F32);
+        PM_BAD_PIXELS(F64);
+    default:
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED,
+                 inType);
+    }
+
+    return false;
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixels.h	(revision 22108)
@@ -0,0 +1,60 @@
+/** @file  pmMaskBadPixels.h
+ *
+ *  @brief Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  Given an input image, in, a bad pixel mask, a corresponding value in the bad pixel mask to mask in the
+ *  input image, maskVal, a saturation level, and a growing radius, pmMaskBadPixels shall mask in the input
+ *  image those pixels in the bad pixel mask that match the value to mask. Note that the input image, in, is
+ *  modified in-place. All pixels in the mask which satisfy the maskVal shall have their corresponding pixels
+ *  masked in the input image, in. All pixels which satisfy the growVal shall have their corresponding
+ *  pixels, along with all pixels within the grow radius masked. Pixels which have flux greater than sat shall
+ *  also be masked, but not grown. Note that the input image, in, and the mask need not be the same size,
+ *  since the input image may already have been trimmed (following overscan subtraction), but the function
+ *  shall use the offsets in the image (in->x0 and in->y0) to determine the appropriate offsets to obtain the
+ *  correct pixel on the mask. In the event that the mask image is too small (i.e., pixels on the input image
+ *  refer to pixels outside the range of the mask image), the function shall generate an error.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-17 00:49:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+
+/** Mask values */
+typedef enum {
+    PM_MASK_TRAP    = 0x0001,   ///< The pixel is a charge trap.
+    PM_MASK_BADCOL  = 0x0002,   ///< The pixel is a bad column.
+    PM_MASK_SAT     = 0x0004,   ///< The pixel is saturated.
+    PM_MASK_FLAT    = 0x0008    ///< The pixel is non-positive in the flat-field.
+} pmMaskValue;
+
+/** Macro to find maximum of two numbers */
+#define MAX(A,B)((A)>=(B)?(A):(B))
+
+/** Macro to find minimum of two numbers */
+#define MIN(A,B)((A)<=(B)?(A):(B))
+
+
+/** Execute bad pixels module.
+ *
+ *  Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  @return  bool: True or false for success or failure
+ */
+bool pmMaskBadPixels(
+    psReadout *in,          ///< Readout containing input image data.
+    const psImage *mask,    ///< Mask data to be added to readout mask data.
+    unsigned int maskVal,   ///< Mask value to determine what to add to input mask.
+    float sat,              ///< Saturation limit to mask bad pixels.
+    unsigned int growVal,   ///< Mask data to determine if a circurlar area should be masked.
+    int grow                ///< Radius of mask to apply around pixel.
+);
+
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.dat
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.dat	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.dat	(revision 22108)
@@ -0,0 +1,20 @@
+#
+#  This file is used to generate pmMaskBadPixelsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+pmMaskBadPixels_NULL_MASK_IMAGE            Null not allowed for mask image.
+pmMaskBadPixels_NULL_INPUT_IMAGE           Null not allowed for input image.
+pmMaskBadPixels_SIZE_INPUT_IMAGE           Input image size exceeds that of mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_SIZE_MASK_IMAGE            Input image mask size exceeds that of mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_MASK_IMAGE          Total offset >= mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_INPUT_IMAGE         Total offset >= input image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK    Total offset >= input image mask: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_TYPE_INPUT_IMAGE           Complex types not allowed for input image. Type: %d
+pmMaskBadPixels_TYPE_MASK_IMAGE            Mask must be PS_TYPE_MASK type. Type: %d
+pmMaskBadPixels_TYPE_MISMATCH              Input and flat image types differ: (%d vs %d)
+pmMaskBadPixels_TYPE_UNSUPPORTED           Unsupported image datatype. Type: %d
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmMaskBadPixelsErrors.h	(revision 22108)
@@ -0,0 +1,45 @@
+/** @file  pmMaskBadPixelsErrors.h
+ *
+ *  @brief Contains the error text for the mask bad pixels module
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-24 18:00:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PM_FLATFIELD_ERRORS_H
+#define PM_FLATFIELD_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in pmMaskBadPixelsErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the pmMaskBadPixelsErrors.h lines)
+ *     $2  The error text (rest of the line in pmMaskBadPixelsErrors.h)
+ *     $n  The order of the source line in pmMaskBadPixelsErrors.h (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psModule.src."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE "Null not allowed for mask image."
+#define PS_ERRORTEXT_pmMaskBadPixels_NULL_INPUT_IMAGE "Null not allowed for input image."
+#define PS_ERRORTEXT_pmMaskBadPixels_SIZE_INPUT_IMAGE "Input image size exceeds that of mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_SIZE_MASK_IMAGE "Input image mask size exceeds that of mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_MASK_IMAGE "Total offset >= mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE "Total offset >= input image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK "Total offset >= input image mask: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_INPUT_IMAGE "Complex types not allowed for input image. Type: %d"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_MASK_IMAGE "Mask must be PS_TYPE_MASK type. Type: %d"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_MISMATCH "Input and flat image types differ: (%d vs %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED "Unsupported image datatype. Type: %d"
+//~End
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.c	(revision 22108)
@@ -0,0 +1,123 @@
+/** @file  pmNonLinear.c
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-07 20:00:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: The SDR is silent about image types.  Only F32 was implemented.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+
+#include "pmNonLinear.h"
+
+/******************************************************************************
+pmNonLinearityLookup(): This routine will take an psReadout image as input
+and a 1-D polynomial.  For each pixel in the input image, the polynomial will
+be evaluated at that pixels value, and the image pixel will then be set to
+that value.
+ *****************************************************************************/
+
+psReadout *pmNonLinearityPolynomial(psReadout *inputReadout,
+                                    const psPolynomial1D *input1DPoly)
+{
+    PS_PTR_CHECK_NULL(inputReadout, NULL);
+    PS_PTR_CHECK_NULL(inputReadout->image, NULL);
+    PS_IMAGE_CHECK_TYPE(inputReadout->image, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(input1DPoly, NULL);
+
+    psS32 i;
+    psS32 j;
+
+    for (i=0;i<inputReadout->image->numRows;i++) {
+        for (j=0;j<inputReadout->image->numCols;j++) {
+            inputReadout->image->data.F32[i][j] = psPolynomial1DEval(input1DPoly, inputReadout->image->data.F32[i][j]);
+        }
+    }
+    return(inputReadout);
+}
+
+
+/******************************************************************************
+pmNonLinearityLookup(): This routine will take an psReadout image as input
+and two input vectors, which constitute a lookup table.  For each pixel in
+the input image, that pixels value will be determined in the input vector
+inFluxe, and the corresponding value in outFlux.  The image pixel will then
+be set to the value from outFlux.
+ *****************************************************************************/
+psReadout *pmNonLinearityLookup(psReadout *inputReadout,
+                                const psVector *inFlux,
+                                const psVector *outFlux)
+{
+    PS_PTR_CHECK_NULL(inputReadout,NULL);
+    PS_PTR_CHECK_NULL(inputReadout->image,NULL);
+    PS_IMAGE_CHECK_TYPE(inputReadout->image, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(inFlux,NULL);
+    if (inFlux->n < 2) {
+        psError(PS_ERR_UNKNOWN,true, "pmNonLinearityLookup(): input vector less than 2 elements.  Returning inputReadout image.");
+        return(inputReadout);
+    }
+    PS_PTR_CHECK_NULL(outFlux,NULL);
+    psS32 tableSize = inFlux->n;
+    if (inFlux->n != outFlux->n) {
+        tableSize = PS_MIN(inFlux->n, outFlux->n);
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (%d, %d)\n", inFlux->n, outFlux->n);
+    }
+    PS_VECTOR_CHECK_TYPE(inFlux, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_TYPE(outFlux, PS_TYPE_F32, NULL);
+
+    psS32 i;
+    psS32 j;
+    psS32 binNum;
+    psScalar x;
+    psS32 numPixels = 0;
+    psF32 slope;
+
+    x.type.type = PS_TYPE_F32;
+    for (i=0;i<inputReadout->image->numRows;i++) {
+        for (j=0;j<inputReadout->image->numCols;j++) {
+            x.data.F32 = inputReadout->image->data.F32[i][j];
+            binNum = p_psVectorBinDisect((psVector *)inFlux, &x);
+
+            if (binNum == -2) {
+                // We get here if x is below the table lookup range.
+                inputReadout->image->data.F32[i][j] = outFlux->data.F32[0];
+                numPixels++;
+
+            } else if (binNum == -1) {
+                // We get here if x is above the table lookup range.
+                inputReadout->image->data.F32[i][j] = outFlux->data.F32[tableSize-1];
+                numPixels++;
+
+            } else if (binNum < -2) {
+                // We get here if there was some other problem.
+                psError(PS_ERR_UNKNOWN,true, "pmNonLinearityLookup(): Could not perform p_psVectorBinDisect().  Returning inputReadout image.");
+                return(inputReadout);
+                numPixels++;
+            } else {
+                // Perform linear interpolation.
+                slope = (outFlux->data.F32[binNum+1] - outFlux->data.F32[binNum]) /
+                        (inFlux->data.F32[binNum+1]  - inFlux->data.F32[binNum]);
+                inputReadout->image->data.F32[i][j] = outFlux->data.F32[binNum] +
+                                                      ((x.data.F32 - inFlux->data.F32[binNum]) * slope);
+            }
+        }
+    }
+    if (numPixels > 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmNonLinear.c: pmNonLinearityLookup(): %d pixels outside table.", numPixels);
+    }
+    return(inputReadout);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmNonLinear.h	(revision 22108)
@@ -0,0 +1,26 @@
+/** @file  pmNonLinear.h
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 19:58:18 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_NON_LINEAR_H)
+#define PM_NON_LINEAR_H
+
+#include "pslib.h"
+
+psReadout *pmNonLinearityPolynomial(psReadout *in,
+                                    const psPolynomial1D *coeff);
+
+psReadout *pmNonLinearityLookup(psReadout *in,
+                                const psVector *inFlux,
+                                const psVector *outFlux);
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.c	(revision 22108)
@@ -0,0 +1,2143 @@
+/** @file  pmObjects.c
+ *
+ *  This file will ...
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-01 20:47:40 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "psConstants.h"
+#include "pmObjects.h"
+
+/******************************************************************************
+pmPeakAlloc(): Allocate the psPeak data structure and set appropriate members.
+ *****************************************************************************/
+psPeak *pmPeakAlloc(psS32 x,
+                    psS32 y,
+                    psF32 counts,
+                    psPeakType class)
+{
+    psPeak *tmp = (psPeak *) psAlloc(sizeof(psPeak));
+    tmp->x = x;
+    tmp->y = y;
+    tmp->counts = counts;
+    tmp->class = class;
+
+    return(tmp);
+}
+
+/******************************************************************************
+pmMomentsAlloc(): Allocate the psMoments structure and initialize the members
+to zero.
+ *****************************************************************************/
+psMoments *pmMomentsAlloc()
+{
+    psMoments *tmp = (psMoments *) psAlloc(sizeof(psMoments));
+    tmp->x = 0.0;
+    tmp->y = 0.0;
+    tmp->Sx = 0.0;
+    tmp->Sx = 0.0;
+    tmp->Sxy = 0.0;
+    tmp->Sum = 0.0;
+    tmp->Peak = 0.0;
+    tmp->Sky = 0.0;
+    tmp->nPixels = 0;
+
+    return(tmp);
+}
+
+static void p_psModelFree(psModel *tmp)
+{
+    psFree(tmp->params);
+    psFree(tmp->dparams);
+}
+
+/******************************************************************************
+pmModelAlloc(): Allocate the psModel structure, along with its parameters,
+and initialize the type member.  Initialize the params to 0.0.
+ *****************************************************************************/
+psModel *pmModelAlloc(psModelType type)
+{
+    psModel *tmp = (psModel *) psAlloc(sizeof(psModel));
+
+    tmp->type = type;
+    tmp->chisq = 0.0;
+    switch (type) {
+    case PS_MODEL_GAUSS:
+        tmp->Nparams = 7;
+        tmp->params = (psF32 *) psAlloc(7 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(7 * sizeof(PS_TYPE_F32));
+        break;
+    case PS_MODEL_PGAUSS:
+        tmp->Nparams = 7;
+        tmp->params = (psF32 *) psAlloc(7 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(7 * sizeof(PS_TYPE_F32));
+        break;
+    case PS_MODEL_TWIST_GAUSS:
+        tmp->Nparams = 11;
+        tmp->params = (psF32 *) psAlloc(11 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(11 * sizeof(PS_TYPE_F32));
+        break;
+    case PS_MODEL_WAUSS:
+        tmp->Nparams = 9;
+        tmp->params = (psF32 *) psAlloc(9 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(9 * sizeof(PS_TYPE_F32));
+        break;
+    case PS_MODEL_SERSIC:
+        tmp->Nparams = 8;
+        tmp->params = (psF32 *) psAlloc(8 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(8 * sizeof(PS_TYPE_F32));
+        break;
+    case PS_MODEL_SERSIC_CORE:
+        tmp->Nparams = 12;
+        tmp->params = (psF32 *) psAlloc(12 * sizeof(PS_TYPE_F32));
+        tmp->dparams = (psF32 *) psAlloc(12 * sizeof(PS_TYPE_F32));
+        break;
+    default:
+        psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
+        return(NULL);
+    }
+
+    for (psS32 i = 0 ; i < tmp->Nparams ; i++) {
+        tmp->params[i] = 0.0;
+        tmp->dparams[i] = 0.0;
+    }
+
+    p_psMemSetDeallocator(tmp, (psFreeFcn) p_psModelFree);
+    return(tmp);
+}
+
+/******************************************************************************
+XXX: We don't free pixels and mask since that caused a memory error.
+We might need to increase the reference counter and decrease it here.
+ *****************************************************************************/
+static void p_psSourceFree(psSource *tmp)
+{
+    psFree(tmp->peak);
+    //    psFree(tmp->pixels);
+    //    psFree(tmp->mask);
+    psFree(tmp->moments);
+    psFree(tmp->models);
+}
+
+/******************************************************************************
+pmSourceAlloc(): Allocate the psSource structure and initialize its members
+to NULL.
+ *****************************************************************************/
+psSource *pmSourceAlloc()
+{
+    psSource *tmp = (psSource *) psAlloc(sizeof(psSource));
+    tmp->peak = NULL;
+    tmp->pixels = NULL;
+    tmp->mask = NULL;
+    tmp->moments = NULL;
+    tmp->models = NULL;
+    p_psMemSetDeallocator(tmp, (psFreeFcn) p_psSourceFree);
+
+    return(tmp);
+}
+
+/******************************************************************************
+pmFindVectorPeaks(vector, threshold): Find all local peaks in the given vector
+above the given threshold.  Returns a vector of type PS_TYPE_U32 containing
+the location (x value) of all peaks.
+ 
+XXX: What types should be supported?  Only F32 is implemented.
+ 
+XXX: We currently step through the input vector twice; once to determine the
+size of the output vector, then to set the values of the output vector.
+Depending upon actual use, this may need to be optimized.
+ *****************************************************************************/
+psVector *pmFindVectorPeaks(const psVector *vector,
+                            psF32 threshold)
+{
+    PS_VECTOR_CHECK_NULL(vector, NULL);
+    PS_VECTOR_CHECK_EMPTY(vector, NULL);
+    PS_VECTOR_CHECK_TYPE(vector, PS_TYPE_F32, NULL);
+    int count = 0;
+    int n = vector->n;
+
+    //
+    // Special case: the input vector has a single element.
+    //
+    if (n == 1) {
+        psVector *tmpVector = NULL;
+        ;
+        if (vector->data.F32[0] > threshold) {
+            tmpVector = psVectorAlloc(1, PS_TYPE_U32);
+            tmpVector->data.U32[0] = 0;
+        } else {
+            tmpVector = psVectorAlloc(0, PS_TYPE_U32);
+        }
+        return(tmpVector);
+    }
+
+    //
+    // Determine if first pixel is a peak
+    //
+    if ((vector->data.F32[0] > vector->data.F32[1]) &&
+            (vector->data.F32[0] > threshold)) {
+        count++;
+    }
+
+    //
+    // Determine if interior pixels are peaks
+    //
+    for (psU32 i = 1; i < n-1 ; i++) {
+        if ((vector->data.F32[i] > vector->data.F32[i-1]) &&
+                (vector->data.F32[i] > vector->data.F32[i+1]) &&
+                (vector->data.F32[i] > threshold)) {
+            count++;
+        }
+    }
+
+    //
+    // Determine if last pixel is a peak
+    //
+    if ((vector->data.F32[n-1] > vector->data.F32[n-2]) &&
+            (vector->data.F32[n-1] > threshold)) {
+        count++;
+    }
+
+    //
+    // We know how many peaks exist, so we now allocate a psVector to store
+    // those peaks.
+    //
+    psVector *tmpVector = psVectorAlloc(count, PS_TYPE_U32);
+    count = 0;
+
+    //
+    // Determine if first pixel is a peak
+    //
+    if ((vector->data.F32[0] > vector->data.F32[1]) &&
+            (vector->data.F32[0] > threshold)) {
+        tmpVector->data.U32[count++] = 0;
+    }
+
+    //
+    // Determine if interior pixels are peaks
+    //
+    for (psU32 i = 1; i < (n-1) ; i++) {
+        if ((vector->data.F32[i] > vector->data.F32[i-1]) &&
+                (vector->data.F32[i] > vector->data.F32[i+1]) &&
+                (vector->data.F32[i] > threshold)) {
+            tmpVector->data.U32[count++] = i;
+        }
+    }
+
+    //
+    // Determine if last pixel is a peak
+    //
+    if ((vector->data.F32[n-1] > vector->data.F32[n-2]) &&
+            (vector->data.F32[n-1] > threshold)) {
+        tmpVector->data.U32[count++] = n-1;
+    }
+
+    return(tmpVector);
+}
+
+/******************************************************************************
+p_psGetRowVectorFromImage(): a private function which simply returns a
+psVector containing the specified row of data from the psImage.
+ 
+XXX: Is there a better way to do this?
+ *****************************************************************************/
+psVector *p_psGetRowVectorFromImage(psImage *image,
+                                    psU32 row)
+{
+    PS_IMAGE_CHECK_NULL(image, NULL);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, NULL);
+
+    psVector *tmpVector = psVectorAlloc(image->numCols, PS_TYPE_F32);
+    for (psU32 col = 0; col < image->numCols ; col++) {
+        tmpVector->data.F32[col] = image->data.F32[row][col];
+    }
+    return(tmpVector);
+}
+
+/******************************************************************************
+MyListAddPeak(): A private function which allocates a psList, if the list
+argument is NULL, otherwise it adds the peak to that list.
+ 
+XXX: Switch row, col args?
+ *****************************************************************************/
+psList *MyListAddPeak(psList *list,
+                      psS32 row,
+                      psS32 col,
+                      psF32 counts,
+                      psPeakType type)
+{
+    psPeak *tmpPeak = pmPeakAlloc(row, col, counts, type);
+
+    if (list == NULL) {
+        list = psListAlloc(tmpPeak);
+    } else {
+        psListAdd(list, PS_LIST_HEAD, tmpPeak);
+    }
+
+    return(list);
+}
+
+/******************************************************************************
+pmFindImagePeaks(image, threshold): Find all local peaks in the given psImage
+above the given threshold.  Returns a psList containing location (x/y value)
+of all peaks.
+ 
+XXX: I'm not convinced the peak type definition in the SDRS is mutually
+exclusive.  Some peaks can have multiple types.  Edges for sure.  Also, a
+digonal line with the same value at each point will have a peak for every
+point on that line.
+ 
+XXX: This does not work if image has either a single row, or a single column.
+ 
+XXX: In the output psList elements, should we use the image row/column offsets?
+     Currently, we do not.
+ *****************************************************************************/
+psList *pmFindImagePeaks(const psImage *image,
+                         psF32 threshold)
+{
+    PS_IMAGE_CHECK_NULL(image, NULL);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, NULL);
+    if ((image->numRows == 1) || (image->numCols == 1)) {
+        psError(PS_ERR_UNKNOWN, true, "Currently, input image must have at least 2 rows and 2 columns.");
+    }
+    psVector *tmpRow = NULL;
+    psU32 col = 0;
+    psU32 row = 0;
+    psList *list = NULL;
+
+    //
+    // Find peaks in row 0 only.
+    //
+    row = 0;
+    tmpRow = p_psGetRowVectorFromImage((psImage *) image, row);
+    psVector *row1 = pmFindVectorPeaks(tmpRow, threshold);
+    for (psU32 i = 0 ; i < row1->n ; i++ ) {
+        col = row1->data.U32[i];
+
+        //
+        // Determine if pixel (0,0) is a peak.
+        //
+        if (col == 0) {
+            if ( (image->data.F32[row][col] >  image->data.F32[row][col+1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row+1][col]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row+1][col+1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+        } else if (col < (image->numCols - 1)) {
+            if ( (image->data.F32[row][col] >= image->data.F32[row][col-1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row][col+1]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row+1][col-1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row+1][col]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row+1][col+1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+
+        } else if (col == (image->numCols - 1)) {
+            if ( (image->data.F32[row][col] >= image->data.F32[row][col-1]) &&
+                    (image->data.F32[row][col] > image->data.F32[row+1][col]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row+1][col-1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+
+        } else {
+            psError(PS_ERR_UNKNOWN, true, "peak specified valid column range.");
+        }
+    }
+    //
+    // Exit if this image has a single row.
+    //
+    if (image->numRows == 1) {
+        return(list);
+    }
+
+    //
+    // Find peaks in interior rows only.
+    //
+    for (row = 1 ; row < (image->numRows - 1) ; row++) {
+        tmpRow = p_psGetRowVectorFromImage((psImage *) image, 0);
+        row1 = pmFindVectorPeaks(tmpRow, threshold);
+
+        // Step through all local peaks in this row.
+        for (psU32 i = 0 ; i < row1->n ; i++ ) {
+            psPeakType myType = PM_PEAK_UNDEF;
+            col = row1->data.U32[i];
+
+            if (col == 0) {
+                // If col==0, then we can not read col-1 pixels
+                if ((image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row-1][col+1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row][col+1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col+1])) {
+                    myType = PM_PEAK_EDGE;
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], myType);
+                }
+            } else if (col < (image->numCols - 1)) {
+                // This is an interior pixel
+                if ((image->data.F32[row][col] >= image->data.F32[row-1][col-1]) &&
+                        (image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row-1][col+1]) &&
+                        (image->data.F32[row][col] > image->data.F32[row][col-1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row][col+1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col-1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col+1])) {
+                    if (image->data.F32[row][col] > threshold) {
+                        if ((image->data.F32[row][col] > image->data.F32[row-1][col-1]) &&
+                                (image->data.F32[row][col] > image->data.F32[row-1][col]) &&
+                                (image->data.F32[row][col] > image->data.F32[row-1][col+1]) &&
+                                (image->data.F32[row][col] > image->data.F32[row][col-1]) &&
+                                (image->data.F32[row][col] > image->data.F32[row][col+1]) &&
+                                (image->data.F32[row][col] > image->data.F32[row+1][col-1]) &&
+                                (image->data.F32[row][col] > image->data.F32[row+1][col]) &&
+                                (image->data.F32[row][col] > image->data.F32[row+1][col+1])) {
+                            myType = PM_PEAK_LONE;
+                        }
+
+                        if ((image->data.F32[row][col] == image->data.F32[row-1][col-1]) ||
+                                (image->data.F32[row][col] == image->data.F32[row-1][col]) ||
+                                (image->data.F32[row][col] == image->data.F32[row-1][col+1]) ||
+                                (image->data.F32[row][col] == image->data.F32[row][col-1]) ||
+                                (image->data.F32[row][col] == image->data.F32[row][col+1]) ||
+                                (image->data.F32[row][col] == image->data.F32[row+1][col-1]) ||
+                                (image->data.F32[row][col] == image->data.F32[row+1][col]) ||
+                                (image->data.F32[row][col] == image->data.F32[row+1][col+1])) {
+                            myType = PM_PEAK_FLAT;
+                        }
+
+                        list = MyListAddPeak(list, row, col, image->data.F32[row][col], myType);
+                    }
+                }
+            } else if (col == (image->numCols - 1)) {
+                // If col==numCols - 1, then we can not read col+1 pixels
+                if ((image->data.F32[row][col] >= image->data.F32[row-1][col-1]) &&
+                        (image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                        (image->data.F32[row][col] > image->data.F32[row][col-1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row][col+1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col-1]) &&
+                        (image->data.F32[row][col] >= image->data.F32[row+1][col])) {
+                    myType = PM_PEAK_EDGE;
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], myType);
+                }
+            } else {
+                psError(PS_ERR_UNKNOWN, true, "peak specified valid column range.");
+            }
+
+        }
+    }
+
+    //
+    // Find peaks in the last row only.
+    //
+    row = image->numRows - 1;
+    tmpRow = p_psGetRowVectorFromImage((psImage *) image, row);
+    row1 = pmFindVectorPeaks(tmpRow, threshold);
+    for (psU32 i = 0 ; i < row1->n ; i++ ) {
+        col = row1->data.U32[i];
+        if (col == 0) {
+            if ( (image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row-1][col+1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row][col+1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+        } else if (col < (image->numCols - 1)) {
+            if ( (image->data.F32[row][col] >= image->data.F32[row-1][col-1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row-1][col+1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row][col-1]) &&
+                    (image->data.F32[row][col] >= image->data.F32[row][col+1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+
+        } else if (col == (image->numCols - 1)) {
+            if ( (image->data.F32[row][col] >= image->data.F32[row-1][col-1]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row-1][col]) &&
+                    (image->data.F32[row][col] >  image->data.F32[row][col-1])) {
+                if (image->data.F32[row][col] > threshold) {
+                    list = MyListAddPeak(list, row, col, image->data.F32[row][col], PM_PEAK_EDGE);
+                }
+            }
+        } else {
+            psError(PS_ERR_UNKNOWN, true, "peak specified valid colum range.");
+        }
+    }
+
+    return(list);
+}
+
+// XXX: Macro this.
+bool IsItInThisRegion(const psRegion *valid,
+                      psS32 x,
+                      psS32 y)
+{
+
+    if ((x >= valid->x0) &&
+            (x <= valid->x1) &&
+            (y >= valid->y0) &&
+            (y <= valid->y1)) {
+        return(true);
+    }
+
+    return(false);
+}
+
+
+/******************************************************************************
+psCullPeaks(peaks, maxValue, valid): eliminate peaks from the psList that have
+a peak value above the given maximum, or fall outside the valid region.
+ 
+XXX: Should the sky value be used when comparing the maximum?
+ 
+XXX: warning message if valid is NULL?
+ *****************************************************************************/
+psList *pmCullPeaks(psList *peaks,
+                    psF32 maxValue,
+                    const psRegion *valid)
+{
+    PS_PTR_CHECK_NULL(peaks, NULL);
+    //    PS_PTR_CHECK_NULL(valid, NULL);
+
+    psListElem *tmpListElem = (psListElem *) peaks->head;
+    psS32 indexNum = 0;
+
+    //    printf("pmCullPeaks(): list size is %d\n", peaks->size);
+    while (tmpListElem != NULL) {
+        psPeak *tmpPeak = (psPeak *) tmpListElem->data;
+        if ((tmpPeak->counts > maxValue) ||
+                ((valid != NULL) &&
+                 (true == IsItInThisRegion(valid, tmpPeak->x, tmpPeak->y)))) {
+            psListRemoveData(peaks, (psPtr) tmpPeak);
+        }
+
+        indexNum++;
+        tmpListElem = tmpListElem->next;
+    }
+
+    return(peaks);
+}
+
+/******************************************************************************
+psSource *pmSourceLocalSky(image, peak, innerRadius, outerRadius): this
+routine creates a new psSource data structure and sets the following members:
+    ->psPeak
+    ->psMoments->sky
+ 
+The sky value is set from the pixels in the square annulus surrounding the
+peak pixel.
+ 
+We simply create a subSet image and mask the inner pixels, then call
+psImageStats on that subImage+mask.
+ 
+XXX: The subImage has width of 1+2*outerRadius.  Verify with IfA.
+ 
+XXX: Use static data structures for:
+     subImage
+     subImageMask
+     myStats
+ 
+XXX: ensure that the inner and out radius fit in the actual image.  Should
+     we generate an error, or warning?  Currently an error.
+ 
+XXX: Sync with IfA on whether the peak x/y coords are data structure coords,
+     or they use the image row/column offsets.
+ 
+XXX: Should we simply set psSource->peak = peak?  If so, should we increase
+the reference counter?  Or, should we copy the data structure?
+ 
+XXX: Currently the subimage always has an even number of rows/columns.  Is
+     this correct?  Since there is a center pixel, maybe it should have an
+     odd number of rows/columns.
+ 
+XXX: Use psTrace() for the print statements.
+ 
+XXX: Don't use separate structs for the subimage and mask.  Use the source->
+     members.
+ *****************************************************************************/
+psSource *pmSourceLocalSky(const psImage *image,
+                           const psPeak *peak,
+                           psStatsOptions statsOptions,
+                           psF32 innerRadius,
+                           psF32 outerRadius)
+{
+    PS_IMAGE_CHECK_NULL(image, NULL);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(peak, NULL);
+    PS_FLOAT_COMPARE(0.0, innerRadius, NULL);
+    PS_FLOAT_COMPARE(innerRadius, outerRadius, NULL);
+    psS32 innerRadiusS32 = (psS32) innerRadius;
+    psS32 outerRadiusS32 = (psS32) outerRadius;
+
+    //
+    // We define variables for code readability.
+    //
+    // XXX: Since the peak->xy coords are in image, not subImage coords,
+    // these variables should be renamed for clarity (imageCenterRow, etc).
+    //
+    psS32 SubImageCenterRow = peak->y;
+    psS32 SubImageCenterCol = peak->x;
+    psS32 SubImageStartRow = SubImageCenterRow - outerRadiusS32;
+    psS32 SubImageEndRow = SubImageCenterRow + outerRadiusS32;
+    psS32 SubImageStartCol = SubImageCenterCol - outerRadiusS32;
+    psS32 SubImageEndCol = SubImageCenterCol + outerRadiusS32;
+    // AnulusWidth == number of pixels width in the annulus.  We add one since
+    // the pixels at the inner AND outher radius are included.
+    psS32 AnulusWidth = 1 + (outerRadiusS32 - innerRadiusS32);
+    // Example: assume an outer/inner radius of 20/10.  Then the subimage
+    // should have width/length of 40.  An 18-by-18 interior region will
+    // be masked.
+    //    printf("pmSourceLocalSky(): innerRadiusS32 is %d\n", innerRadiusS32);
+    //    printf("pmSourceLocalSky(): outerRadiusS32 is %d\n", outerRadiusS32);
+    //    printf("pmSourceLocalSky(): AnulusWidth is %d\n", AnulusWidth);
+
+    if (SubImageStartRow < 0) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image startRow is outside image boundaries (%d).\n",
+                SubImageStartRow);
+        return(NULL);
+    }
+    if (SubImageEndRow >= image->numRows) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image endRow is outside image boundaries (%d).\n",
+                SubImageEndRow);
+        return(NULL);
+    }
+    if (SubImageStartCol < 0) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image startCol is outside image boundaries (%d).\n",
+                SubImageStartCol);
+        return(NULL);
+    }
+    if (SubImageEndCol >= image->numCols) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image endCol is outside image boundaries (%d).\n",
+                SubImageEndCol);
+        return(NULL);
+    }
+
+    //
+    // Grab a subimage of the original image of size (2 * outerRadius).
+    //
+    psImage *subImage = psImageSubset((psImage *) image,
+                                      SubImageStartCol,
+                                      SubImageStartRow,
+                                      SubImageEndCol,
+                                      SubImageEndRow);
+    //    printf("pmSourceLocalSky: subimage width/length is (%d, %d)\n", subImage->numCols, subImage->numRows);
+    psImage *subImageMask = psImageAlloc(subImage->numCols,
+                                         subImage->numRows,
+                                         PS_TYPE_U8);
+
+    //
+    // Loop through the subimage mask, initialize mask to 0.
+    //
+    for (psS32 row = 0 ; row < subImageMask->numRows; row++) {
+        for (psS32 col = 0 ; col < subImageMask->numCols; col++) {
+            subImageMask->data.U8[row][col] = 0;
+        }
+    }
+
+    //
+    // Loop through the subimage, mask off pixels in the inner square.
+    //
+    for (psS32 row = AnulusWidth; row <= (subImageMask->numRows - AnulusWidth) - 1; row++) {
+        for (psS32 col = AnulusWidth; col <= (subImageMask->numCols - AnulusWidth) - 1; col++) {
+            subImageMask->data.U8[row][col] = 1;
+        }
+    }
+
+
+    //    for (psS32 row = 0 ; row < subImage->numRows; row++) {
+    //        for (psS32 col = 0 ; col < subImage->numCols; col++) {
+    //            printf("(%d) ", subImageMask->data.U8[row][col]);
+    //        }
+    //        printf("\n");
+    //    }
+
+    //
+    // Allocate the myStats structure, then call psImageStats(), which will
+    // calculate the specified statistic.
+    //
+    psStats *myStats = psStatsAlloc(statsOptions);
+    myStats = psImageStats(myStats, subImage, subImageMask, 1);
+
+    //
+    // Create the output mySource, and set appropriate members.
+    //
+    psSource *mySource = pmSourceAlloc();
+    mySource->peak = (psPeak *) peak;
+    mySource->moments = pmMomentsAlloc();
+    psF64 tmpF64;
+    p_psGetStatValue(myStats, &tmpF64);
+    mySource->moments->Sky = (psF32) tmpF64;
+    mySource->pixels = subImage;
+    mySource->mask = subImageMask;
+
+    //
+    // Free things.  XXX: This should be static memory.
+    //
+    psFree(myStats);
+
+    return(mySource);
+}
+
+/******************************************************************************
+bool CheckRadius(*peak, radius, x, y): private function which simply
+determines if the (x, y) point is within the radius of the specified peak.
+ 
+XXX: macro this for performance.
+  *****************************************************************************/
+bool CheckRadius(psPeak *peak,
+                 psF32 radius,
+                 psS32 x,
+                 psS32 y)
+{
+    if (PS_SQR(radius) >= (psF32) (PS_SQR(x - peak->x) + PS_SQR(y - peak->y))) {
+        return(true);
+    }
+
+    return(false);
+}
+
+/******************************************************************************
+bool CheckRadius2(): private function which simply determines if the (x, y)
+point is within the radius of the specified peak.
+ 
+XXX: macro this for performance.
+  *****************************************************************************/
+bool CheckRadius2(psF32 xCenter,
+                  psF32 yCenter,
+                  psF32 radius,
+                  psF32 x,
+                  psF32 y)
+{
+    if ((PS_SQR(x - xCenter) + PS_SQR(y - yCenter)) < PS_SQR(radius)) {
+        return(true);
+    }
+
+    return(false);
+}
+
+/******************************************************************************
+pmSourceMoments(source, radius): this function takes a subImage defined in the
+psSource data structure, along with the peak location, and determines the
+various moments associated with that peak.
+ 
+Requires the following to have been created:
+    psSource
+    psSource->peak
+    psSource->pixels
+ 
+XXX: The peak calculations are done in image coords, not subImage coords.
+ 
+XXX: mask values?
+ *****************************************************************************/
+psSource *pmSourceMoments(psSource *source,
+                          psF32 radius)
+{
+    PS_PTR_CHECK_NULL(source, NULL);
+    PS_PTR_CHECK_NULL(source->peak, NULL);
+    PS_PTR_CHECK_NULL(source->pixels, NULL);
+    PS_FLOAT_COMPARE(0.0, radius, NULL);
+
+    //
+    // XXX: Verify the setting for sky if source->moments == NULL.
+    //
+    psF32 sky = 0.0;
+    if (source->moments == NULL) {
+        source->moments = pmMomentsAlloc();
+    } else {
+        sky = source->moments->Sky;
+    }
+
+    //
+    // Sum = SUM (z - sky)
+    // X1  = SUM (x - xc)*(z - sky)
+    // X2  = SUM (x - xc)^2 * (z - sky)
+    // XY  = SUM (x - xc)*(y - yc)*(z - sky)
+    //
+    psF32 Sum = 0.0;
+    psF32 peakPixel = -PS_MAX_F32;
+    psS32 numPixels = 0;
+    psF32 X1 = 0.0;
+    psF32 Y1 = 0.0;
+    psF32 X2 = 0.0;
+    psF32 Y2 = 0.0;
+    psF32 XY = 0.0;
+    //
+    // We loop through all pixels in this subimage (source->pixels), and for each
+    // pixel that is not masked, AND within the radius of the peak pixel, we
+    // proceed with the moments calculation.
+    //
+    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
+        for (psS32 col = 0; col < source->pixels->numCols ; col++) {
+            if ((source->mask != NULL) && (source->mask->data.U8[row][col] != 0)) {
+                psS32 imgColCoord = col + source->pixels->col0;
+                psS32 imgRowCoord = row + source->pixels->row0;
+                if (CheckRadius(source->peak,
+                                radius,
+                                imgColCoord,
+                                imgRowCoord)) {
+                    psF32 xDiff = (psF32) (imgColCoord - source->peak->x);
+                    psF32 yDiff = (psF32) (imgRowCoord - source->peak->y);
+                    psF32 pDiff = source->pixels->data.F32[row][col] - sky;
+
+                    Sum+= pDiff;
+                    X1+= xDiff * pDiff;
+                    Y1+= yDiff * pDiff;
+                    X2+= PS_SQR(xDiff) * pDiff;
+                    Y2+= PS_SQR(yDiff) * pDiff;
+                    XY+= xDiff * yDiff * pDiff;
+
+                    if (source->pixels->data.F32[row][col] > peakPixel) {
+                        peakPixel = source->pixels->data.F32[row][col];
+                    }
+                    numPixels++;
+                }
+            }
+        }
+    }
+
+    //
+    // first moment X  = X1/Sum + xc
+    // second moment X = sqrt (X2/Sum - (X1/Sum)^2)
+    // Sxy             = XY / Sum
+    //
+    source->moments->x = X1/Sum + ((psF32) source->peak->x);
+    source->moments->y = Y1/Sum + ((psF32) source->peak->y);
+    source->moments->Sx = sqrt(X2/Sum - PS_SQR(X1/Sum));
+    source->moments->Sy = sqrt(Y2/Sum - PS_SQR(Y1/Sum));
+    source->moments->Sxy = XY/Sum;
+    source->moments->Peak = peakPixel;
+    source->moments->nPixels = numPixels;
+
+    return(source);
+}
+
+/******************************************************************************
+pmSourceRoughClass(source, metadata): make a guess at the source
+classification.
+ 
+XXX: This is not useable code, as of the release date.  There remains a fair
+bit of coding to be completed.
+ 
+XXX: The sigX and sigY stuff in the SDRS is unclear.
+ 
+XXX: How can this function ever return FALSE?
+ *****************************************************************************/
+#define SATURATE 0.0
+#define FAINT_SN_LIM 0.0
+#define PSF_SN_LIM 0.0
+#define SATURATE 0.0
+#define SATURATE 0.0
+
+bool pmSourceRoughClass(psArray *source,
+                        psMetadata *metadata)
+{
+    PS_PTR_CHECK_NULL(source, false);
+    PS_PTR_CHECK_NULL(metadata, false);
+    psBool rc = true;
+
+    for (psS32 i = 0 ; i < source->n ; i++) {
+        psSource *tmpSrc = (psSource *) source->data[i];
+        PS_PTR_CHECK_NULL(tmpSrc->moments, false);
+        tmpSrc->peak->class = 0;
+
+        psF32 sigX = 0.0;
+        psF32 sigY = 0.0;
+        // XXX: gleen these from the metadata: keywords GAIN and READ_NOISE.
+        psF32 clumpX = 0.0;
+        psF32 clumpDX = 0.0;
+        psF32 clumpY = 0.0;
+        psF32 clumpDY = 0.0;
+
+        if (tmpSrc->moments->Peak > SATURATE) {
+            tmpSrc->peak->class|= PS_SOURCE_SATURATED;
+        } else {
+            // XXX: gleen these from the metadata: keywords GAIN and READ_NOISE.
+            psF32 gain = 0.0;
+            psF32 readNoise = 0.0;
+            psF32 S = tmpSrc->moments->Sum;
+            psF32 A = PS_PI * tmpSrc->moments->Sx * tmpSrc->moments->Sy;
+            psF32 B = tmpSrc->moments->Sky;
+            psF32 SN = (PS_SQRT_F32(gain) * S) /
+                       PS_SQRT_F32(S + (A * B) + ((A * readNoise * readNoise) / PS_SQRT_F32(gain)));
+            if (SN < FAINT_SN_LIM) {
+                tmpSrc->peak->class|= PS_SOURCE_FAINTSTAR;
+            }
+            if (SN < PSF_SN_LIM) {
+                tmpSrc->peak->class|= PS_SOURCE_FAINTSTAR;
+            }
+            // XXX: The SDRS is not real clear on how to calculate sigX, sigY.
+            if ((fabs(sigX - clumpX) < clumpDX) &&
+                    (fabs(sigY - clumpY) < clumpDY)) {
+                tmpSrc->peak->class|= PS_SOURCE_PSFSTAR;
+            }
+
+            if ((sigX < (clumpX - clumpDX)) &&
+                    (sigY < (clumpY - clumpDY)))
+                tmpSrc->peak->class|= PS_SOURCE_DEFECT;
+        }
+
+        if ((sigX > (clumpX + clumpDX)) &&
+                (sigY > (clumpY + clumpDY))) {
+            tmpSrc->peak->class|= PS_SOURCE_GALAXY;
+        }
+
+        if (tmpSrc->peak->class == 0) {
+            tmpSrc->peak->class|= PS_SOURCE_OTHER;
+        }
+    }
+
+    return(rc);
+}
+
+
+
+/******************************************************************************
+pmSourceSetPixelCircle(source, image, radius)
+ 
+XXX: Why boolean output?
+ 
+XXX: Why are we checking source->moments for NULL?  Should the circle be
+     centered on the centroid or the peak?
+ 
+XXX: The circle will have a diameter of (1+radius).  This is different from
+     the pmSourceSetLocal() function.
+ *****************************************************************************/
+bool pmSourceSetPixelCircle(psSource *source,
+                            const psImage *image,
+                            psF32 radius)
+{
+    PS_IMAGE_CHECK_NULL(image, false);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, false);
+    PS_PTR_CHECK_NULL(source, false);
+    //    PS_PTR_CHECK_NULL(source->moments, false);
+    PS_PTR_CHECK_NULL(source->peak, false);
+    PS_FLOAT_COMPARE(0.0, radius, false);
+
+    //
+    // We define variables for code readability.
+    //
+    // XXX: Since the peak->xy coords are in image, not subImage coords,
+    // these variables should be renamed for clarity (imageCenterRow, etc).
+    //
+    psS32 radiusS32 = (psS32) radius;
+    psS32 SubImageCenterRow = source->peak->y;
+    psS32 SubImageCenterCol = source->peak->x;
+    psS32 SubImageStartRow = SubImageCenterRow - radiusS32;
+    psS32 SubImageEndRow = SubImageCenterRow + radiusS32;
+    psS32 SubImageStartCol = SubImageCenterCol - radiusS32;
+    psS32 SubImageEndCol = SubImageCenterCol + radiusS32;
+
+    if (SubImageStartRow < 0) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image startRow is outside image boundaries (%d).\n",
+                SubImageStartRow);
+        return(false);
+    }
+    if (SubImageEndRow+1 >= image->numRows) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image endRow is outside image boundaries (%d).\n",
+                SubImageEndRow);
+        return(false);
+    }
+    if (SubImageStartCol < 0) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image startCol is outside image boundaries (%d).\n",
+                SubImageStartCol);
+        return(false);
+    }
+    if (SubImageEndCol+1 >= image->numCols) {
+        psError(PS_ERR_UNKNOWN, true, "Sub image endCol is outside image boundaries (%d).\n",
+                SubImageEndCol);
+        return(false);
+    }
+
+    // XXX: Must recycle image.
+    if (source->pixels != NULL) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSourceSetPixelCircle(): image->pixels not NULL.  Freeing and reallocating.\n");
+        psFree(source->pixels);
+    }
+    source->pixels = psImageSubset((psImage *) image,
+                                   SubImageStartCol,
+                                   SubImageStartRow,
+                                   SubImageEndCol+1,
+                                   SubImageEndRow+1);
+
+    // XXX: Must recycle image.
+    if (source->mask != NULL) {
+        psFree(source->mask);
+    }
+    source->mask = psImageAlloc(1 + 2 * radiusS32,
+                                1 + 2 * radiusS32,
+                                PS_TYPE_F32);
+
+    //
+    // Loop through the subimage mask, initialize mask to 0 or 1.
+    //
+    for (psS32 row = 0 ; row < source->mask->numRows; row++) {
+        for (psS32 col = 0 ; col < source->mask->numCols; col++) {
+
+            if (CheckRadius2((psF32) radiusS32,
+                             (psF32) radiusS32,
+                             radius,
+                             (psF32) col,
+                             (psF32) row)) {
+                source->mask->data.U8[row][col] = 1;
+            } else {
+                source->mask->data.U8[row][col] = 0;
+            }
+        }
+    }
+    return(true);
+}
+
+
+/******************************************************************************
+pmSourceModelGuess(source, image, model): This function allocates a new
+psModel structure and stores it in the psSource data structure specified in
+the argument list.  The model type is specified in the argument list.  The
+params array in that psModel structure are allocated, and then set to the
+appropriate values.  This function returns true if everything was successful.
+ 
+XXX: Many of the initial parameters are set to 0.0 since I don't know what
+the appropiate initial guesses are.
+ 
+XXX: The image argument is redundant.
+ 
+XXX: Many parameters are based on the src->moments structure, which is in
+image, not subImage coords.  Therefore, the calls to the model evaluation
+functions will be in image, not subImage coords.  Remember this.
+ *****************************************************************************/
+bool pmSourceModelGuess(psSource *source,
+                        const psImage *image,
+                        psModelType model)
+{
+    PS_PTR_CHECK_NULL(source, false);
+    PS_PTR_CHECK_NULL(source->moments, false);
+    PS_PTR_CHECK_NULL(source->peak, false);
+    PS_IMAGE_CHECK_NULL(image, false);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, false);
+    if (source->models != NULL) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: source->models was non-NULL; calling psFree(source->models).\n");
+        psFree(source->models);
+    }
+    source->models = pmModelAlloc(model);
+
+    switch (model) {
+    case PS_MODEL_GAUSS:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        source->models->params[4] = sqrt(2.0) / source->moments->Sx;
+        source->models->params[5] = sqrt(2.0) / source->moments->Sy;
+        source->models->params[6] = source->moments->Sxy;
+        return(true);
+
+    case PS_MODEL_PGAUSS:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        source->models->params[4] = sqrt(2.0) / source->moments->Sx;
+        source->models->params[5] = sqrt(2.0) / source->moments->Sy;
+        source->models->params[6] = source->moments->Sxy;
+        return(true);
+
+    case PS_MODEL_TWIST_GAUSS:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        // XXX: What are these?
+        // source->models->params[4] = SxInner;
+        // source->models->params[5] = SyInner;
+        // source->models->params[6] = SxyInner;
+        // source->models->params[7] = SxOuter;
+        // source->models->params[8] = SyOuter;
+        // source->models->params[9] = SxyOuter;
+        // source->models->params[10] = N;
+        return(true);
+
+    case PS_MODEL_WAUSS:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        source->models->params[4] = sqrt(2.0) / source->moments->Sx;
+        source->models->params[5] = sqrt(2.0) / source->moments->Sy;
+        source->models->params[6] = source->moments->Sxy;
+        // XXX: What are these?
+        // source->models->params[7] = B2;
+        // source->models->params[8] = B3;
+        return(true);
+
+    case PS_MODEL_SERSIC:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        source->models->params[4] = sqrt(2.0) / source->moments->Sx;
+        source->models->params[5] = sqrt(2.0) / source->moments->Sy;
+        source->models->params[6] = source->moments->Sxy;
+        // XXX: What are these?
+        //source->models->params[7] = Nexp;
+        return(true);
+
+    case PS_MODEL_SERSIC_CORE:
+        source->models->params[0] = source->moments->Sky;
+        source->models->params[1] = source->peak->counts - source->moments->Sky;
+        source->models->params[2] = source->moments->x;
+        source->models->params[3] = source->moments->y;
+        // XXX: What are these?
+        //source->models->params[4] SxInner;
+        //source->models->params[5] SyInner;
+        //source->models->params[6] SxyInner;
+        //source->models->params[7] Zd;
+        //source->models->params[8] SxOuter;
+        //source->models->params[9] SyOuter;
+        //source->models->params[10] = SxyOuter;
+        //source->models->params[11] = Nexp;
+        return(true);
+
+    default:
+        psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
+        return(false);
+    }
+}
+
+/******************************************************************************
+evalModel(source, level, row): a private function which evaluates the
+source->model function at the specified coords.  The coords are subImage, not
+image coords.
+ 
+NOTE: The coords are in subImage source->pixel coords, not image coords.
+ 
+XXX: reverse order of row,col args?
+ 
+XXX: rename all coords in this file such that their name defines whether
+the coords is in subImage or image space.
+ 
+XXX: This should probably be a public psModules function.
+ 
+XXX: Use static vectors for x.
+ 
+XXX: Figure out if it's (row, col) or (col, row) for the model functions.
+ 
+XXX: For a while, the first psVectorAlloc() was generating a seg fault during
+testing.  Try to reproduce that and debug.
+ *****************************************************************************/
+psF32 evalModel(psSource *src,
+                psU32 row,
+                psU32 col)
+{
+    PS_PTR_CHECK_NULL(src, false);
+    PS_PTR_CHECK_NULL(src->models, false);
+    PS_PTR_CHECK_NULL(src->models->params, false);
+
+    // XXX: The following step will not be necessary if the models->params
+    // member is a psVector.  Suggest to IfA.
+    psVector *params = psVectorAlloc(7, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < src->models->Nparams ; i++) {
+        params->data.F32[i] = src->models->params[i];
+    }
+
+    //
+    // Allocate the x coordinate structure and convert row/col to image space.
+    //
+    psVector *x = psVectorAlloc(2, PS_TYPE_F32);
+    x->data.F32[0] = (psF32) (col + src->pixels->col0);
+    x->data.F32[1] = (psF32) (row + src->pixels->row0);
+    psF32 tmpF;
+
+    switch (src->models->type) {
+    case PS_MODEL_GAUSS:
+        tmpF = pmMinLM_Gauss2D(NULL, params, x);
+        break;
+    case PS_MODEL_PGAUSS:
+        tmpF = pmMinLM_PsuedoGauss2D(NULL, params, x);
+        break;
+    case PS_MODEL_TWIST_GAUSS:
+        tmpF = pmMinLM_TwistGauss2D(NULL, params, x);
+        break;
+    case PS_MODEL_WAUSS:
+        tmpF = pmMinLM_Wauss2D(NULL, params, x);
+        break;
+    case PS_MODEL_SERSIC:
+        tmpF = pmMinLM_Sersic(NULL, params, x);
+        break;
+    case PS_MODEL_SERSIC_CORE:
+        tmpF = pmMinLM_SersicCore(NULL, params, x);
+        break;
+    default:
+        psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
+        return(NAN);
+    }
+
+    psFree(params);
+    psFree(x);
+    return(tmpF);
+}
+
+/******************************************************************************
+findValue(source, level, row, col, dir): a private function which determines
+the column coordinate of the model function which has the value "level".  If
+dir equals 0, then you loop leftwards from the peak pixel, otherwise,
+rightwards.
+ 
+XXX: reverse order of row,col args?
+ 
+XXX: Input row/col are in image coords.
+ 
+XXX: The result is returned in image coords.
+ *****************************************************************************/
+psF32 findValue(psSource *source,
+                psF32 level,
+                psU32 row,
+                psU32 col,
+                psU32 dir)
+{
+    //
+    // Convert coords to subImage space.
+    //
+    psU32 subRow = row - source->pixels->row0;
+    psU32 subCol = col - source->pixels->col0;
+
+    // Ensure that the starting column is allowable.
+    if (!((0 <= subCol) && (subCol < source->pixels->numCols))) {
+        psError(PS_ERR_UNKNOWN, true, "Starting column outside subImage range");
+        return(NAN);
+    }
+    if (!((0 <= subRow) && (subRow < source->pixels->numRows))) {
+        psError(PS_ERR_UNKNOWN, true, "Starting row outside subImage range");
+        return(NAN);
+    }
+
+    psF32 oldValue = evalModel(source, subRow, subCol);
+    if (oldValue == level) {
+        return(((psF32) (subCol + source->pixels->col0)));
+    }
+
+    //
+    // We define variables incr and lastColumn so that we can use the same loop
+    // whether we are stepping leftwards, or rightwards.
+    //
+    psS32 incr;
+    psS32 lastColumn;
+    if (dir == 0) {
+        incr = -1;
+        lastColumn = -1;
+    } else {
+        incr = 1;
+        lastColumn = source->pixels->numCols;
+    }
+    subCol+=incr;
+
+    while (subCol != lastColumn) {
+        psF32 newValue = evalModel(source, subRow, subCol);
+        if (oldValue == level) {
+            return((psF32) (subCol + source->pixels->col0));
+        }
+
+        if ((newValue <= level) && (level <= oldValue)) {
+            // This is simple linear interpolation.
+            return( ((psF32) (subCol + source->pixels->col0)) + ((psF32) incr) * ((level - newValue) / (oldValue - newValue)) );
+        }
+
+        if ((oldValue <= level) && (level <= newValue)) {
+            // This is simple linear interpolation.
+            return( ((psF32) (subCol + source->pixels->col0)) + ((psF32) incr) * ((level - oldValue) / (newValue - oldValue)) );
+        }
+
+        subCol+=incr;
+    }
+
+    return(NAN);
+}
+
+/******************************************************************************
+pmSourceContour(src, img, level, mode): For an input subImage, and model, this
+routine returns a psArray of coordinates that evaluate to the specified level.
+ 
+XXX: Probably should remove the "image" argument. 
+XXX: What type should the output coordinate vectors consist of?  col,row?
+XXX: Why a pmArray output?
+XXX: doex x,y correspond with col,row or row/col?
+XXX: What is momde?
+XXX: The top, bottom of the contour is not correctly determined.
+ *****************************************************************************/
+psArray *pmSourceContour(psSource *source,
+                         const psImage *image,
+                         psF32 level,
+                         pmContourType mode)
+{
+    PS_PTR_CHECK_NULL(source, false);
+    PS_PTR_CHECK_NULL(image, false);
+    PS_PTR_CHECK_NULL(source->moments, false);
+    PS_PTR_CHECK_NULL(source->peak, false);
+    PS_PTR_CHECK_NULL(source->pixels, false);
+    PS_PTR_CHECK_NULL(source->models, false);
+
+    //
+    // Allocate data for x/y pairs.
+    //
+    psVector *xVec = psVectorAlloc(2 * source->pixels->numRows, PS_TYPE_F32);
+    psVector *yVec = psVectorAlloc(2 * source->pixels->numRows, PS_TYPE_F32);
+
+    //
+    // Start at the row with peak pixel, then decrement.
+    //
+    psS32 col = source->peak->x;
+    for (psS32 row = source->peak->y; row>= 0 ; row--) {
+        // XXX: yVec contain no real information.  Do we really need it?
+        yVec->data.F32[row] = (psF32) (source->pixels->row0 + row);
+        yVec->data.F32[row+yVec->n] = (psF32) (source->pixels->row0 + row);
+
+        // Starting at peak pixel, search leftwards for the column intercept.
+        psF32 leftIntercept = findValue(source, level, row, col, 0);
+        if (isnan(leftIntercept)) {
+            psError(PS_ERR_UNKNOWN, true, "Could not find contour edge (NAN)");
+            psFree(xVec);
+            psFree(yVec);
+            return(NULL);
+        }
+        xVec->data.F32[row] = ((psF32) source->pixels->col0) + leftIntercept;
+
+        // Starting at peak pixel, search rightwards for the column intercept.
+
+        psF32 rightIntercept = findValue(source, level, row, col, 1);
+        if (isnan(rightIntercept)) {
+            psError(PS_ERR_UNKNOWN, true, "Could not find contour edge (NAN)");
+            psFree(xVec);
+            psFree(yVec);
+            return(NULL);
+        }
+        //printf("HERE the intercepts are (%.2f, %.2f)\n", leftIntercept, rightIntercept);
+        xVec->data.F32[row+xVec->n] = ((psF32) source->pixels->col0) + rightIntercept;
+
+        // Set starting column for next row
+        col = (psS32) ((leftIntercept + rightIntercept) / 2.0);
+    }
+    //
+    // Start at the row (+1) with peak pixel, then increment.
+    //
+    col = source->peak->x;
+    for (psS32 row = 1 + source->peak->y; row < source->pixels->numRows ; row++) {
+        // XXX: yVec contain no real information.  Do we really need it?
+        yVec->data.F32[row] = (psF32) (source->pixels->row0 + row);
+        yVec->data.F32[row+yVec->n] = (psF32) (source->pixels->row0 + row);
+
+        // Starting at peak pixel, search leftwards for the column intercept.
+        psF32 leftIntercept = findValue(source, level, row, col, 0);
+        if (isnan(leftIntercept)) {
+            psError(PS_ERR_UNKNOWN, true, "Could not find contour edge (NAN)");
+            psFree(xVec);
+            psFree(yVec);
+            return(NULL);
+        }
+        xVec->data.F32[row] = ((psF32) source->pixels->col0) + leftIntercept;
+
+        // Starting at peak pixel, search rightwards for the column intercept.
+        psF32 rightIntercept = findValue(source, level, row, col, 1);
+        if (isnan(rightIntercept)) {
+            psError(PS_ERR_UNKNOWN, true, "Could not find contour edge (NAN)");
+            psFree(xVec);
+            psFree(yVec);
+            return(NULL);
+        }
+        xVec->data.F32[row+xVec->n] = ((psF32) source->pixels->col0) + rightIntercept;
+
+        // Set starting column for next row
+        col = (psS32) ((leftIntercept + rightIntercept) / 2.0);
+    }
+
+    //
+    // Allocate an array for result, store coord vectors there.
+    //
+    psArray *tmpArray = psArrayAlloc(2);
+    tmpArray->data[0] = (psPtr *) yVec;
+    tmpArray->data[1] = (psPtr *) xVec;
+    return(tmpArray);
+}
+
+psVector *p_pmMinLM_Gauss2D_Vec(psImage *deriv, psVector *params, psArray *x);
+psVector *p_pmMinLM_PsuedoGauss2D_Vec(psImage *deriv, psVector *params, psArray *x);
+psVector *p_pmMinLM_Wauss2D_Vec(psImage *deriv, psVector *params, psArray *x);
+psVector *p_pmMinLM_TwistGauss2D_Vec(psImage *deriv, psVector *params, psArray *x);
+psVector *p_pmMinLM_Sersic_Vec(psImage *deriv, psVector *params, psArray *x);
+psVector *p_pmMinLM_SersicCore_Vec(psImage *deriv, psVector *params, psArray *x);
+
+//XXX: What should these values be?
+#define PM_SOURCE_FIT_MODEL_NUM_ITERATIONS 100
+#define PM_SOURCE_FIT_MODEL_TOLERANCE 1.0
+/******************************************************************************
+pmSourceFitModel(source, image): must create the appropiate arguments to the
+LM minimization routines for the various p_pmMinLM_XXXXXX_Vec() functions.
+ 
+XXX: should there be a mask value?
+XXX: Probably should remove the "image" argument. 
+ *****************************************************************************/
+bool pmSourceFitModel(psSource *source,
+                      const psImage *image)
+{
+    PS_PTR_CHECK_NULL(source, false);
+    PS_PTR_CHECK_NULL(source->moments, false);
+    PS_PTR_CHECK_NULL(source->peak, false);
+    PS_PTR_CHECK_NULL(source->pixels, false);
+    PS_PTR_CHECK_NULL(source->models, false);
+    PS_IMAGE_CHECK_NULL(image, false);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, false);
+    psBool rc;
+    psS32 count = 0;
+    for (psS32 i = 0 ; i < source->pixels->numRows ; i++) {
+        for (psS32 j = 0 ; j < source->pixels->numCols ; j++) {
+            if (source->mask->data.U8[i][j] == 0) {
+                count++;
+            }
+        }
+    }
+    psArray *x = psArrayAlloc(count);
+    psVector *y = psVectorAlloc(count, PS_TYPE_F32);
+    psS32 tmpCnt = 0;
+    for (psS32 i = 0 ; i < source->pixels->numRows ; i++) {
+        for (psS32 j = 0 ; j < source->pixels->numCols ; j++) {
+            if (source->mask->data.U8[i][j] == 0) {
+                psVector *coord = psVectorAlloc(2, PS_TYPE_F32);
+                // XXX: Convert i/j to image space:
+                coord->data.F32[0] = (psF32) (i + source->pixels->row0);
+                coord->data.F32[1] = (psF32) (j + source->pixels->col0);
+                x->data[tmpCnt] = (psPtr *) coord;
+                y->data.F32[tmpCnt] = source->pixels->data.F32[i][j];
+                tmpCnt++;
+            }
+        }
+    }
+
+    psMinimization *myMin = psMinimizationAlloc(PM_SOURCE_FIT_MODEL_NUM_ITERATIONS,
+                            PM_SOURCE_FIT_MODEL_TOLERANCE);
+
+    psVector *params = psVectorAlloc(source->models->Nparams, PS_TYPE_F32);
+
+    switch (source->models->type) {
+    case PS_MODEL_GAUSS:
+
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_Gauss2D_Vec);
+        break;
+    case PS_MODEL_PGAUSS:
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_PsuedoGauss2D_Vec);
+        break;
+    case PS_MODEL_TWIST_GAUSS:
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_Wauss2D_Vec);
+        break;
+    case PS_MODEL_WAUSS:
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_TwistGauss2D_Vec);
+        break;
+    case PS_MODEL_SERSIC:
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_Sersic_Vec);
+        break;
+    case PS_MODEL_SERSIC_CORE:
+        rc = psMinimizeLMChi2(myMin, NULL, params, NULL, x, y,
+                              NULL, (psMinimizeLMChi2Func) p_pmMinLM_SersicCore_Vec);
+        break;
+    default:
+        psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
+        rc = false;
+    }
+
+    psFree(x);
+    psFree(y);
+    psFree(myMin);
+    psFree(params);
+    return(rc);
+}
+
+bool p_pmSourceAddOrSubModel(psImage *image,
+                             psSource *src,
+                             bool center,
+                             psS32 flag)
+{
+    PS_PTR_CHECK_NULL(src, false);
+    PS_PTR_CHECK_NULL(src->moments, false);
+    PS_PTR_CHECK_NULL(src->peak, false);
+    PS_PTR_CHECK_NULL(src->pixels, false);
+    PS_PTR_CHECK_NULL(src->models, false);
+    PS_IMAGE_CHECK_NULL(image, false);
+    PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, false);
+
+    psVector *params = psVectorAlloc(src->models->Nparams, PS_TYPE_F32);
+    psVector *x = psVectorAlloc(2, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < src->models->Nparams ; i++) {
+        params->data.F32[i] = src->models->params[i];
+    }
+
+    for (psS32 i = 0 ; i < src->pixels->numRows ; i++) {
+        for (psS32 j = 0 ; j < src->pixels->numCols ; j++) {
+            psF32 pixelValue;
+            // XXX: Should you be adding the pixels for the entire subImage,
+            // or a radius of pixels around it?
+
+            // Convert i/j to imace coord space:
+            // XXX: Make sure you have col/row order correct.
+            psS32 imageRow = i + src->pixels->row0;
+            psS32 imageCol = j + src->pixels->col0;
+
+            x->data.F32[0] = (float) imageCol;
+            x->data.F32[1] = (float) imageRow;
+            switch (src->models->type) {
+            case PS_MODEL_GAUSS:
+                pixelValue = pmMinLM_Gauss2D(NULL, params, x);
+                break;
+            case PS_MODEL_PGAUSS:
+                pixelValue = pmMinLM_PsuedoGauss2D(NULL, params, x);
+                break;
+            case PS_MODEL_TWIST_GAUSS:
+                pixelValue = pmMinLM_TwistGauss2D(NULL, params, x);
+                break;
+            case PS_MODEL_WAUSS:
+                pixelValue = pmMinLM_Wauss2D(NULL, params, x);
+                break;
+            case PS_MODEL_SERSIC:
+                pixelValue = pmMinLM_Sersic(NULL, params, x);
+                break;
+            case PS_MODEL_SERSIC_CORE:
+                pixelValue = pmMinLM_SersicCore(NULL, params, x);
+                break;
+            default:
+                psError(PS_ERR_UNKNOWN, true, "Undefined psModelType");
+                psFree(x);
+                psFree(params);
+                return(false);
+            }
+            if (flag == 1) {
+                pixelValue = -pixelValue;
+            }
+
+            // XXX: Must figure out how to calculate the image coordinates and
+            // how to use the boolean "center" flag.
+
+            image->data.F32[imageRow][imageCol]+= pixelValue;
+        }
+    }
+    psFree(x);
+    psFree(params);
+    return(true);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceAddModel(psImage *image,
+                      psSource *src,
+                      bool center)
+{
+    return(p_pmSourceAddOrSubModel(image, src, center, 0));
+}
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceSubModel(psImage *image,
+                      psSource *src,
+                      bool center)
+{
+    return(p_pmSourceAddOrSubModel(image, src, center, 1));
+}
+
+
+// XXX: Put this is psConstants.h
+#define PS_VECTOR_CHECK_SIZE(VEC1, N, RVAL) \
+if (VEC1->n != N) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "psVector %s has size %d, should be %d.", \
+            #VEC1, VEC1->n, N); \
+    return(RVAL); \
+}
+
+
+/******************************************************************************
+pmMinLM_Gauss2D(*deriv, *params, *x): the argument "x" contains a single "x,
+y" coordinate pair.  This function computes the gaussian, specified by the
+parameters in "params" at that x,y point and returns the value.  The
+derivatives are also caculated and returned in the "deriv" argument.
+ 
+    params->data.F32[0] = So;
+    params->data.F32[1] = Zo;
+    params->data.F32[2] = Xo;
+    params->data.F32[3] = Yo;
+    params->data.F32[4] = sqrt(2.0) / SigmaX;
+    params->data.F32[5] = sqrt(2.0) / SigmaY;
+    params->data.F32[6] = Sxy;
+ 
+XXX: Consider getting rid of the parameter checks since this might consume
+a significant fraction of this function CPU time.
+ 
+XXX: I added the following.  Must conform with IfA.  If deriv==NULL, then
+we simply don't perform the derivative calculations.
+ 
+XXX: It is not clear whether the subImage coords, or the image coords should
+be used when calling these functions.  I don't think it really matters, as
+long as we are consistent.
+ *****************************************************************************/
+psF32 pmMinLM_Gauss2D(psVector *deriv,
+                      psVector *params,
+                      psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 7, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    psF32 X = x->data.F32[0] - params->data.F32[2];
+    psF32 Y = x->data.F32[1] - params->data.F32[3];
+    psF32 px = params->data.F32[4]*X;
+    psF32 py = params->data.F32[5]*Y;
+    psF32 z = 0.5*PS_SQR(px) + 0.5*PS_SQR(py) + params->data.F32[6]*X*Y;
+    psF32 r = exp(-z);
+    psF32 f = params->data.F32[1]*r + params->data.F32[0];
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
+
+        psF32 q = params->data.F32[1]*r;
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q*(2*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+    }
+
+    return(f);
+}
+
+/******************************************************************************
+p_pmMinLM_Gauss2D_Vec(*deriv, *params, *x): this function wraps the above
+function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_Gauss2D_Vec(psImage *deriv,
+                                psVector *params,
+                                psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        psVector *tmpVec2 = (psVector *) x->data[i];
+        tmpVec->data.F32[i] = pmMinLM_Gauss2D(tmpRow,
+                                              params,
+                                              tmpVec2);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+
+/******************************************************************************
+    params->data.F32[0] = So;
+    params->data.F32[1] = Zo;
+    params->data.F32[2] = Xo;
+    params->data.F32[3] = Yo;
+    params->data.F32[4] = sqrt(2) / SigmaX;
+    params->data.F32[5] = sqrt(2) / SigmaY;
+    params->data.F32[6] = Sxy;
+ *****************************************************************************/
+psF32 pmMinLM_PsuedoGauss2D(psVector *deriv,
+                            psVector *params,
+                            psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 7, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    psF32 X = x->data.F32[0] - params->data.F32[2];
+    psF32 Y = x->data.F32[1] - params->data.F32[3];
+    psF32 px = params->data.F32[4]*X;
+    psF32 py = params->data.F32[5]*Y;
+    psF32 z = 0.5*PS_SQR(px) + 0.5*PS_SQR(py) + params->data.F32[6]*X*Y;
+    psF32 t = 1 + z + 0.5*z*z;
+    psF32 r = 1.0 / (t*(1 + z/3)); /* exp (-Z) */
+    psF32 f = params->data.F32[1]*r + params->data.F32[0];
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 7, NAN);
+
+        //
+        // note difference from a pure gaussian: q = params->data.F32[1]*r
+        //
+        psF32 q = params->data.F32[1]*r*r*t;
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q *
+                             (2.0*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+    }
+
+    return(f);
+}
+
+/******************************************************************************
+p_pmMinLM_PsuedoGauss2D_Vec(*deriv, *params, *x): this function wraps the
+above function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_PsuedoGauss2D_Vec(psImage *deriv,
+                                      psVector *params,
+                                      psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        tmpVec->data.F32[i] = pmMinLM_PsuedoGauss2D(tmpRow,
+                              params,
+                              (psVector *) x->data[i]);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+
+
+
+/******************************************************************************
+    params->data.F32[0] = So;
+    params->data.F32[1] = Zo;
+    params->data.F32[2] = Xo;
+    params->data.F32[3] = Yo;
+    params->data.F32[4] = Sx;
+    params->data.F32[5] = Sy;
+    params->data.F32[6] = Sxy;
+    params->data.F32[7] = B2;
+    params->data.F32[8] = B3;
+ *****************************************************************************/
+psF32 pmMinLM_Wauss2D(psVector *deriv,
+                      psVector *params,
+                      psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 9, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    psF32 X = x->data.F32[0] - params->data.F32[2];
+    psF32 Y = x->data.F32[1] - params->data.F32[2];
+    psF32 px = params->data.F32[4]*X;
+    psF32 py = params->data.F32[5]*Y;
+    psF32 z = 0.5*PS_SQR(px) + 0.5*PS_SQR(py) + params->data.F32[6]*X*Y;
+    psF32 t = 0.5*z*z*(1.0 + params->data.F32[8]*z/3.0);
+    psF32 r = 1.0 / (1.0 + z + params->data.F32[7]*t); /* exp (-Z) */
+    psF32 f = params->data.F32[1]*r + params->data.F32[0];
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 9, NAN);
+        //
+        // note difference from gaussian: q = params->data.F32[1]*r
+        //
+
+        psF32 q = params->data.F32[1]*r*r*(1.0 + params->data.F32[7]*z*(1.0 + params->data.F32[8]*z/2.0));
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q*(2.0*px*params->data.F32[4] + params->data.F32[6]*Y);
+        deriv->data.F32[3] = q*(2.0*py*params->data.F32[5] + params->data.F32[6]*X);
+        deriv->data.F32[4] = -2.0*q*px*X;
+        deriv->data.F32[5] = -2.0*q*py*Y;
+        deriv->data.F32[6] = -q*X*Y;
+        deriv->data.F32[7] = -100.0*params->data.F32[1]*r*r*t;
+        deriv->data.F32[8] = -100.0*params->data.F32[1]*r*r*params->data.F32[7]*(z*z*z)/6.0;
+        //
+        // The values of 100 dampen the swing of params->data.F32[7,8] */
+        //
+    }
+
+    return(f);
+}
+
+/******************************************************************************
+p_pmMinLM_Wauss2D_Vec(*deriv, *params, *x): this function wraps the above
+function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_Wauss2D_Vec(psImage *deriv,
+                                psVector *params,
+                                psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        tmpVec->data.F32[i] = pmMinLM_Wauss2D(tmpRow,
+                                              params,
+                                              (psVector *) x->data[i]);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+
+
+
+
+
+// XXX: What should these be?
+#define FFACTOR 1.0
+#define FSCALE 1.0
+/******************************************************************************
+    params->data.F32[0] = So;
+    params->data.F32[1] = Zo;
+    params->data.F32[2] = Xo;
+    params->data.F32[3] = Yo;
+    params->data.F32[4] = SxInner;
+    params->data.F32[5] = SyInner;
+    params->data.F32[6] = SxyInner;
+    params->data.F32[7] = SxOuter;
+    params->data.F32[8] = SyOuter;
+    params->data.F32[9] = SxyOuter;
+    params->data.F32[10] = N;
+ *****************************************************************************/
+psF32 pmMinLM_TwistGauss2D(psVector *deriv,
+                           psVector *params,
+                           psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 11, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    psF32 X = x->data.F32[0] - params->data.F32[2];
+    psF32 Y = x->data.F32[1] - params->data.F32[3];
+    psF32 px1 = params->data.F32[4]*X;
+    psF32 py1 = params->data.F32[5]*Y;
+    psF32 px2 = params->data.F32[7]*X;
+    psF32 py2 = params->data.F32[8]*Y;
+    psF32 z1 = 0.5*PS_SQR(px1) + 0.5*PS_SQR(py1) + params->data.F32[4]*X*Y;
+    psF32 z2 = 0.5*PS_SQR(px2) + 0.5*PS_SQR(py2) + params->data.F32[9]*X*Y;
+    psF32 r = 1.0 / (1.0 + z1 + pow(z2,params->data.F32[10]));
+
+
+    psF32 f = params->data.F32[5]*r + params->data.F32[6];
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 11, NAN);
+
+        psF32 q1 = params->data.F32[5]*PS_SQR(r);
+        psF32 q2 = params->data.F32[5]*PS_SQR(r)*params->data.F32[10]*pow(z2,(params->data.F32[10]-1.0));
+        deriv->data.F32[0] = +1.0;
+        deriv->data.F32[1] = +r;
+        deriv->data.F32[2] = q1*(2.0*px1*params->data.F32[4] + params->data.F32[6]*Y) + q2*(2*px2*params->data.F32[7] + params->data.F32[9]*Y);
+        deriv->data.F32[3] = q1*(2.0*py1*params->data.F32[5] + params->data.F32[6]*X) + q2*(2*py2*params->data.F32[8] + params->data.F32[9]*X);
+
+        //
+        // These fudge factors impede the growth of params->data.F32[4] beyond
+        // params->data.F32[7].
+        //
+        psF32 f1 = fabs(params->data.F32[7]) / fabs(params->data.F32[4]);
+        psF32 f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
+        deriv->data.F32[4] = -2.0*q1*px1*X*f2;
+
+        //
+        // These fudge factors impede the growth of params->data.F32[5] beyond
+        // params->data.F32[8].
+        //
+        f1 = fabs(params->data.F32[8]) / fabs(params->data.F32[5]);
+        f2 = (f1 < FSCALE) ? 1.0 : FFACTOR*(f1 - FSCALE) + 1.0;
+        deriv->data.F32[5] = -2.0*q1*py1*Y*f2;
+        deriv->data.F32[6] = -q1*X*Y;
+        deriv->data.F32[7] = -2.0*q2*px2*X;
+        deriv->data.F32[8] = -2.0*q2*py2*Y;
+        deriv->data.F32[9] = -q2*X*Y;
+        deriv->data.F32[10] = -q1*log(z2);
+    }
+
+    return(f);
+}
+
+/******************************************************************************
+p_pmMinLM_TwistGauss2D_Vec(*deriv, *params, *x): this function wraps the above
+function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_TwistGauss2D_Vec(psImage *deriv,
+                                     psVector *params,
+                                     psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        tmpVec->data.F32[i] = pmMinLM_TwistGauss2D(tmpRow,
+                              params,
+                              (psVector *) x->data[i]);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+
+
+/******************************************************************************
+    float Sersic()
+    params->data.F32[0] = So;
+    params->data.F32[1] = Zo;
+    params->data.F32[2] = Xo;
+    params->data.F32[3] = Yo;
+    params->data.F32[4] = Sx;
+    params->data.F32[5] = Sy;
+    params->data.F32[6] = Sxy;
+    params->data.F32[7] = Nexp;
+ *****************************************************************************/
+psF32 pmMinLM_Sersic(psVector *deriv,
+                     psVector *params,
+                     psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 8, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 8, NAN);
+    }
+
+    psError(PS_ERR_UNKNOWN, true, "This function is not implemented yet.");
+    return(0.0);
+}
+/******************************************************************************
+p_pmMinLM_Sersic_Vec(*deriv, *params, *x): this function wraps the above
+function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_Sersic_Vec(psImage *deriv,
+                               psVector *params,
+                               psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        tmpVec->data.F32[i] = pmMinLM_Sersic(tmpRow,
+                                             params,
+                                             (psVector *) x->data[i]);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+/******************************************************************************
+    float SersicBulge()
+    params->data.F32[0] So;
+    params->data.F32[1] Zo;
+    params->data.F32[2] Xo;
+    params->data.F32[3] Yo;
+    params->data.F32[4] SxInner;
+    params->data.F32[5] SyInner;
+    params->data.F32[6] SxyInner;
+    params->data.F32[7] Zd;
+    params->data.F32[8] SxOuter;
+    params->data.F32[9] SyOuter;
+    params->data.F32[10] = SxyOuter;
+    params->data.F32[11] = Nexp;
+ *****************************************************************************/
+psF32 pmMinLM_SersicCore(psVector *deriv,
+                         psVector *params,
+                         psVector *x)
+{
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(params, 12, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_SIZE(x, 2, NAN);
+
+    if (deriv != NULL) {
+        PS_VECTOR_CHECK_TYPE(deriv, PS_TYPE_F32, NAN);
+        PS_VECTOR_CHECK_SIZE(deriv, 12, NAN);
+    }
+
+    psError(PS_ERR_UNKNOWN, true, "This function is not implemented yet.");
+    return(0.0);
+}
+/******************************************************************************
+p_pmMinLM_SersicCore_Vec(*deriv, *params, *x): this function wraps the above
+function in a form that is usable in the LM minimization routines.
+ *****************************************************************************/
+psVector *p_pmMinLM_SersicCore_Vec(psImage *deriv,
+                                   psVector *params,
+                                   psArray *x)
+{
+    PS_IMAGE_CHECK_NULL(deriv, NULL);
+    PS_IMAGE_CHECK_EMPTY(deriv, NULL);
+    PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    if (deriv->numRows != x->n) {
+        psError(PS_ERR_UNKNOWN, true, "deriv must have one row for each coordinate set in x.");
+    }
+    psVector *tmpVec = psVectorAlloc(x->n, PS_TYPE_F32);
+    // XXX: use static memory here.
+    psVector *tmpRow = psVectorAlloc(deriv->numCols, PS_TYPE_F32);
+
+    for (psS32 i = 0 ; i < x->n ; i++) {
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            tmpRow->data.F32[j] = deriv->data.F32[i][j];
+        }
+
+        tmpVec->data.F32[i] = pmMinLM_SersicCore(tmpRow,
+                              params,
+                              (psVector *) x->data[i]);
+
+        for (psS32 j = 0 ; j < tmpRow->n ; j++) {
+            deriv->data.F32[i][j] = tmpRow->data.F32[j];
+        }
+    }
+
+    psFree(tmpRow);
+    return(tmpVec);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_PsuedoSersic(psVector *deriv,
+                           psVector *params,
+                           psVector *x)
+{
+    return(0.0);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmObjects.h	(revision 22108)
@@ -0,0 +1,261 @@
+/** @file  pmObjects.h
+ *
+ *  This file will ...
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.7.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-06 19:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_OBJECTS_H)
+#define PM_OBJECTS_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+
+typedef enum {
+    PM_PEAK_LONE,           ///< Isolated peak.
+    PM_PEAK_EDGE,           ///< Peak on edge.
+    PM_PEAK_FLAT,           ///< Peak has equal-value neighbors.
+    PM_PEAK_UNDEF           ///< Undefined.
+} psPeakType;
+
+typedef struct
+{
+    psS32 x;                ///< X-coordinate of peak pixel.
+    psS32 y;                ///< Y-coordinate of peak pixel.
+    psF32 counts;           ///< Value of peak pixel (above sky?).
+    psPeakType class;       ///< Description of peak.
+}
+psPeak;
+
+typedef struct
+{
+    psF32 x;                ///< X-coord of centroid.
+    psF32 y;                ///< Y-coord of centroid.
+    psF32 Sx;               ///< x-second moment.
+    psF32 Sy;               ///< y-second moment.
+    psF32 Sxy;              ///< xy cross moment.
+    psF32 Sum;              ///< Pixel sum above sky (background).
+    psF32 Peak;             ///< Peak counts above sky.
+    psF32 Sky;              ///< Sky level (background).
+    psS32 nPixels;          ///< Number of pixels used.
+}
+psMoments;
+
+typedef enum {
+    PS_MODEL_GAUSS,  ///< Regular 2-D Gaussian
+    PS_MODEL_PGAUSS,  ///< Psuedo 2-D Gaussian
+    PS_MODEL_TWIST_GAUSS, ///< 2-D Twisted Gaussian
+    PS_MODEL_WAUSS,  ///< 2-D Waussian
+    PS_MODEL_SERSIC,  ///< Sersic
+    PS_MODEL_SERSIC_CORE, ///< Sersic Core
+    PS_MODEL_UNDEFINED  ///< Undefined
+} psModelType;
+
+// XXX: It will be better if params, and dparams, were psVectors.
+typedef struct
+{
+    psModelType type;       ///< Model to be used.
+    psS32 Nparams;          ///< Number of parameters.
+    psF32 *params;          ///< Paramater values.
+    psF32 *dparams;         ///< Parameter errors.
+    psF32 chisq;            ///< Fit chi-squared.
+}
+psModel;
+
+// XXX: What is this enum?
+typedef enum {
+    PS_SOURCE_PSFSTAR,
+    PS_SOURCE_GALAXY,
+    PS_SOURCE_DEFECT,
+    PS_SOURCE_SATURATED,
+    PS_SOURCE_SATSTAR,
+    PS_SOURCE_FAINTSTAR,
+    PS_SOURCE_BRIGHTSTAR,
+    PS_SOURCE_OTHER
+} psSourceType;
+
+typedef struct
+{
+    psPeak *peak;           ///< Description of peak pixel.
+    psImage *pixels;        ///< Rectangular region including object pixels.
+    psImage *mask;          ///< Mask which marks pixels associated with objects.
+    psMoments *moments;     ///< Basic moments measure for the object.
+    psModel *models;        ///< Model parameters and type.
+    psSourceType type;      ///< Best identification of object.
+}
+psSource;
+
+psPeak *pmPeakAlloc(psS32 x,  ///< Row-coordinate in image space
+                    psS32 y,  ///< Col-coordinate in image space
+                    psF32 counts, ///< The value of the peak pixel
+                    psPeakType class ///< The type of peak pixel
+                   );
+
+psMoments *pmMomentsAlloc();
+psModel *pmModelAlloc(psModelType type);
+psSource *pmSourceAlloc();
+
+/******************************************************************************
+pmFindVectorPeaks(vector, threshold): Find all local peaks in the given vector
+above the given threshold.  Returns a vector of type PS_TYPE_U32 containing
+the location (x value) of all peaks.
+ *****************************************************************************/
+psVector *pmFindVectorPeaks(const psVector *vector, ///< The input vector (psF32)
+                            psF32 threshold  ///< Threshold above which to find a peak
+                           );
+
+/******************************************************************************
+pmFindImagePeaks(image, threshold): Find all local peaks in the given psImage
+above the given threshold.  Returns a psList containing the location (x/y
+value) of all peaks.
+ *****************************************************************************/
+psList *pmFindImagePeaks(const psImage *image, ///< The input image where peaks will be found (psF32)
+                         psF32 threshold ///< Threshold above which to find a peak
+                        );
+
+/******************************************************************************
+psCullPeaks(peaks, maxValue, valid): eliminate peaks from the psList that have
+a peak value above the given maximum, or fall outside the valid region.
+ 
+XXX: Do we free the psList elements of those culled peaks?
+ *****************************************************************************/
+psList *pmCullPeaks(psList *peaks,  ///< The psList of peaks to be culled
+                    psF32 maxValue,  ///< Cull peaks above this value
+                    const psRegion *valid ///< Cull peaks otside this psRegion
+                   );
+
+/******************************************************************************
+psSource *pmSourceLocalSky(image, peak, innerRadius, outerRadius):
+ 
+ *****************************************************************************/
+psSource *pmSourceLocalSky(const psImage *image, ///< The input image (psF32)
+                           const psPeak *peak,  ///< The peak for which the psSource struct is created.
+                           psStatsOptions statsOptions, ///< The statistic used in calculating the background sky
+                           psF32 innerRadius,  ///< The inner radius of the suqare annulus for calculating sky
+                           psF32 outerRadius  ///< The outer radius of the suqare annulus for calculating sky
+                          );
+
+/******************************************************************************
+ *****************************************************************************/
+psSource *pmSourceMoments(psSource *source, ///< The input psSource for which moments will be computed
+                          psF32 radius  ///< Use a circle of pixels around the peak
+                         );
+
+/******************************************************************************
+pmSourceRoughClass(pmArray *source, psMetaDeta *metadata): make a guess at the
+source classification.
+ *****************************************************************************/
+bool pmSourceRoughClass(psArray *source, ///< The input psSource
+                        psMetadata *metadata ///< Contains classification parameters
+                       );
+/******************************************************************************
+pmSourceSetPixelCircle(source, image, radius)
+ *****************************************************************************/
+bool pmSourceSetPixelCircle(psSource *source,  ///< The input psSource
+                            const psImage *image, ///< The input image (psF32)
+                            psF32 radius  ///< The radius of the circle
+                           );
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceModelGuess(psSource *source, ///< The input psSource
+                        const psImage *image, ///< The input image (psF32)
+                        psModelType model ///< The type of model to be created.
+                       );
+
+/******************************************************************************
+ *****************************************************************************/
+typedef enum {
+    PS_CONTOUR_CRUDE,
+} pmContourType;
+
+psArray *pmSourceContour(psSource *source, ///< The input psSource
+                         const psImage *image, ///< The input image (psF32) (this arg should be removed)
+                         psF32 level,  ///< The level of the contour
+                         pmContourType mode ///< Currently this must be PS_CONTOUR_CRUDE
+                        );
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceFitModel(psSource *source,  ///< The input psSource
+                      const psImage *image ///< The input image (psF32)
+                     );
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceAddModel(psImage *image,  ///< The opuut image (psF32)
+                      psSource *source,  ///< The input psSource
+                      bool center  ///< A boolean flag that determines whether pixels are centered
+                     );
+
+/******************************************************************************
+ *****************************************************************************/
+bool pmSourceSubModel(psImage *image,  ///< The output image (psF32)
+                      psSource *source,  ///< The input psSource
+                      bool center  ///< A boolean flag that determines whether pixels are centered
+                     );
+
+/******************************************************************************
+XXX: Why only *x argument?
+ *****************************************************************************/
+psF32 pmMinLM_Gauss2D(psVector *deriv,  ///< A possibly-NULL structure for the output derivatives
+                      psVector *params,  ///< A psVector which holds the parameters of this function
+                      psVector *x  ///< A psVector which holds the row/col coordinate
+                     );
+
+/******************************************************************************
+XXX: Why only *x argument?
+ *****************************************************************************/
+psF32 pmMinLM_PsuedoGauss2D(psVector *deriv, ///< A possibly-NULL structure for the output derivatives
+                            psVector *params, ///< A psVector which holds the parameters of this function
+                            psVector *x  ///< A psVector which holds the row/col coordinate
+                           );
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_Wauss2D(psVector *deriv,  ///< A possibly-NULL structure for the output derivatives
+                      psVector *params,  ///< A psVector which holds the parameters of this function
+                      psVector *x  ///< A psVector which holds the row/col coordinate
+                     );
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_TwistGauss2D(psVector *deriv, ///< A possibly-NULL structure for the output derivatives
+                           psVector *params, ///< A psVector which holds the parameters of this function
+                           psVector *x  ///< A psVector which holds the row/col coordinate
+                          );
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_Sersic(psVector *deriv,  ///< A possibly-NULL structure for the output derivatives
+                     psVector *params,  ///< A psVector which holds the parameters of this function
+                     psVector *x  ///< A psVector which holds the row/col coordinate
+                    );
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_SersicCore(psVector *deriv, ///< A possibly-NULL structure for the output derivatives
+                         psVector *params, ///< A psVector which holds the parameters of this function
+                         psVector *x  ///< A psVector which holds the row/col coordinate
+                        );
+
+/******************************************************************************
+ *****************************************************************************/
+psF32 pmMinLM_PsuedoSersic(psVector *deriv, ///< A possibly-NULL structure for the output derivatives
+                           psVector *params, ///< A psVector which holds the parameters of this function
+                           psVector *x  ///< A psVector which holds the row/col coordinate
+                          );
+
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.c	(revision 22108)
@@ -0,0 +1,374 @@
+/** @file  pmReadoutCombine.c
+ *
+ *  This file will contain a module which will combine multiple readout images.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-07 20:00:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "pmReadoutCombine.h"
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions DetermineNumBits(psStatsOptions data)
+{
+    psS32 i;
+    psU64 tmpData = data;
+    psS32 numBits = 0;
+
+    for (i=0;i<8 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
+            numBits++;
+        }
+        tmpData = tmpData >> 1;
+    }
+    return(numBits);
+}
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ 
+XXX: Must add support for S16 and S32 types.  F32 currently supported.
+ *****************************************************************************/
+psImage *pmReadoutCombine(psImage *output,
+                          const psList *inputs,
+                          psCombineParams *params,
+                          const psVector *zero,
+                          const psVector *scale,
+                          bool applyZeroScale,
+                          psF32 gain,
+                          psF32 readnoise)
+{
+    PS_PTR_CHECK_NULL(inputs, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+    PS_PTR_CHECK_NULL(params->stats, NULL);
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+        //        PS_VECTOR_CHECK_TYPE_S16_S32_F32(zero, NULL);
+    }
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+        //        PS_VECTOR_CHECK_TYPE_S16_S32_F32(scale, NULL);
+    }
+    if ((zero != NULL) && (scale != NULL)) {
+        PS_VECTOR_CHECK_TYPE_EQUAL(zero, scale, NULL);
+        // PS_VECTOR_CHECK_TYPE_S16_S32_F32(scale, NULL);
+    }
+
+    psStats *stats = params->stats;
+    psS32 i;
+    psS32 j;
+    psS32 maxInputCols = 0;
+    psS32 maxInputRows = 0;
+    psS32 minInputCols = PS_MAX_S32;
+    psS32 minInputRows = PS_MAX_S32;
+    psListElem *tmpInput = NULL;
+    psReadout *tmpReadout = NULL;
+    psS32 numInputs = 0;
+    psS32 tmpI;
+    psElemType outputType = PS_TYPE_F32;
+
+    if (1 < DetermineNumBits(params->stats->options)) {
+        psError(PS_ERR_UNKNOWN, true,
+                "Multiple statistical options have been requested.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    //
+    // We step through each readout in the input image list.  If any readout is
+    // NULL, empty, or has the wrong type, we generate an error and return
+    // NULL.  We determine how big of an output image is needed to combine
+    // these input images.  We do this by taking the
+    //     max(readout->col0 + readout->numCols + image->col0 + image->numCols)
+    //     max(readout->row0 + readout->numRows + image->row0 + image->numRows)
+    // We then compare that to
+    //     output->col0 + output->numCols
+    //     output->row0 + output->numRows
+    // to determine if the output image actually stores that pixel.  A similar
+    // thing is done for the minimum row and column.
+    //
+    tmpInput = (psListElem *) inputs->head;
+    while (NULL != tmpInput) {
+        tmpReadout = (psReadout *) tmpInput->data;
+        PS_READOUT_CHECK_NULL(tmpReadout, output);
+        PS_READOUT_CHECK_EMPTY(tmpReadout, output);
+        PS_READOUT_CHECK_TYPE(tmpReadout, PS_TYPE_F32, output);
+        outputType = tmpReadout->image->type.type;
+
+        minInputRows = PS_MIN(minInputRows,
+                              (tmpReadout->row0 + tmpReadout->image->row0));
+        tmpI = tmpReadout->row0 +
+               tmpReadout->image->row0 +
+               tmpReadout->image->numRows;
+        maxInputRows = PS_MAX(maxInputRows, tmpI);
+
+        minInputCols = PS_MIN(minInputCols,
+                              (tmpReadout->col0 + tmpReadout->image->col0));
+        tmpI = tmpReadout->col0 +
+               tmpReadout->image->col0 +
+               tmpReadout->image->numCols;
+        maxInputCols = PS_MAX(maxInputCols, tmpI);
+        tmpInput = tmpInput->next;
+        numInputs++;
+    }
+
+    // We ensure that the zero vector is of the proper size.
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+        if (numInputs > zero->n) {
+            psError(PS_ERR_UNKNOWN, true, "zero vector has incorrect size (%d).  Returning NULL.\n", zero->n);
+            return(NULL);
+        } else if (numInputs < zero->n) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the zero vector too many elements (%d)\n", zero->n);
+        }
+    }
+
+    // We ensure that the scale vector is of the proper size.
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+        if (numInputs > scale->n) {
+            psError(PS_ERR_UNKNOWN, true, "scale vector has incorrect size (%d).  Returning NULL.\n", scale->n);
+            return(NULL);
+        } else if (numInputs < scale->n) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the scale vector has too many elements (%d)\n", scale->n);
+        }
+    }
+
+    // At this point, the following variables have been computed:
+    // maxInputRows: the largest input row value, in output image space.
+    // maxInputCols: the largest input column value, in output image space.
+    // minInputRows: the smallest input row value, in output image space.
+    // minInputCols: the smallest input column value, in output image space.
+    //
+    if (output == NULL) {
+        output = psImageAlloc(maxInputCols-minInputCols,
+                              maxInputRows-minInputRows, outputType);
+        *(psS32 *) &(output->col0) = minInputCols;
+        *(psS32 *) &(output->row0) = minInputRows;
+    } else {
+        PS_IMAGE_CHECK_TYPE(output, PS_TYPE_F32, NULL);
+        if (((output->col0 + output->numCols) < maxInputCols) ||
+                ((output->row0 + output->numRows) < maxInputRows)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Output image (%d, %d) is too small to hold combined images.  Returning NULL.\n",
+                    output->row0 + output->numRows,
+                    output->col0 + output->numCols);
+            return(NULL);
+        }
+
+        if ((output->col0 > minInputCols) || (output->row0 > minInputRows)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Output image offset is larger then input image offset.  Returning NULL.\n");
+            return(NULL);
+        }
+    }
+
+    psVector *tmpPixels = psVectorAlloc(numInputs, PS_TYPE_F32);
+    psVector *tmpPixelErrors = psVectorAlloc(numInputs, PS_TYPE_F32);
+    psVector *tmpPixelMask = psVectorAlloc(numInputs, PS_TYPE_U8);
+    psVector *tmpPixelMaskNKeep = psVectorAlloc(numInputs, PS_TYPE_U8);
+    psVector *outRowLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outRowUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psReadout **tmpReadouts = (psReadout **) psAlloc(numInputs * sizeof(psReadout *));
+
+    // For each input readout, we create a pointer to that readout in
+    // "tmpReadouts[]", and we store the min/max pixel indices for that
+    // readout, in output image coordinates, in the psVectors
+    // (outRowLower, outColLower, outRowUpper, outColUpper).
+    i = 0;
+    tmpInput = (psListElem *) inputs->head;
+    while (NULL != tmpInput) {
+        tmpReadouts[i] = (psReadout *) tmpInput->data;
+        outRowLower->data.U32[i] = tmpReadouts[i]->row0 + tmpReadouts[i]->image->row0;
+        outColLower->data.U32[i] = tmpReadouts[i]->col0 + tmpReadouts[i]->image->col0;
+        outRowUpper->data.U32[i] = tmpReadouts[i]->row0 +
+                                   tmpReadouts[i]->image->row0 +
+                                   tmpReadouts[i]->image->numRows;
+        outColUpper->data.U32[i] = tmpReadouts[i]->col0 +
+                                   tmpReadouts[i]->image->col0 +
+                                   tmpReadouts[i]->image->numCols;
+        tmpInput = tmpInput->next;
+        i++;
+    }
+
+    // We loop through each pixel in the output image.  We loop through each
+    // input readout.  We determine if that output pixel is contained in the
+    // image from that readout.  If so, we save it in psVector tmpPixels.
+    // If not, we set a mask for that element in tmpPixels.  Then, we mask off
+    // pixels not between fracLow and fracHigh.  Then we call the vector
+    // stats routine on those pixels/mask.  Then we set the output pixel value
+    // to the result of the stats call.
+
+    for (i = output->row0; i < (output->row0 + output->numRows) ; i++) {
+        for (j = output->col0; j < (output->col0 + output->numCols) ; j++) {
+            for (psS32 r = 0; r < numInputs ; r++) {
+                //  printf("[%d][%d]: [%d][%d] to [%d][%d]\n", i, j, outRowLower->data.U32[r], outColLower->data.U32[r], outRowUpper->data.U32[r], outColUpper->data.U32[r]);
+                if ((outRowLower->data.U32[r] <= i) &&
+                        (outColLower->data.U32[r] <= j) &&
+                        (outRowUpper->data.U32[r] > i) &&
+                        (outColUpper->data.U32[r] > j)) {
+
+                    psS32 imageRow = i - (tmpReadouts[r]->row0 +
+                                          tmpReadouts[r]->image->row0);
+                    psS32 imageCol = j - (tmpReadouts[r]->col0 +
+                                          tmpReadouts[r]->image->col0);
+
+                    if ((NULL == tmpReadouts[r]->mask) ||
+                            !(params->maskVal && tmpReadouts[r]->mask->data.U8[imageRow][imageCol])) {
+                        tmpPixels->data.F32[r] = tmpReadouts[r]->image->data.F32[imageRow][imageCol];
+                        tmpPixelMask->data.U8[r] = 0;
+                    } else {
+                        tmpPixels->data.F32[r] = 0.0;
+                        tmpPixelMask->data.U8[r] = 1;
+                    }
+                } else {
+                    tmpPixels->data.F32[r] = 0.0;
+                    tmpPixelMask->data.U8[r] = 1;
+                }
+                // printf("readout[%d], image [%d][%d] is %f\n", r, i, j, tmpPixels->data.F32[r]);
+            }
+            // At this point, we have scanned all input readouts for this
+            // one output pixel.
+
+            // Determine how many pixels lie between fracLow and fracHigh.
+            psS32 pixelCount = 0;
+            for (psS32 r = 0; r < numInputs ; r++) {
+                if (tmpPixelMask->data.U8[r] == 0) {
+                    if ((params->fracLow <= tmpPixels->data.F32[r]) &&
+                            (params->fracHigh >= tmpPixels->data.F32[r])) {
+                        pixelCount++;
+                    }
+                }
+            }
+
+            // If more than params->nKeep pixels lie between the valid range,
+            // then loop through the pixels, and mask away any pixels outside
+            // that range.
+            if (pixelCount >= params->nKeep) {
+                for (psS32 r = 0; r < numInputs ; r++) {
+                    if (tmpPixelMask->data.U8[r] == 0) {
+                        if ((params->fracLow <= tmpPixels->data.F32[r]) &&
+                                (params->fracHigh >= tmpPixels->data.F32[r])) {
+                            tmpPixelMaskNKeep->data.U8[r] = 0;
+                        } else {
+                            tmpPixelMaskNKeep->data.U8[r] = 1;
+                        }
+                    }
+                }
+            }
+
+            if ((gain > 0.0) && (readnoise >= 0.0)) {
+                psF32 x;
+                psF32 sigma;
+                if (applyZeroScale == true) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        if (zero != NULL) {
+                            x = zero->data.F32[r];
+                        } else {
+                            x = 0.0;
+                        }
+                        if (scale != NULL) {
+                            x+= tmpPixels->data.F32[r] * scale->data.F32[r];
+                        } else {
+                            x+= tmpPixels->data.F32[r];
+                        }
+                        sigma = PS_SQRT_F32((readnoise*readnoise) + gain * x) / gain;
+
+                        tmpPixelErrors->data.F32[r] = sigma;
+                        tmpPixels->data.F32[r]= x;
+                    }
+                } else {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        x= tmpPixels->data.F32[r];
+
+                        if (zero != NULL) {
+                            sigma = zero->data.F32[r];
+                        } else {
+                            sigma = 0.0;
+                        }
+                        if (scale != NULL) {
+                            sigma+= tmpPixels->data.F32[r] * scale->data.F32[r];
+                        } else {
+                            sigma+= tmpPixels->data.F32[r];
+                        }
+                        sigma = PS_SQRT_F32((readnoise*readnoise) + (gain * sigma)) / gain;
+
+                        tmpPixelErrors->data.F32[r] = sigma;
+                        tmpPixels->data.F32[r]= x;
+                    }
+                }
+                // Calculate the specified statistic on the stack of pixels.
+                psStats *rc = psVectorStats(stats,
+                                            tmpPixels,
+                                            tmpPixelErrors,
+                                            tmpPixelMaskNKeep,
+                                            1);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning NULL.\n");
+                    return(NULL);
+                }
+            } else {
+                if (scale != NULL) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        tmpPixels->data.F32[r]*= scale->data.F32[r];
+                    }
+                }
+
+                // We add the zero vector, if non-NULL.
+                if (zero != NULL) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        tmpPixels->data.F32[r]+= zero->data.F32[r];
+                    }
+                }
+
+                // Calculate the specified statistic on the stack of pixels.
+                psStats *rc = psVectorStats(stats,
+                                            tmpPixels,
+                                            NULL,
+                                            tmpPixelMaskNKeep,
+                                            1);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning NULL.\n");
+                    return(NULL);
+                }
+            }
+
+
+            // Set the pixel value in the output image to the stat value.
+            double statValue;
+            if (!p_psGetStatValue(stats, &statValue)) {
+                psError(PS_ERR_UNKNOWN, true, "Could not determine stats value.  Returning NULL.\n");
+                return(NULL);
+            } else {
+                output->data.F32[i-output->row0][j-output->col0] = (psF32) statValue;
+            }
+        }
+    }
+
+    psFree(tmpPixels);
+    psFree(tmpPixelErrors);
+    psFree(tmpPixelMask);
+    psFree(tmpPixelMaskNKeep);
+    psFree(outRowLower);
+    psFree(outRowUpper);
+    psFree(outColLower);
+    psFree(outColUpper);
+    psFree(tmpReadouts);
+
+    return(output);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmReadoutCombine.h	(revision 22108)
@@ -0,0 +1,45 @@
+/** @file  pmReadoutCombine.h
+ *
+ *  This file will contain a module which will combine multiple readout images.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-06 19:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_READOUT_COMBINE_H)
+#define PM_READOUT_COMBINE_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "psConstants.h"
+
+typedef struct
+{
+    psStats *stats;
+    unsigned int maskVal;
+    float fracHigh;
+    float fracLow;
+    int nKeep;
+}
+psCombineParams;
+
+psImage *pmReadoutCombine(psImage *output,
+                          const psList *inputs,
+                          psCombineParams *params,
+                          const psVector *zero,
+                          const psVector *scale,
+                          bool applyZeroScale,
+                          float gain,
+                          float readnoise);
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.c	(revision 22108)
@@ -0,0 +1,646 @@
+/** @file  pmSubtractBias.c
+ *
+ *  This file will contain a module which will subtract the detector bias
+ *  in place from an input image.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-03-31 02:02:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+
+
+
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pmSubtractBias.h"
+
+#define PM_SUBTRACT_BIAS_POLYNOMIAL_ORDER 2
+#define PM_SUBTRACT_BIAS_SPLINE_ORDER 3
+
+/******************************************************************************
+psSubtractFrame(): this routine will take as input a readout for the input
+image and a readout for the bias image.  The bias image is subtracted in
+place from the input image.
+ *****************************************************************************/
+psReadout *psSubtractFrame(psReadout *in,
+                           const psReadout *bias)
+{
+    psS32 i;
+    psS32 j;
+
+    if (bias == NULL) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.c: psSubtractFrame(): bias frame is NULL.  Returning original image.\n");
+        return(in);
+    }
+
+    if (((in->image)->numRows + in->row0 - bias->row0) > (bias->image)->numRows) {
+        psError(PS_ERR_UNKNOWN,true, "bias image does not have enough rows.  Returning in image\n");
+        return(in);
+    }
+    if (((in->image)->numCols + in->row0 - bias->row0) > (bias->image)->numCols) {
+        psError(PS_ERR_UNKNOWN,true, "bias image does not have enough columns.  Returning in image\n");
+        return(in);
+    }
+
+    for (i=0;i<(in->image)->numRows;i++) {
+        for (j=0;j<(in->image)->numCols;j++) {
+            (in->image)->data.F32[i][j]-=
+                (bias->image)->data.F32[i+in->row0-bias->row0][j+in->col0-bias->col0];
+            if ((in->mask != NULL) && (bias->mask != NULL)) {
+                ((in->mask)->data.U8[i][j])|=
+                    (bias->mask)->data.U8[i+in->row0-bias->row0][j+in->col0-bias->col0];
+            }
+        }
+    }
+
+    return(in);
+}
+
+/******************************************************************************
+p_psImageSubtractScalar(): subtract a scalar from the input image.
+ *****************************************************************************/
+psImage *p_psImageSubtractScalar(psImage *image,
+                                 psF32 scalar)
+{
+    for (psS32 i=0;i<image->numRows;i++) {
+        for (psS32 j=0;j<image->numCols;j++) {
+            (image->data.F32[i][j])-= scalar;
+        }
+    }
+    return(image);
+}
+
+/******************************************************************************
+GenNewStatOptions(): this routine will take as input the options member of the
+stat data structure, determine if multiple options have been specified, issue
+a warning message if so, and return the highest priority option (according to
+the order of the if-statements in this code).  The higher priority options are
+listed lower in the code.
+ *****************************************************************************/
+psStatsOptions GenNewStatOptions(const psStats *stat)
+{
+    psS32 numOptions = 0;
+    psStatsOptions opt = 0;
+
+    if (stat->options & PS_STAT_ROBUST_MODE) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MODE;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_CLIPPED_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_CLIPPED_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_SAMPLE_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_SAMPLE_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_SAMPLE_MEAN) {
+        numOptions++;
+        opt = PS_STAT_SAMPLE_MEAN;
+    }
+
+
+    if (numOptions == 0) {
+        psError(PS_ERR_UNKNOWN,true, "No statistics options have been specified.\n");
+    }
+    if (numOptions != 1) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.c: GenNewStatOptions(): Too many statistics options have been specified\n");
+    }
+    return(opt);
+}
+
+/******************************************************************************
+ScaleOverscanVector(): this routine takes as input an arbitrary vector,
+creates a new vector of length n, and fills the new vector with the
+interpolated values of the old vector.  The type of interpolation is:
+    PM_FIT_POLYNOMIAL: fit a polynomial to the entire input vector data.
+    PM_FIT_SPLINE: fit splines to the input vector data.
+XXX: Doesn't it make more sense to do polynomial interpolation on a few
+elements of the input vector, rather than fit a polynomial to the entire
+vector?
+ *****************************************************************************/
+psVector *ScaleOverscanVector(psVector *overscanVector,
+                              psS32 n,
+                              void *fitSpec,
+                              pmFit fit)
+{
+    psTrace(".psModule.pmSubtracBias.ScaleOverscanVector", 4,
+            "---- ScaleOverscanVector() begin (%d -> %d) ----\n", overscanVector->n, n);
+
+    if (NULL == overscanVector) {
+        return(overscanVector);
+    }
+
+    // Allocate the new vector.
+    psVector *newVec = psVectorAlloc(n, PS_TYPE_F32);
+
+    //
+    // If the new vector is the same size as the old, simply copy the data.
+    if (n == overscanVector->n) {
+        for (psS32 i = 0 ; i < n ; i++) {
+            newVec->data.F32[i] = overscanVector->data.F32[i];
+        }
+        return(newVec);
+    }
+    psPolynomial1D *myPoly;
+    psSpline1D *mySpline;
+    psF32 x;
+    psS32 i;
+
+    if (fit == PM_FIT_POLYNOMIAL) {
+        // Fit a polynomial to the old overscan vector.
+        myPoly = (psPolynomial1D *) fitSpec;
+        PS_POLY_CHECK_NULL(myPoly, NULL);
+        myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+        if (myPoly == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): Could not fit a polynomial to the psVector.\n");
+            return(NULL);
+        }
+
+        // For each element of the new vector, convert the x-ordinate to that
+        // of the old vector, use the fitted polynomial to determine the
+        // interpolated value at that point, and set the new vector.
+        for (i=0;i<n;i++) {
+            x = ((psF32) i) * ((psF32) overscanVector->n) / ((psF32) n);
+            newVec->data.F32[i] = psPolynomial1DEval(myPoly, x);
+        }
+    } else if (fit == PM_FIT_SPLINE) {
+        psS32 mustFreeSpline = 0;
+        // Fit a spline to the old overscan vector.
+        mySpline = (psSpline1D *) fitSpec;
+        if (mySpline == NULL) {
+            mustFreeSpline = 1;
+        }
+
+        //
+        // NOTE: Since the X arg in the psVectorFitSpline1D() function is NULL,
+        // splines enpoints will be from 0.0 to overscanVector->n-1.  Must scale
+        // properly when doing the spline eval.
+        //
+        mySpline = psVectorFitSpline1D(mySpline, NULL, overscanVector, NULL);
+        if (mySpline == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): Could not fit a spline to the psVector.\n");
+            return(NULL);
+        }
+
+        // For each element of the new vector, convert the x-ordinate to that
+        // of the old vector, use the fitted polynomial to determine the
+        // interpolated value at that point, and set the new vector.
+        for (i=0;i<n;i++) {
+            // Scale to [0 : overscanVector->n - 1]
+            x = ((psF32) i) * ((psF32) (overscanVector->n-1)) / ((psF32) n);
+            newVec->data.F32[i] = psSpline1DEval(mySpline, x);
+        }
+        if (mustFreeSpline ==1) {
+            psFree(mySpline);
+        }
+
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "unknown fit type.  Returning NULL.\n");
+        psFree(newVec);
+        return(NULL);
+    }
+
+    psTrace(".psModule.pmSubtracBias.ScaleOverscanVector", 4,
+            "---- ScaleOverscanVector() exit ----\n");
+    return(newVec);
+}
+
+/******************************************************************************
+XXX: The SDRS does not specify type support.  F32 is implemented here.
+ *****************************************************************************/
+psReadout *pmSubtractBias(psReadout *in,
+                          void *fitSpec,
+                          const psList *overscans,
+                          pmOverscanAxis overScanAxis,
+                          psStats *stat,
+                          psS32 nBinOrig,
+                          pmFit fit,
+                          const psReadout *bias)
+{
+    psTrace(".psModule.pmSubtracBias.pmSubtractBias", 4,
+            "---- pmSubtractBias() begin ----\n");
+    PS_READOUT_CHECK_NULL(in, NULL);
+    PS_READOUT_CHECK_EMPTY(in, NULL);
+    PS_READOUT_CHECK_TYPE(in, PS_TYPE_F32, NULL);
+
+    //
+    // If the overscans != NULL, then check the type of each image.
+    //
+    if (overscans != NULL) {
+        psListElem *tmpOverscan = (psListElem *) overscans->head;
+        while (NULL != tmpOverscan) {
+            psImage *myOverscanImage = (psImage *) tmpOverscan->data;
+            PS_IMAGE_CHECK_TYPE(myOverscanImage, PS_TYPE_F32, NULL);
+            tmpOverscan = tmpOverscan->next;
+        }
+    }
+
+    if ((overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE)) {
+        psError(PS_ERR_UNKNOWN,true, "(overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image\n");
+        return(in);
+    }
+
+    // Check for an unallowable pmFit.
+    if ((fit != PM_OVERSCAN_NONE) &&
+            (fit != PM_OVERSCAN_ROWS) &&
+            (fit != PM_OVERSCAN_COLUMNS) &&
+            (fit != PM_OVERSCAN_ALL)) {
+        psError(PS_ERR_UNKNOWN, true, "fit is unallowable (%d).  Returning in image.\n", fit);
+        return(in);
+    }
+    // Check for an unallowable pmOverscanAxis.
+    if ((overScanAxis != PM_OVERSCAN_NONE) &&
+            (overScanAxis != PM_OVERSCAN_ROWS) &&
+            (overScanAxis != PM_OVERSCAN_COLUMNS) &&
+            (overScanAxis != PM_OVERSCAN_ALL)) {
+        psError(PS_ERR_UNKNOWN, true, "overScanAxis is unallowable (%d).  Returning in image.\n", overScanAxis);
+        return(in);
+    }
+    psS32 i;
+    psS32 j;
+    psS32 numBins = 0;
+    static psVector *overscanVector = NULL;
+    psVector *tmpRow = NULL;
+    psVector *tmpCol = NULL;
+    psVector *myBin = NULL;
+    psVector *binVec = NULL;
+    psListElem *tmpOverscan = NULL;
+    double statValue;
+    psImage *myOverscanImage = NULL;
+    psPolynomial1D *myPoly = NULL;
+    psSpline1D *mySpline = NULL;
+    psS32 nBin;
+
+    //
+    //  Create a static stats data structure and determine the highest
+    //  priority stats option.
+    //
+    static psStats *myStats = NULL;
+    if (myStats == NULL) {
+        myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        p_psMemSetPersistent(myStats, true);
+    }
+    if (stat != NULL) {
+        myStats->options = GenNewStatOptions(stat);
+    }
+
+
+
+
+    if (overScanAxis == PM_OVERSCAN_NONE) {
+        if (fit != PM_FIT_NONE) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.\n");
+        }
+
+        if (overscans != NULL) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractBias.(): overScanAxis equals NONE and overscans does not equal NULL.  Proceeding to full fram subtraction.\n");
+        }
+        return(psSubtractFrame(in, bias));
+    }
+
+    if ((overScanAxis == PM_OVERSCAN_ALL) && (fit != PM_FIT_NONE)) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.\n");
+    }
+
+
+    //
+    // We subtract each overscan region from the image data.
+    // If we get here we know that overscans != NULL.
+    //
+
+    if (overScanAxis == PM_OVERSCAN_ALL) {
+        tmpOverscan = (psListElem *) overscans->head;
+        while (NULL != tmpOverscan) {
+            myOverscanImage = (psImage *) tmpOverscan->data;
+
+            PS_IMAGE_CHECK_TYPE(myOverscanImage, PS_TYPE_F32, NULL);
+            psStats *rc = psImageStats(myStats, myOverscanImage, NULL, 0xffffffff);
+            if (rc == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+                return(in);
+            }
+            if (false == p_psGetStatValue(myStats, &statValue)) {
+                psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                return(in);
+            }
+            p_psImageSubtractScalar(in->image, statValue);
+
+            tmpOverscan = tmpOverscan->next;
+        }
+        return(in);
+    }
+
+    // This check is redundant with above code.
+    if (!((overScanAxis == PM_OVERSCAN_ROWS) || (overScanAxis == PM_OVERSCAN_COLUMNS))) {
+        psError(PS_ERR_UNKNOWN, true, "overScanAxis is unallowable (%d).\nReturning in image.\n", overScanAxis);
+        return(in);
+    }
+
+    tmpOverscan = (psListElem *) overscans->head;
+    while (NULL != tmpOverscan) {
+        myOverscanImage = (psImage *) tmpOverscan->data;
+
+        if (overScanAxis == PM_OVERSCAN_ROWS) {
+            if (myOverscanImage->numCols != (in->image)->numCols) {
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractBias.(): overscan image has %d columns, input image has %d columns\n",
+                         myOverscanImage->numCols, in->image->numCols);
+            }
+
+            // We create a row vector and subtract this vector from image.
+            // XXX: Is there a better way to extract a psVector from a psImage without
+            // having to copy every element in that vector?
+            overscanVector = psVectorAlloc(myOverscanImage->numCols, PS_TYPE_F32);
+            for (i=0;i<overscanVector->n;i++) {
+                overscanVector->data.F32[i] = 0.0;
+            }
+            tmpRow = psVectorAlloc(myOverscanImage->numRows, PS_TYPE_F32);
+
+            // For each column of the input image, loop through every row,
+            // collect the pixel in that row, then performed the specified
+            // statistical op on those pixels.  Store this in overscanVector.
+            for (i=0;i<myOverscanImage->numCols;i++) {
+                for (j=0;j<myOverscanImage->numRows;j++) {
+                    tmpRow->data.F32[j] = myOverscanImage->data.F32[j][i];
+                }
+                psStats *rc = psVectorStats(myStats, tmpRow, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                overscanVector->data.F32[i] = statValue;
+            }
+            psFree(tmpRow);
+
+            // Scale the overscan vector to the size of the input image.
+            if (overscanVector->n != in->image->numCols) {
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector,
+                                                           in->image->numCols,
+                                                           fitSpec, fit);
+                    if (newVec == NULL) {
+                        psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): could not scale the overscan vector.  Returning in image.\n");
+                        return(in);
+                    }
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                } else {
+                    psError(PS_ERR_UNKNOWN, true, "Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+        }
+
+        if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+            if (myOverscanImage->numRows != (in->image)->numRows) {
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractBias.(): overscan image has %d rows, input image has %d rows\n",
+                         myOverscanImage->numRows, in->image->numRows);
+            }
+
+            // We create a column vector and subtract this vector from image.
+            overscanVector = psVectorAlloc(myOverscanImage->numRows, PS_TYPE_F32);
+            for (i=0;i<overscanVector->n;i++) {
+                overscanVector->data.F32[i] = 0.0;
+            }
+            tmpCol = psVectorAlloc(myOverscanImage->numCols, PS_TYPE_F32);
+
+            // For each row of the input image, loop through every column,
+            // collect the pixel in that row, then performed the specified
+            // statistical op on those pixels.  Store this in overscanVector.
+            for (i=0;i<myOverscanImage->numRows;i++) {
+                for (j=0;j<myOverscanImage->numCols;j++) {
+                    tmpCol->data.F32[j] = myOverscanImage->data.F32[i][j];
+                }
+                psStats *rc = psVectorStats(myStats, tmpCol, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                overscanVector->data.F32[i] = statValue;
+            }
+            psFree(tmpCol);
+
+            // Scale the overscan vector to the size of the input image.
+            if (overscanVector->n != in->image->numRows) {
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector,
+                                                           in->image->numRows,
+                                                           fitSpec, fit);
+                    if (newVec == NULL) {
+                        psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): could not scale the overscan vector.  Returning in image.\n");
+                        return(in);
+                    }
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                } else {
+                    psError(PS_ERR_UNKNOWN, true, "Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+        }
+
+        //
+        // Re-bin the overscan vector (change its length).
+        //
+        // Only if nBinOrig > 1.
+        if ((nBinOrig > 1) && (nBinOrig < overscanVector->n)) {
+            numBins = 1+((overscanVector->n)/nBinOrig);
+            myBin = psVectorAlloc(numBins, PS_TYPE_F32);
+            binVec = psVectorAlloc(nBinOrig, PS_TYPE_F32);
+
+            for (i=0;i<numBins;i++) {
+                for(j=0;j<nBinOrig;j++) {
+                    if (overscanVector->n > ((i*nBinOrig)+j)) {
+                        binVec->data.F32[j] = overscanVector->data.F32[(i*nBinOrig)+j];
+                    } else {
+                        // XXX: we get here if nBinOrig does not evenly divide
+                        // the overscanVector vector.  This is the last bin.  Should
+                        // we change the binVec->n to acknowledge that?
+                        binVec->n = j;
+                    }
+                }
+                psStats *rc = psVectorStats(myStats, binVec, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                myBin->data.F32[i] = statValue;
+            }
+
+            // Change the effective size of overscanVector.
+            overscanVector->n = numBins;
+            for (i=0;i<numBins;i++) {
+                overscanVector->data.F32[i] = myBin->data.F32[i];
+            }
+            psFree(binVec);
+            psFree(myBin);
+            nBin = nBinOrig;
+        } else {
+            nBin = 1;
+        }
+
+        // At this point the number of data points in overscanVector should be
+        // equal to the number of rows/columns (whatever is appropriate) in the
+        // image divided by numBins.
+        //
+
+
+        //
+        // This doesn't seem right.  The only way to do a spline fit is if,
+        // by SDRS requirements, fitSpec is not-NULL>  But in order for it
+        // to be non-NULL, someone must have called psSpline1DAlloc() with
+        // the min, max, and number of splines.
+        //
+        if (!((fitSpec == NULL) || (fit == PM_FIT_NONE))) {
+            //
+            // Fit a polynomial or spline to the overscan vector.
+            //
+            if (fit == PM_FIT_POLYNOMIAL) {
+                myPoly = (psPolynomial1D *) fitSpec;
+                myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+                if (myPoly == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "Could not fit a polynomial to overscan vector.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            } else if (fit == PM_FIT_SPLINE) {
+                mySpline = (psSpline1D *) fitSpec;
+                mySpline = psVectorFitSpline1D(mySpline, NULL, overscanVector, NULL);
+                if (mySpline == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "Could not fit a spline to overscan vector.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+
+            //
+            // Subtract fitted overscan vector row-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_ROWS) {
+                for (i=0;i<(in->image)->numCols;i++) {
+                    psF32 tmpF32 = 0.0;
+                    if (fit == PM_FIT_POLYNOMIAL) {
+                        tmpF32 = psPolynomial1DEval(myPoly, ((psF32) i) / ((psF32) nBin));
+                    } else if (fit == PM_FIT_SPLINE) {
+                        tmpF32 = psSpline1DEval(mySpline, ((psF32) i) / ((psF32) nBin));
+                    }
+                    for (j=0;j<(in->image)->numRows;j++) {
+                        (in->image)->data.F32[j][i]-= tmpF32;
+                    }
+                }
+            }
+
+            //
+            // Subtract fitted overscan vector column-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+                for (i=0;i<(in->image)->numRows;i++) {
+                    psF32 tmpF32 = 0.0;
+                    if (fit == PM_FIT_POLYNOMIAL) {
+                        tmpF32 = psPolynomial1DEval(myPoly, ((psF32) i) / ((psF32) nBin));
+                    } else if (fit == PM_FIT_SPLINE) {
+                        tmpF32 = psSpline1DEval(mySpline, ((psF32) i) / ((psF32) nBin));
+                    }
+
+                    for (j=0;j<(in->image)->numCols;j++) {
+                        (in->image)->data.F32[i][j]-= tmpF32;
+                    }
+                }
+            }
+        } else {
+            //
+            // If we get here, then no polynomials were fit to the overscan
+            // vector.  We simply subtract it, taking into account binning,
+            // from the image.
+            //
+
+            //
+            // Subtract overscan vector row-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_ROWS) {
+                for (i=0;i<(in->image)->numCols;i++) {
+                    for (j=0;j<(in->image)->numRows;j++) {
+                        (in->image)->data.F32[j][i]-= overscanVector->data.F32[i/nBin];
+                    }
+                }
+            }
+
+            //
+            // Subtract overscan vector column-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+                for (i=0;i<(in->image)->numRows;i++) {
+                    for (j=0;j<(in->image)->numCols;j++) {
+                        (in->image)->data.F32[i][j]-= overscanVector->data.F32[i/nBin];
+                    }
+                }
+            }
+        }
+
+        psFree(overscanVector);
+
+        tmpOverscan = tmpOverscan->next;
+    }
+
+    psTrace(".psModule.pmSubtracBias.pmSubtractBias", 4,
+            "---- pmSubtractBias() exit ----\n");
+
+    if (bias != NULL) {
+        return(psSubtractFrame(in, bias));
+    }
+    return(in);
+}
+
+
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractBias.h	(revision 22108)
@@ -0,0 +1,48 @@
+/** @file  pmSubtractBias.h
+ *
+ *  This file will contain a module which will subtract the detector bias
+ *  in place from an input image.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.4.6.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-06 19:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_SUBTRACT_BIAS_H)
+#define PM_SUBTRACT_BIAS_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+
+typedef enum {
+    PM_OVERSCAN_NONE,                         ///< No overscan subtraction
+    PM_OVERSCAN_ROWS,                         ///< Subtract rows
+    PM_OVERSCAN_COLUMNS,                      ///< Subtract columns
+    PM_OVERSCAN_ALL                           ///< Subtract the statistic of all pixels in overscan region
+} pmOverscanAxis;
+
+typedef enum {
+    PM_FIT_NONE,                              ///< No fit
+    PM_FIT_POLYNOMIAL,                        ///< Fit polynomial
+    PM_FIT_SPLINE                             ///< Fit cubic splines
+} pmFit;
+
+psReadout *pmSubtractBias(psReadout *in,
+                          void *fitSpec,
+                          const psList *overscans,
+                          pmOverscanAxis overScanAxis,
+                          psStats *stat,
+                          int nBin,
+                          pmFit fit,
+                          const psReadout *bias);
+
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.c	(revision 22108)
@@ -0,0 +1,676 @@
+/** @file  pmSubtractSky.c
+ *
+ *  This file will contain a module which will create a model of the
+ *  background sky and subtract that from the input image.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-19 00:06:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+xd *
+ */
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "psConstants.h"
+#include "pmSubtractSky.h"
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions p_psDetermineNumBits(psStatsOptions data)
+{
+    psS32 i;
+    psU64 tmpData = data;
+    psS32 numBits = 0;
+
+    for (i=0;i<8 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
+            numBits++;
+        }
+        tmpData = tmpData >> 1;
+    }
+    return(numBits);
+}
+
+/******************************************************************************
+getHighestPriorityStatOption(statOptions): this routine takes as input a
+psStats->options with multiple options set and returns one with a single
+option set according to the precedence set in the SDRS.
+ *****************************************************************************/
+psU64 getHighestPriorityStatOption(psU64 statOptions)
+{
+    if (statOptions & PS_STAT_SAMPLE_MEAN) {
+        return(PS_STAT_SAMPLE_MEAN);
+    } else if (statOptions & PS_STAT_SAMPLE_MEDIAN) {
+        return(PS_STAT_SAMPLE_MEDIAN);
+    } else if (statOptions & PS_STAT_CLIPPED_MEAN) {
+        return(PS_STAT_CLIPPED_MEAN);
+    } else if (statOptions & PS_STAT_ROBUST_MEAN) {
+        return(PS_STAT_ROBUST_MEAN);
+    } else if (statOptions & PS_STAT_ROBUST_MEDIAN) {
+        return(PS_STAT_ROBUST_MEDIAN);
+    } else if (statOptions & PS_STAT_ROBUST_MODE) {
+        return(PS_STAT_ROBUST_MODE);
+    }
+    psError(PS_ERR_UNKNOWN, true, "Unallowable option requested for statistically binning image pixels.\n");
+    return(-1);
+}
+
+/******************************************************************************
+psImage *binImage(origImage, binFactor, statOptions): This routine takes an
+input psImage and scales it smaller by a factor of binFactor.  The statistic
+used in combining input pixels is specified in statOptions.
+ 
+XXX: use static vectors for myStats, binVector and binMask.
+XXX: I coded this before I was aware of a psLib reBin function.  I don't
+use this function in this module.  I'm keeping it here in the event that
+requirements change and we might need a custom reBin function.
+ *****************************************************************************/
+psImage *binImage(psImage *origImage,
+                  int binFactor,
+                  psStatsOptions statOptions)
+{
+    if (binFactor <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: binImage(): binFactor is %d\n", binFactor);
+        return(origImage);
+    }
+    if (binFactor == 1) {
+        return(origImage);
+    }
+
+    psVector *binVector = psVectorAlloc(binFactor * binFactor, PS_TYPE_F32);
+    psVector *binMask = psVectorAlloc(binFactor * binFactor, PS_TYPE_U8);
+    psStats *myStats = psStatsAlloc(statOptions);
+
+    for (psS32 row = 0; row < origImage->numRows ; row+=binFactor) {
+        for (psS32 col = 0; col < origImage->numCols ; col+=binFactor) {
+            psS32 count = 0;
+            for (psS32 binRow = 0; binRow <= binFactor ; binRow++) {
+                for (psS32 binCol = 0; binCol <= binFactor ; binCol++) {
+                    if (((row + binRow) < origImage->numRows) &&
+                            ((col + binCol) < origImage->numCols)) {
+                        binVector->data.F32[count] =
+                            origImage->data.F32[row + binRow][col + binCol];
+                        binMask->data.U8[count] = 0;
+                    } else {
+                        binVector->data.F32[count] = 0.0;
+                        binMask->data.U8[count] = 1;
+                    }
+                    count++;
+                }
+            }
+            psStats *rc1 = psVectorStats(myStats, binVector, NULL, binMask, 1);
+            if (rc1 == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                return(origImage);
+            }
+            psF64 statValue;
+            psBool rc = p_psGetStatValue(rc1, &statValue);
+
+            if (rc == true) {
+                origImage->data.F32[row][col] = (psF32) statValue;
+            } else {
+                origImage->data.F32[row][col] = 0.0;
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractSky(), binImage(): p_psGetStatValue() was FALSE\n");
+            }
+        }
+    }
+    psFree(binVector);
+    psFree(binMask);
+    psFree(myStats);
+
+    return(origImage);
+}
+
+/******************************************************************************
+CalculatePolyTerms(xOrder, yOrder): this routine will calculate the number of
+coefficients (or terms) in a 2-D polynomial of order (xOrder, yOrder).
+ *****************************************************************************/
+psS32 CalculatePolyTerms(psS32 xOrder, psS32 yOrder)
+{
+    psS32 maxOrder = PS_MAX(xOrder, yOrder);
+    psS32 localPolyTerms = 0;
+    psS32 order = 0;
+    psS32 num=0;
+
+    for (order=0;order<=maxOrder;order++) {
+        for (num=0;num<=order;num++) {
+            if (((order-num) <= xOrder) && (num <= yOrder)) {
+                localPolyTerms++;
+            }
+        }
+    }
+    return(localPolyTerms);
+}
+
+/******************************************************************************
+buildPolyTerms(): this routine computes a 2-D array polyTerms[][] that holds
+terms for the polynomial that is used to model the sky background.  We use
+this array primarily for convenience in computations involving sky model
+polynomials.  It is defined as:
+    polyTerms[i][0] = the power to which X is raised in the i-th term of in an
+    poly-order sky background polynomial.
+ 
+    polyTerms[i][1] = the power to which Y is raised in the i-th term of in an
+    poly-order sky background polynomial.
+ *****************************************************************************/
+psS32 **buildPolyTerms(psS32 xOrder, psS32 yOrder)
+{
+    psS32 i=0;
+    psS32 order = 0;
+    psS32 num=0;
+    psS32 localPolyTerms = CalculatePolyTerms(xOrder, yOrder);
+    psS32 maxOrder = PS_MAX(xOrder, yOrder);
+
+    // Create the data structure which we hold the xy order of each coeff.
+    psS32 **polyTerms = (psS32 **) psAlloc(localPolyTerms * sizeof(psS32 *));
+    for (i=0; i < localPolyTerms ; i++) {
+        polyTerms[i] = (psS32 *) psAlloc(2 * sizeof(psS32));
+    }
+
+    i=0;
+    // This code segment loops through each term i in the polynomial and
+    // calculates the power to which x/y are raised in that i-th term.
+    // We first do the 0-order terms, then the 1-order terms, etc.
+    for (order=0;order<=maxOrder;order++) {
+        for (num=0;num<=order;num++) {
+            if (((order-num) <= xOrder) && (num <= yOrder)) {
+                polyTerms[i][0] = order-num;
+                polyTerms[i][1] = num;
+                i++;
+            }
+        }
+    }
+
+    if (psTraceGetLevel(".psModule.pmSubtractSky.buildPolyTerms") >= 10) {
+        for (i=0; i < localPolyTerms ; i++) {
+            printf("x^%d * y^%d\n", polyTerms[i][0], polyTerms[i][1]);
+        }
+    }
+
+    return(polyTerms);
+}
+
+/******************************************************************************
+This procedure calculates various combinations of powers of x and y and stores
+them in the data structure p_psPolySums[][].  After it completes:
+ 
+    p_psPolySums[i][j] == x^i * y^j
+ 
+XXX: Use a psImage for the p_psPolySums data structure?
+XXX: Use variable size arrays for p_psPolySums[][].
+XXX: Must initialize p_psPolySums[][]?
+ *****************************************************************************/
+#define PS_MAX_POLYNOMIAL_ORDER 20
+psF64 p_psPolySums[PS_MAX_POLYNOMIAL_ORDER+1][PS_MAX_POLYNOMIAL_ORDER+1];
+void buildSums(psF64 x,
+               psF64 y,
+               psS32 xOrder,
+               psS32 yOrder)
+{
+    psS32 i = 0;
+    psS32 j = 0;
+    psF64 xSum = 0.0;
+    psF64 ySum = 0.0;
+
+    xSum = 1.0;
+    ySum = 1.0;
+    for(i=0;i<=xOrder;i++) {
+        ySum = xSum;
+        for(j=0;j<=yOrder;j++) {
+            p_psPolySums[i][j] = ySum;
+            ySum*= y;
+        }
+        xSum*= x;
+    }
+}
+
+/******************************************************************************
+ImageFitPolynomial(myPoly, dataImage, maskImage): this private routine takes
+an input image along with a mask and fits a polynomial to it.  The degree of
+the polynomial is specified by input parameter myPoly, and need not be
+symmetrical in orders of X and Y.  The polynomial must be type
+PS_POLYNOMIAL_ORD.  If there are not enough rows or columns in the input image
+for the order of the polynomial, then that order is reduced.  The algorithm
+used in this routine is based on that of the pilot project ADD, but is not
+documented anywhere.
+ *****************************************************************************/
+psPolynomial2D *ImageFitPolynomial(psPolynomial2D *myPoly,
+                                   psImage *dataImage,
+                                   psImage *maskImage)
+{
+    psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 4,
+            "---- ImageFitPolynomial() begin ----\n");
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL);
+    PS_IMAGE_CHECK_NULL(dataImage, NULL);
+    PS_IMAGE_CHECK_EMPTY(dataImage, NULL);
+    PS_IMAGE_CHECK_TYPE(dataImage, PS_TYPE_F32, NULL);
+    PS_IMAGE_CHECK_NULL(maskImage, NULL);
+    PS_IMAGE_CHECK_EMPTY(maskImage, NULL);
+    PS_IMAGE_CHECK_TYPE(maskImage, PS_TYPE_U8, NULL);
+    PS_IMAGE_CHECK_SIZE_EQUAL(dataImage, maskImage, NULL);
+    psS32 oldPolyX = -1;
+    psS32 oldPolyY = -1;
+
+    // The matrix equations become singular if there are more powers of X
+    // in myPoly then there are rows of the image.  I think.  Similarly for
+    // powers of Y and columns.  So.  Here we reduce the complexity of the
+    // polynomial if there are not enough rows/columns in the input image.
+
+    if (myPoly->nX > dataImage->numRows) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.\n");
+        oldPolyX = myPoly->nX;
+        myPoly->nX = dataImage->numRows;
+    }
+    if (myPoly->nY > dataImage->numCols) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.\n");
+        oldPolyY = myPoly->nY;
+        myPoly->nY = dataImage->numCols;
+    }
+    psS32 i;
+    psS32 j;
+    psS32 x;
+    psS32 y;
+    psS32 aRow;
+    psS32 aCol;
+    // The myPoly->nX and ->nY terms are actually 1 larger
+    // than the order of the polynomial.
+    psS32 **polyTerms = buildPolyTerms(myPoly->nX-1, myPoly->nY-1);
+    // We determine how many coefficients will be in the polynomial that we
+    // are fitting to this image.
+    psS32 localPolyTerms = CalculatePolyTerms(myPoly->nX-1, myPoly->nY-1);
+    psImage *A = psImageAlloc(localPolyTerms, localPolyTerms, PS_TYPE_F64);
+    psImage *Aout = psImageAlloc(localPolyTerms, localPolyTerms, PS_TYPE_F64);
+    psVector *B = psVectorAlloc(localPolyTerms, PS_TYPE_F64);
+    psVector *outPerm = NULL;
+
+    //
+    // Initialize A matrix and B vector.
+    //
+    PS_IMAGE_SET_F64(A, 0.0);
+    PS_VECTOR_SET_F64(B, 0.0);
+
+    //
+    // We build the A matrix and B vector.
+    //
+    for (x=0;x<dataImage->numRows;x++) {
+        for (y=0;y<dataImage->numCols;y++) {
+            if (maskImage->data.U8[x][y] == 0) {
+                buildSums((psF64) x, (psF64) y, myPoly->nX-1, myPoly->nY-1);
+
+                /************************************************************
+                This code dervies from equation (7) of the pilot ADD.  However,
+                it is not exactly the same in that the order of the polynomial
+                may be different in X And Y.
+
+                Equation (7) from the pilot ADD describes 16 linear equations.
+                The i-th equation is simply the partial derivative of the
+                sky background polynomial (1) w.r.t. to the i-th term in
+                that polynomial.  The i-th equation is stored in row i of
+                matrix A[][] (matrix A[][] has origin (1,1), not (0,0)).  To
+                compute A[i][j] we simply multiply the j-th term of the Sky
+                Background Polynomial (SBP) by the i-th term of SBP.
+                ************************************************************/
+                for (aRow=0;aRow<localPolyTerms;aRow++) {
+                    for (aCol=0;aCol<localPolyTerms;aCol++) {
+                        A->data.F64[aRow][aCol]+=
+                            (p_psPolySums[ polyTerms[aCol][0] ][ polyTerms[aCol][1] ] *
+                             p_psPolySums[ polyTerms[aRow][0] ][ polyTerms[aRow][1] ]);
+                    }
+                }
+                // Build the B[] vector, which is the right-hand side of (7).
+                for (i=0;i<localPolyTerms;i++) {
+                    B->data.F64[i]+= dataImage->data.F32[x][y] *
+                                     p_psPolySums[ polyTerms[i][0] ][ polyTerms[i][1] ];
+                }
+            }
+        }
+    }
+
+    if (psTraceGetLevel(".psModule.pmSubtractSky.ImageFitPolynomial") >= 8) {
+        for (aRow=0;aRow<localPolyTerms;aRow++) {
+            for (aCol=0;aCol<localPolyTerms;aCol++) {
+                printf("A[%d][%d] is %f\n", aRow, aCol,
+                       A->data.F64[aRow][aCol]);
+            }
+        }
+
+        for (i=0;i<=localPolyTerms;i++) {
+            printf("B[%d] is %f\n", i, B->data.F64[i]);
+        }
+    }
+
+    //
+    // Solve the matrix equations for the polynomial coefficients C.
+    // XXX: How do we know if these matrix operations were successful?
+    //
+    Aout = psMatrixLUD(Aout, &outPerm, A);
+    PS_IMAGE_CHECK_NULL(Aout, NULL);
+    PS_IMAGE_CHECK_EMPTY(Aout, NULL);
+    psVector *C = psVectorAlloc(localPolyTerms, PS_TYPE_F64);
+    psMatrixLUSolve(C, Aout, B, outPerm);
+
+    //
+    // Set the appropriate coefficients in the myPoly structure.
+    //
+    for (i=0;i<localPolyTerms;i++) {
+        myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ] = C->data.F64[i];
+        psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 6,
+                "myPoly->coeff[%d][%d] is %f\n", polyTerms[i][0], polyTerms[i][1], myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ]);
+    }
+
+    //
+    // Free data structures that were allocated in this module.
+    //
+    for (i=0;i<localPolyTerms;i++) {
+        psFree(polyTerms[i]);
+    }
+    psFree(polyTerms);
+    psFree(A);
+    psFree(Aout);
+    psFree(B);
+    psFree(C);
+    psFree(outPerm);
+
+    //
+    // We restore the original size of the polynomial and set remaining
+    // coefficients to 0.0, if necessary.
+    //
+    if (oldPolyX != -1) {
+        myPoly->nX = oldPolyX;
+        for (i=oldPolyX ; i < myPoly->nX ; i++) {
+            for (j=0;j<myPoly->nY ; j++) {
+                myPoly->coeff[i][j] = 0.0;
+            }
+        }
+    }
+    if (oldPolyY != -1) {
+        myPoly->nY = oldPolyY;
+        for (i=0 ; i < myPoly->nX ; i++) {
+            for (j=oldPolyY;j<myPoly->nY ; j++) {
+                myPoly->coeff[i][j] = 0.0;
+            }
+        }
+    }
+
+    psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 4,
+            "---- ImageFitPolynomial() end successfully ----\n");
+    return(myPoly);
+}
+
+
+/******************************************************************************
+psReadout pmSubtractSky():
+ 
+XXX: use static vectors for myStats, and the binned image
+ 
+XXX: The SDR is silent about types.  PS_TYPE_F32 is implemented here.
+ *****************************************************************************/
+psReadout *pmSubtractSky(psReadout *in,
+                         void *fitSpec,
+                         psFit fit,
+                         psS32 binFactor,
+                         psStats *stats,
+                         psF32 clipSD)
+{
+    PS_READOUT_CHECK_NULL(in, NULL);
+    PS_READOUT_CHECK_EMPTY(in, NULL);
+    PS_READOUT_CHECK_TYPE(in, PS_TYPE_F32, NULL);
+    psTrace(".psModule.pmSubtractSky", 4,
+            "---- pmSubtractSky() begin ----\n");
+
+    if ((fit != PM_FIT_NONE) &&
+            (fit != PM_FIT_POLYNOMIAL) &&
+            (fit != PM_FIT_SPLINE)) {
+        psError(PS_ERR_UNKNOWN, true, "psFit is unallowable (%d).  Returning in image.\n", fit);
+        return(in);
+    }
+
+    psStatsOptions statOptions = 0;
+
+    //
+    // Return the original input readout if the fit specs are poorly defined.
+    // No warning or error messages should be generated.
+    //
+    if ((fitSpec == NULL) ||
+            ((fit == PM_FIT_NONE) || (fit == PM_FIT_SPLINE))) {
+        //        psLogMsg(__func__, PS_LOG_WARN, "Fit specs are poorly defined.  Returning in image.\n");
+        return(in);
+    }
+    psImage *origImage = in->image;
+    psImage *binnedImage = NULL;
+    psPolynomial2D *myPoly = NULL;
+    psImage *binnedMaskImage = NULL;
+    psU32 oldStatOptions = 0;
+
+    //
+    // Determine which statistic to use when binning pixels, if any.
+    //
+    if (stats != NULL) {
+        statOptions = stats->options;
+        if (1 < p_psDetermineNumBits(statOptions)) {
+            psLogMsg(__func__, PS_LOG_WARN, "WARNING: Multiple statistical options have been requested.\n");
+            statOptions = getHighestPriorityStatOption(statOptions);
+            if (statOptions == -1) {
+                psError(PS_ERR_UNKNOWN, true, "Not allowable stats->option was specified.  Returning in image.\n");
+                return(in);
+            }
+            // Save old input "stats" parameter.
+            oldStatOptions = stats->options;
+            stats->options = statOptions;
+        }
+        if (0 == p_psDetermineNumBits(statOptions)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractSky(): no stats->options was requested\n");
+        }
+    }
+
+    //
+    // Generate required warning messages.
+    //
+    if (binFactor <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): binFactor is %d\n", binFactor);
+    }
+    if (stats == NULL) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): input parameter stats is NULL\n");
+    }
+
+    //
+    // Bin the input image according to input parameters.
+    // Create a new binned image mask.
+    //
+    if ((binFactor <= 1) || (stats == NULL) || (0 == p_psDetermineNumBits(statOptions))) {
+        // No binning is required here.  Simply create a copy of the image
+        // and a mask.
+        binnedImage = psImageCopy(binnedImage, origImage, PS_TYPE_F32);
+        if (binnedImage == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageCopy() returned NULL.  Returning in image.\n");
+            return(in);
+        }
+
+        if (in->mask != NULL) {
+            binnedMaskImage = psImageCopy(binnedMaskImage, in->mask, PS_TYPE_U8);
+            if (binnedMaskImage == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageCopy() returned NULL.  Returning in image.\n");
+                psFree(binnedImage);
+                return(in);
+            }
+        } else {
+            binnedMaskImage = psImageAlloc(binnedImage->numCols,
+                                           binnedImage->numRows,
+                                           PS_TYPE_U8);
+            PS_IMAGE_SET_U8(binnedMaskImage, 0);
+        }
+    } else {
+        binnedImage = psImageRebin(NULL, origImage, in->mask, 0, binFactor, stats);
+        if (binnedImage == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageRebin() returned NULL.  Returning in image.\n");
+            return(in);
+        }
+        binnedMaskImage = psImageAlloc(binnedImage->numCols,
+                                       binnedImage->numRows,
+                                       PS_TYPE_U8);
+        PS_IMAGE_SET_U8(binnedMaskImage, 0);
+    }
+    psTrace(".psModule.pmSubtractSky", 4,
+            "binnedImage size is (%d, %d)\n", binnedImage->numRows, binnedImage->numCols);
+
+    //
+    // Clip pixels that are outside the acceptable range.
+    //
+    if (clipSD <= 0.0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD);
+    } else {
+        // Determine the mean and standard deviation of the binned image.
+        psF64 binnedMean;
+        psF64 binnedStdev;
+        psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        psStats *rc =  psImageStats(myStats, binnedImage, NULL, 0);
+        if (rc == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        if (false == p_psGetStatValue(rc, &binnedMean)) {
+            psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        psTrace(".psModule.pmSubtractSky", 6,
+                "binned Mean is %f\n", binnedMean);
+
+        myStats->options = PS_STAT_SAMPLE_STDEV;
+        rc =  psImageStats(myStats, binnedImage, NULL, 0);
+        if (rc == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        if (false == p_psGetStatValue(myStats, &binnedStdev)) {
+            psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        psFree(myStats);
+        psTrace(".psModule.pmSubtractSky", 6,
+                "binned StDev is %f\n", binnedStdev);
+
+        // Clip all pixels which are more than clipSD sigmas from the mean.
+        psTrace(".psModule.pmSubtractSky", 6,
+                "clipSD is %f\n", clipSD);
+
+        for (psS32 row = 0; row < binnedImage->numRows ; row++) {
+            for (psS32 col = 0; col < binnedImage->numCols ; col++) {
+                if (fabs(binnedImage->data.F32[row][col] - binnedMean) >
+                        (clipSD * binnedStdev)) {
+                    binnedMaskImage->data.U8[row][col] = 1;
+                }
+            }
+        }
+    }
+
+    //
+    // Fit the polynomial to the binned image
+    //
+    if (fit == PM_FIT_POLYNOMIAL) {
+        myPoly = (psPolynomial2D *) fitSpec;
+        PS_POLY_CHECK_NULL(myPoly, NULL);
+        PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL);
+
+        myPoly = ImageFitPolynomial(myPoly, binnedImage, binnedMaskImage);
+
+        if (myPoly != NULL) {
+            // Set the pixels in the binned image to that of the polynomial.
+            binnedImage = psImageEvalPolynomial(binnedImage, myPoly);
+            if (binnedImage == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageEvalPolynomial() returned NULL.  Returning in image.\n");
+                psFree(binnedMaskImage);
+                if (!((binFactor <= 1) || (stats == NULL))) {
+                    psFree(binnedImage);
+                }
+                if (oldStatOptions != 0) {
+                    stats->options = statOptions;
+                }
+                return(in);
+            }
+        } else {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractSky(): could not model sky with a polynomial.\n");
+            psFree(binnedMaskImage);
+            if (!((binFactor <= 1) || (stats == NULL))) {
+                psFree(binnedImage);
+            }
+            if (oldStatOptions != 0) {
+                stats->options = statOptions;
+            }
+            return(in);
+        }
+    } else {
+        // We shouldn't get here since we check this above.
+        psError(PS_ERR_UNKNOWN, true, "Unallowable fit type.  Returning in image.\n");
+        psFree(binnedMaskImage);
+        if (!((binFactor <= 1) || (stats == NULL))) {
+            psFree(binnedImage);
+        }
+        if (oldStatOptions != 0) {
+            stats->options = statOptions;
+        }
+        return(in);
+    }
+
+    //
+    //Subtract the polynomially fitted image from the original image
+    //
+    if (binFactor <= 1) {
+        // The binned image is the same size as the original image.
+        for (psS32 row = 0; row < origImage->numRows ; row++) {
+            for (psS32 col = 0; col < origImage->numCols ; col++) {
+                origImage->data.F32[row][col]-= binnedImage->data.F32[row][col];
+            }
+        }
+    } else {
+        for (psS32 row = 0; row < origImage->numRows ; row++) {
+            for (psS32 col = 0; col < origImage->numCols ; col++) {
+                // We calculate the F32 value of the pixel coordinates in the
+                // binned image and then use a pixel interpolation routine to
+                // determine the value of the pixel at that location.
+                psF32 binRowF64 = ((psF32) row) / ((psF32) binFactor);
+                psF32 binColF64 = ((psF32) col) / ((psF32) binFactor);
+
+                // We add 0.5 to the pixel locations since the pixel
+                // interpolation routine defines the location of pixel
+                // (i, j) as (i+0.5, j+0.5).
+                binRowF64+= 0.5;
+                binColF64+= 0.5;
+
+                psF32 binPixel = (psF32) psImagePixelInterpolate(
+                                     binnedImage, binColF64, binRowF64,
+                                     NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+                origImage->data.F32[row][col]-= binPixel;
+
+                psTrace(".psModule.pmSubtractSky", 8,
+                        "image[%d][%d] <--> binnedImage[%.2f][%.2f]: %f\n",
+                        row, col, binRowF64-0.5, binColF64-0.5, binPixel);
+            }
+        }
+
+    }
+    psFree(binnedMaskImage);
+    psFree(binnedImage);
+    if (oldStatOptions != 0) {
+        stats->options = statOptions;
+    }
+
+    psTrace(".psModule.pmSubtractSky", 4,
+            "---- pmSubtractSky() exit successfully ----\n");
+    return(in);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/pmSubtractSky.h	(revision 22108)
@@ -0,0 +1,39 @@
+/** @file  pmSubtractSky.h
+ *
+ *  This file will contain a module which will create a model of the
+ *  background sky and subtract that from the input image.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-06 19:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_SUBTRACT_SKY_H)
+#define PM_SUBTRACT_SKY_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+
+// XXX: this is pmFit in pmSubtractBias.c, named psFit here.
+typedef enum {
+    PM_FIT_NONE,                              ///< No fit
+    PM_FIT_POLYNOMIAL,                        ///< Fit polynomial
+    PM_FIT_SPLINE                             ///< Fit cubic splines
+} psFit;
+
+psReadout *pmSubtractSky(psReadout *in,
+                         void *fitSpec,
+                         psFit fit,
+                         int binFactor,
+                         psStats *stats,
+                         float clipSD);
+#endif
Index: /tags/ipp-1-X/rel5_1/psModules/src/psErrorCodes.dat
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/src/psErrorCodes.dat	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/src/psErrorCodes.dat	(revision 22108)
@@ -0,0 +1,18 @@
+#
+#  This file is used to generate psErrorCode.h content
+#
+# Format:
+#    ERROR_CLASS_NAME    ERROR_CLASS_DESCRIPTION
+#
+# Note: the ERROR_CLASS_NAME will appear in the code with a "PS_ERR_" prefix
+#
+UNKNOWN                        unknown error
+IO                             I/O error
+LOCATION_INVALID               specified location is unknown
+MEMORY_CORRUPTION              memory corruption detected
+MEMORY_DEREF_USAGE             dereferenced memory still used
+BAD_PARAMETER_VALUE            parameter is out-of-range
+BAD_PARAMETER_TYPE             parameter is of unsupported type
+BAD_PARAMETER_NULL             parameter is null
+BAD_PARAMETER_SIZE             size of parameter's data is outside of acceptable range.
+UNEXPECTED_NULL                unexpected NULL found
Index: /tags/ipp-1-X/rel5_1/psModules/templates/c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/templates/c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/templates/c	(revision 22108)
@@ -0,0 +1,11 @@
+/** @file  filename.c
+ *
+ *  @brief Contains the definitions for ...
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1.1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-10 19:01:33 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
Index: /tags/ipp-1-X/rel5_1/psModules/templates/h
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/templates/h	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/templates/h	(revision 22108)
@@ -0,0 +1,13 @@
+/** @file  filename.h
+ *
+ *  @brief Contains the definitions for ...
+ *
+ *  Detailed Description goes here.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1.1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-10 19:01:33 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
Index: /tags/ipp-1-X/rel5_1/psModules/test/.cvsignore
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/.cvsignore	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/.cvsignore	(revision 22108)
@@ -0,0 +1,13 @@
+.deps
+.libs
+Makefile
+tst_pmFlatField
+tst_pmMaskBadPixels
+tst_pmNonLinear
+tst_pmSubtractBias
+temp
+Makefile.in
+tst_pmObjects01
+tst_pmReadoutCombine
+tst_pmSubtractSky
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/FullUnitTest
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/FullUnitTest	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/FullUnitTest	(revision 22108)
@@ -0,0 +1,703 @@
+#!/usr/bin/perl
+#
+#  This is a perl script test harness which will recursively search the
+#  directory tree looking for files named UnitTest and then execute
+#  the script
+#
+#  SYNOSIS :  FullUnitTest options arguements
+#
+#       where  options =
+#             --verbose     Display extra information to user
+#             --noverbose   Don't display extra information to user
+#             --recursiv e  Recursively run tests in directory tree
+#             --norecursive Test only the specified or current directory
+#             --silent      Don't display any information to user
+#             --nosilent    Display progress of script to user
+#
+#              arguements = directory(ies) to perform tests
+#
+#  RETURN : integer number of tests which failed
+#
+#  $Revision: 1.2 $  $Name: not supported by cvs2svn $
+#  $Date: 2005-04-01 20:11:19 $
+#
+#  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+#
+##############################################################################
+
+# Provide functions for determining the pathname of current working directory
+use Cwd;
+
+# Provides functions for handling psS64 command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+# The ! option allows for --nooption to be set to zero
+# (e.g. --noverbose --recursive causes $verbose=0 and $recursive=1)
+GetOptions(
+    "verbose!"   => \$verbose,
+    "recursive!" => \$recursive,
+    "silent!"    => \$silent,
+    "clean!"     => \$clean
+);
+
+# Check if both silent and verbose options are set and if so stop the script
+die "Can't specify both verbose and silent options." if ( $verbose && $silent );
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have
+if ( !$ENV{'PSLIB_ROOT'} ) {
+
+    # Use the directory directly above where FullUnitTest script resides
+    $PSLIB_ROOT = `cd ..;pwd`;
+
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT.\n") if $verbose;
+}
+
+# add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment
+# variables
+$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/src/.libs:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/src/.libs:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Initialize variables for counting the makes and test failures and the
+# total makes and tests performed
+$makeFailCount       = 0;
+$testpointFailCount  = 0;
+$testDriverFailCount = 0;
+$totalTestpoints     = 0;
+$totalTestDrivers    = 0;
+$totalMakes          = 0;
+
+# Initialize variable indicating how many arguements were passed
+$args = 0;
+
+# Loop through all the arguements passed to the script
+foreach (@ARGV) {
+
+    # Remove newline if there is one
+    chomp;
+
+    # Increment number of arguements found
+    $args++;
+
+    # Set variable to current working directory
+    $cwd = cwd;
+
+    # Change directory to the directory of the arguement
+    chdir($_);
+
+    # Check for the recursive option
+    if ($recursive) {
+
+        # Invoke subroutine to go to the lowest directory in tree
+        # starting at the specified directory
+        &worm($_);
+    }
+    else {
+
+        # Invoke subroutines to run the test at the specified directory
+        &makeTestDrivers($_);
+        &executeTestDrivers($_);
+    }
+
+    # Change directory back to the directory where FullUnitTest was invoked
+    chdir($cwd);
+}
+
+# Check if there were no arguements specified
+if ( $args == 0 ) {
+
+    # Display message to user that all directories under the current will be
+    # tested
+    print("Recursively testing current directory tree.\n") if $verbose;
+
+    # Invoke subroutine to go to recursively test each directory in tree
+    &worm( $ENV{"PWD"} );
+}
+
+# Check if there were any failures during make or testing
+if ( $makeFailCount > 0 || $testDriverFailCount > 0 ) {
+
+    # Display summary of failures
+    print("\nMake Failures = $makeFailCount out of $totalMakes");
+    print(
+"\nTest Driver Failures = $testDriverFailCount out of $totalTestDrivers\n"
+    );
+    print( "\nMakes that failed:\n  " . join( "\n  ", @makesFailed ) . "\n" )
+      if $makeFailCount;
+    print( "\nTests that failed:\n  " . join( "\n  ", @testsFailed ) . "\n" )
+      if $testDriverFailCount;
+}
+else {
+
+    # Display message of all makes and tests pass to user if silent option
+    # not specified
+    print(
+"\nAll $totalTestDrivers Test Drivers Passed with $totalTestpoints Testpoints.\n"
+      )
+      if ( !$silent );
+}
+
+# Exit with the number of tests that failed
+exit($testDriverFailCount);
+
+################################################################################
+#
+# SUBROUTINE: worm
+#
+#     Description:  This subroutine will perform the necessary unit tests be
+#                   calling makeTestDrivers and executeTestDrivers  subroutines
+#                   and then check each subdirectory below the base directory
+#                   recursively.
+#
+#     Parameter(s):  base directory to start testing
+#
+#     Return:  None
+#
+################################################################################
+
+sub worm {
+
+    # Assign local variable to input parameter
+    local ($base_dir) = @_;
+    local ( @files, $i );
+
+    # Invoke subroutine to make test driver in the base directory
+    &makeTestDrivers($base_dir);
+
+    # Invoke subroutine to execute tests in the base directory
+    &executeTestDrivers($base_dir);
+
+    # Create array of entries found in directory
+    @files = <*>;
+
+    # Loop through the file list looking for another directory that is not
+    # labelled CVS and recursively invoke subroutine worm
+    $i = 0;
+    while ( $files[$i] ) {
+
+        # Check for directory and directory not labelled CVS
+        if (   -d $files[$i]
+            && ( $files[$i] ne "CVS" )
+            && ( $files[$i] ne "temp" )
+            && ( $files[$i] ne "verified" ) )
+        {
+
+            # Change current directory to directory found
+            chdir( $files[$i] );
+
+            # Invoke subroutine worm again
+            &worm( $files[$i] );
+
+            # Change current directory back to parent
+            chdir("..");
+        }
+
+        # Increment file list index
+        $i++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: makeTestDrivers
+#
+#      Description:  This subroutine will perform a make for all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+#      Return:  None
+#
+################################################################################
+
+sub makeTestDrivers {
+    local ($base_dir) = @_;
+    local ($pwd);
+
+    # Set variable pwd to current working directory
+    $pwd = cwd;
+
+    # Display message to user in which directory testing is taken place only
+    # if the silent command option was not specified
+    print("---- Entering $pwd ----\n") if ( !$silent );
+
+    # Check for the existence of a file name Makefile in current directory
+    if ( -e "Makefile" ) {
+
+        # Increment the total number of makes executed
+        $totalMakes++;
+
+        if ($clean) {
+
+            # Execute the make clean
+            `make clean`;
+
+        }
+
+        # Execute the make and save results
+        $_ = join( "\n|| ", split( "\n", "\n" . `make tests` ) );
+
+        # Check the output of make for return value != 0 or any of the
+        # following words: FAILED, FAULT, ERROR, Not found, SIGNAL
+        if ( $? != 0 ) {
+
+            # Display the errored output of make if silent option not enabled
+            print("$_\n") if ( !$silent );
+
+            # Display the make failed in the current directory
+            print("\nMake for $pwd Failed\n");
+
+            # Increment the number of makes that have failed
+            $makeFailCount++;
+
+            # Push the current working directory onto the list of failed
+            # make directories list
+            push( @makesFailed, $pwd );
+        }
+        else {
+
+            # Display the results of the successful make if verbose option set
+            print("$_\n") if $verbose;
+
+            # Display the make was successful if silent option not set
+            print("\nMake successful.\n") if ( !$silent );
+        }
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: executeTestDrivers
+#
+#      Description:  This subroutine will execute all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+################################################################################
+
+sub executeTestDrivers {
+    local ($base_dir) = @_;
+    local ( @files, $j );
+    local ($pwd);
+    local ($exitValue) = 0;
+
+    # Set variable to pwd to current test directory
+    $pwd = cwd;
+
+    # Create a list of all elements in base directory
+    @files = <*>;
+
+    # Loop through all the items in the files array
+    $initialTest = 0;
+    $j           = 0;
+    while ( $files[$j] ) {
+
+        # Check that the item is not a directory and is executable and
+        # conforms to the test driver naming convention TST
+        if (   !( -d $files[$j] )
+            && ( -x $files[$j] )
+            && ( $files[$j] =~ /^TST/i || $files[$j] =~ /^ATST/i ) )
+        {
+
+            # Increment total number of test drivers executed
+            $totalTestDrivers++;
+
+            # Perform subdirectory checks only the first time a test
+            # file is found with the list of enteries
+            if ( $initialTest == 0 ) {
+                $initialTest++;
+
+                # Check for a temp subdirectory already exists and if not
+                # then create one
+                &checkForTempDirectory();
+
+                # Check for the presence of verified directory
+                if ( &checkForVerifiedDirectory() ) {
+
+    # Display message to user that verified directories do not
+    # exist eventhough TST files have been found
+    #                    print("Unable to execute test drivers in $base_dir\n");
+                    print("No verified subdirectory present.\n") if ($verbose);
+
+               # Increment test fail count
+               #                   $testDriverFailCount++;
+               # Save the file failed
+               #                    push(@testsFailed, $pwd . "/" . $files[$j]);
+               #                    return;
+                }
+            }
+
+            # Display message to user of which test driver is being executed
+            print("--- Executing test driver $files[$j]\n") if ( !$silent );
+
+            # Execute the test driver
+            system(
+"./$files[$j] 1> temp/$files[$j].stdout 2> temp/$files[$j].stderr"
+            );
+            $retVal = $?;
+
+            # Count testpoints
+            $testPattern = "\"\\*\\*\\*\\* TESTPOINT \\*\\*\\*\\*\"";
+            $totalPoints = `grep -c $testPattern temp/$files[$j].stdout`;
+            $totalPoints += `grep -c $testPattern temp/$files[$j].stderr`;
+            $failPoints =
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stdout | wc -l`;
+            $failPoints +=
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stderr | wc -l`;
+            $testpointFailCount += $failPoints;
+            $totalTestpoints    += $totalPoints;
+
+            # Check result of test driver
+            if (   ( ( $retVal != 0 ) && ( $files[$j] =~ /^TST/i ) )
+                || ( ( $retVal == 0 ) && ( $files[$j] =~ /^ATST/i ) ) )
+            {
+
+                # Display test driver failed
+                $failPoints++;
+                print(
+                    "Test driver: $files[$j] Failed (Return value $retVal).\n");
+
+                # Increment the total number of test failed
+                $testDriverFailCount++;
+
+                # Push the current working directory on the list of failed
+                push( @testsFailed, $pwd . "/" . $files[$j] );
+            }
+            else {
+
+               # Create filter versions of STDOUT and STDERR to replace variable
+               # items such as date, time and host
+                &filterStdFiles( $files[$j] );
+
+                # Perform difference on STDOUT file collected
+                # with verified files
+                $exitValue = &compareStream("verified/$files[$j].stdout");
+                if ( $exitValue & 2 ) {
+
+                    # STDOUT verified doesn't exist. Search STDOUT capture
+                    # for strings indicating error or failure
+                    $exitValue |= &errorStrSearch("$files[$j].stdout");
+                }
+                if ( ( $exitValue & 8 ) || ( $exitValue & 64 ) ) {
+
+                    # Increment the total number of test failed
+                    $testDriverFailCount++;
+
+                    # Push test on failed list
+                    print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                      )
+                      if ( !$silent );
+                    push( @testsFailed, $pwd . "/" . $files[$j] );
+                }
+                else {
+
+                    # Perform difference on STDERR file collection with verified
+                    $exitValue = &compareStream("verified/$files[$j].stderr");
+                    if ( $exitValue & 4 ) {
+
+                        # STDERR verified doesn't exist. Search STDERR capture
+                        # for strings indicating error or failure
+                        $exitValue |= &errorStrSearch("$files[$j].stderr");
+                    }
+                    if ( ( $exitValue & 16 ) || ( $exitValue & 128 ) ) {
+
+                        # Increment the total number of tests failed
+                        $testDriverFailCount++;
+
+                        # Push test on failed list
+                        print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                          )
+                          if ( !$silent );
+                        push( @testsFailed, $pwd . "/" . $files[$j] );
+                    }
+                    else {
+                        print("Test successful ($totalPoints testpoints)\n")
+                          if ( !$silent );
+                    }
+                }
+            }
+        }
+        $j++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            print;
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile ) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n") if ($verbose);
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        }
+        elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    }
+    else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForTempDirectory
+#
+#      Description:  This subroutine will check for the existence of a temp
+#                    directory to store STDOUT, STDERR files during test.  If
+#                    the subdirectory doesn't exist, it will be created.
+#
+#      Parameter(s):  None
+#
+#      Return: None
+#
+################################################################################
+
+sub checkForTempDirectory {
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n") if ($verbose);
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForVerifiedDirectory
+#
+#      Description:  This subroutine will check for the existence of a verified
+#                    directory which stores verified STDOUT, STDERR files for
+#                    comparison during the test.
+#
+#      Parameter(s):  None
+#
+#      Return: 0 - subdirectory present
+#              1 - subdirectory not present
+#
+################################################################################
+
+sub checkForVerifiedDirectory {
+    $returnValue = 0;
+
+    # Check if verified subdirectory exists in the current working directory
+    if ( !( -e "verified" ) ) {
+
+        # Set return value to 1
+        $returnValue = 1;
+    }
+    return ($returnValue);
+}
+
+################################################################################
+#
+#  SUBROUTINE: filterStdFiles
+#
+#      Description:  This subroutine will filter variable items in the STDOUT
+#                    and STDERR files captured.  Date, time and host names
+#                    are variable items in the log messages captured.
+#
+#      Parameter(s):  test file name
+#
+#      Return: None
+#
+################################################################################
+
+sub filterStdFiles {
+
+    local ($fileName) = @_;
+
+    # Open the STDOUT file for reading
+    open( OUTFILE, "< temp/$fileName.stdout" );
+
+    # Open mod file to place filtered STDOUT
+    open( MODFILE, "> temp/$fileName.stdout.mod" );
+
+    # Replace the variable data, time and host information with constants
+    $hostname = `hostname`;
+    chop $hostname;
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\(.*\:\d+\)/\(FILE\:LINENO\)/g;
+        s/\s+[\_\-\/\.\w]+\:\d+/ FILE\:LINENO/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+        s/v\d+.\d+.\d+/vX.X.X/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+
+    # Open the STDERR file for reading
+    open( OUTFILE, "< temp/$fileName.stderr" );
+
+    # Open mod file to place filtered STDERR
+    open( MODFILE, "> temp/$fileName.stderr.mod" );
+
+    # Replace the variable date, time and host information with constants
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\(.*\:\d+\)/\(FILE\:LINENO\)/g;
+        s/\s+[\_\-\/\.\w]+\:\d+/ FILE\:LINENO/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+        s/v\d+.\d+.\d+/vX.X.X/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+}
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/Makefile.am
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/Makefile.am	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/Makefile.am	(revision 22108)
@@ -0,0 +1,32 @@
+# Makefile for psModule tests
+
+AM_LDFLAGS = -L$(top_builddir)/src -lpsmodule $(LDFLAGS)
+AM_CFLAGS = -I$(top_srcdir)/src
+
+TESTS = tst_pmFlatField \
+	tst_pmMaskBadPixels \
+	tst_pmNonLinear \
+	tst_pmSubtractBias \
+	tst_pmReadoutCombine \
+	tst_pmSubtractSky \
+	tst_pmObjects01
+
+check_PROGRAMS = $(TESTS)
+
+TESTS_ENVIRONMENT = perl $(top_srcdir)/test/runTest --verified=$(srcdir)/verified
+
+tests: $(TESTS)
+
+EXTRA_DIST = runTest verified
+
+CLEANFILES = $(TESTS) temp/*
+
+tst_pmFlatField_SOURCES = tst_pmFlatField.c
+tst_pmMaskBadPixels_SOURCES = tst_pmMaskBadPixels.c
+tst_pmNonLinear_SOURCES = tst_pmNonLinear.c
+tst_pmSubtractBias_SOURCES = tst_pmSubtractBias.c
+tst_pmReadoutCombine_SOURCES = tst_pmReadoutCombine.c
+tst_pmSubtractSky_SOURCES = tst_pmSubtractSky.c
+tst_pmObjects01_SOURCES = tst_pmObjects01.c
+
+test: check
Index: /tags/ipp-1-X/rel5_1/psModules/test/runTest
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/runTest	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/runTest	(revision 22108)
@@ -0,0 +1,358 @@
+#!/usr/bin/perl
+#
+#  This is a perl script to execute a single test driver program.  The script
+#  will examine the return value of the test driver and capture STDOUT, STDERR
+#  to files.  If the return value of the test driver is not zero, the test is
+#  deemed a failure.  STDOUT and STDERR files will be place in a subdirectory
+#  named temp and the files will be compared with verified STDOUT, STDERR files
+#  in a subdirectory named verified.  If there are no STDOUT, STDERR files in
+#  the verified directory, the captured STDOUT, STDERR files will be scanned
+#  for words which indicate a failure.
+#
+#  Assumptions:  A verified subdirectory with STDOUT, STDERR files exists for
+#                the test driver specified in the arguements if an exact
+#                match of the streams STDOUT, STDERR is necessary.
+#
+#  Return values:
+#                 Bit mapped values
+#                 0    Test run successfull and all tests passed
+#                 1    Verified directory did not exist
+#                 8    STDOUT files did not compare
+#                16    STDERR files did not compare
+#                32    Test driver doesn't exist or is not executable
+#                64    Test driver did not return zero
+#
+#  SYNOSIS:  runTest testDriverName
+#
+#  $Revison:  $  $Name: not supported by cvs2svn $
+#  $Date: 2005-04-01 21:52:22 $
+#
+#  Copyright 2004 Maui High Performance Computering Center, University of Hawaii
+#
+################################################################################
+
+# Provides functions for handling psS64 command line options
+use Getopt::Long;
+
+$verifiedDir = "verified";
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "reset!"       => \$reset,
+    "resetStderr!" => \$resetStderr,
+    "resetStdout!" => \$resetStdout,
+    "verified=s"   => \$verifiedDir,
+    "help!"        => \$help
+);
+
+if ($help || $#ARGV < 0) {
+    print
+"Usage: runTest [--reset] [--resetStderr] [--resetStdout] [--verified=DIR] testfile(s)\n\n";
+    exit(0);
+}
+
+if ($reset) {
+    $resetStderr = 1;
+    $resetStdout = 1;
+}
+
+# Initialize exit value
+$exitValue = 0;
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have it set
+if ( $ENV{'PSLIB_ROOT'} ) {
+
+	# Add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment vars
+	$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/src/.libs:$ENV{'LD_LIBRARY_PATH'}";
+	$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/src/.libs:$ENV{'DYLD_LIBRARY_PATH'}";
+}
+
+# Loop through the arguements passed to the script
+foreach (@ARGV) {
+    chomp;
+    $testFile = $_;
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test run
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n");
+    }
+
+    # Check if a verified directory exists in the current work directory
+    if ( !( -e $verifiedDir ) ) {
+
+        # Display message that verified subdirectory doesn't exist
+        print("        Verified directory doesn't exist.\n");
+
+        # Exit script since the test cannot be run with verified files
+        $exitValue = 1;
+    }
+
+    # Check if the test driver file exists and is executable
+    if ( ( -e $testFile ) && ( -x $testFile ) ) {
+
+        # Display message the test driver is being executed
+        print("--- Executing test driver: $testFile\n");
+
+        # Invoke the test driver
+        system("./$testFile 1> temp/$testFile.stdout 2> temp/$testFile.stderr");
+
+        # Check the return value of the test driver.  A value other than 0
+        # indicates failure of the test driver unless the test driver is name
+        # with a leading 'a' which indicates the test driver is expecting an
+        # abort condition to terminate the driver.
+        if (   ( $? != 0 && ( $testFile !~ /^A/i ) )
+            || ( $? == 0 && ( $testFile =~ /^A/i ) ) )
+        {
+
+            # Display failure message with return value to user
+            if ( $? != 0 && ( $testFile !~ /^A/i ) ) {
+                print("Failed - Test Driver returned $?, expected 0.\n");
+            }
+            elsif ( $? == 0 && ( $testFile =~ /^A/i ) ) {
+                print("Failed - Test Driver returned $?, expected abort.\n");
+            }
+            $exitValue |= 64;
+        }
+
+        # Test driver succeeded.
+
+        # Create filtered version of stdout and stderr
+
+        # Open the STDOUT file for reading
+        open( OUTFILE, "< temp/$testFile.stdout" );
+
+        # Open mod file to place filtered STDOUT
+        open( MODFILE,  "> temp/$testFile.stdout.mod" );
+        open( MODFILE2, "> $verifiedDir/$testFile.stdout" ) if $resetStdout;
+
+        # Replace the variable date, time and host information with constants
+        $hostname = `hostname`;
+        chop $hostname;
+        while (<OUTFILE>) {
+            s/\s+\d+:\d+:\d+\w/<TIME>/g;
+            s/\d+:\d+:\d+/<DATE>/g;
+            s/$hostname\s*/<HOST>/g;
+            s/: Line \d+/: Line <LINENO>/g;
+            s/\(.*\:\d+\)/\(FILE\:LINENO\)/g;
+            s/\s+[\_\-\/\.\w]+\:\d+/ FILE\:LINENO/g;
+            s/allocate \d+ bytes at/allocate <N> bytes at/g;
+            s/v\d+.\d+.\d+/vX.X.X/g;
+
+            # Filter lines with malloc.  This is an artifact of memory testing
+            # with the Mac testbed
+            if ( !m/\*\*\*\smalloc/ ) {
+                print MODFILE ($_);
+                print MODFILE2 ($_) if $resetStdout;
+            }
+        }
+
+        # Close mod file
+        close(MODFILE);
+        close(MODFILE2) if $resetStdout;
+
+        # Close STDERR file
+        close(OUTFILE);
+
+        # Open the STDERR file for reading
+        open( OUTFILE, "< temp/$testFile.stderr" );
+
+        # Open mod file to place filtered STDERR
+        open( MODFILE,  "> temp/$testFile.stderr.mod" );
+        open( MODFILE2, "> $verifiedDir/$testFile.stderr" ) if $resetStderr;
+
+        # Replace the variable date, time and host information with constants
+        while (<OUTFILE>) {
+            s/\s+\d+:\d+:\d+\w/<TIME>/g;
+            s/\d+:\d+:\d+/<DATE>/g;
+            s/$hostname\s*/<HOST>/g;
+            s/: Line \d+/: Line <LINENO>/g;
+            s/\(.*\:\d+\)/\(FILE\:LINENO\)/g;
+            s/\s+[\_\-\/\.\w]+\:\d+/ FILE\:LINENO/g;
+            s/allocate \d+ bytes at/allocate <N> bytes at/g;
+            s/v\d+.\d+.\d+/vX.X.X/g;
+
+            # Filter lines with malloc.  This is an artifact of memory testing
+            # with the Mac testbed
+            if ( !m/\*\*\*\smalloc/ ) {
+                print MODFILE ($_);
+                print MODFILE2 ($_) if $resetStderr;
+            }
+        }
+
+        # Close mod file
+        close(MODFILE);
+        close(MODFILE2) if $resetStderr;
+
+        # Close STDERR file
+        close(OUTFILE);
+
+        # Compare STDOUT capture with verified file
+        $exitValue |= &compareStream("$verifiedDir/$testFile.stdout");
+
+        # Check exit value to determine if verified file doesn't exist
+        if ( $exitValue & 2 ) {
+
+            # STDOUT verified doesn't exist.  Search STDOUT capture
+            # for strings indicating error or failure
+            $exitValue |= &errorStrSearch("$testFile.stdout");
+        }
+
+        # Compare STDERR capture with verified file
+        $exitValue |= &compareStream("$verifiedDir/$testFile.stderr");
+
+        # Check exit value to determine if verified file doesn't exist
+        if ( $exitValue & 4 ) {
+
+            # STDERR verified doesn't exist.  Search STDERR capture
+            # for strings indicating error or failure
+            $exitValue |= &errorStrSearch("$testFile.stderr");
+        }
+   }
+    else {
+
+        # Since test driver doesn't exist or is not executable then display
+        # message to user.
+        print(
+"        Need to specify an executable test file within directory.\n"
+        );
+
+        # Exit value set to indicate test driver doesn't exist or not executable
+        $exitValue |= 32;
+    }
+}
+
+# Exit for the script with exit value
+# Ignore the first three bit flags in exitValue since there are not indicators
+# of a failed test
+if ( ( $exitValue >> 3 ) != 0 ) {
+    print("Test failed - return status = $exitValue\n\n");
+}
+else {
+    print("Test successful\n\n");
+}
+exit($exitValue);
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( -e $streamFile ) {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/$verifiedDir/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmFlatField.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmFlatField.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmFlatField.c	(revision 22108)
@@ -0,0 +1,278 @@
+/** @file tst_pmFlatField.c
+ *
+ *  @brief Contains the tests for pmFlatField.c:
+ *
+ *    Test A - Divide input image by flat image
+ *    Test B - Mask flat image data
+ *    Test C - Mask flat image data starting with non-null mask
+ *    Test E - Attempt to use null input image
+ *    Test F - Attempt tp use null flat image
+ *    Test G - Attempt to use input image bigger than flat image
+ *    Test H - Attempt to use input image mask bigger than flat image
+ *    Test I - Attempt to use offset greater than input image
+ *    Test J - Attempt to use complex input image
+ *    Test K - Attempt to use complex flat image
+ *    Test L - Attempt to use non-equal input and flat image types
+ *    Test M - Attempt to use non-mask type mask image
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 01:17:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmFlatField.h"
+
+
+#define PRINT_MATRIX(IMAGE,TYPE,STRING)                                                                      \
+printf(STRING);                                                                                              \
+printf("\n");                                                                                                \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                     \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));                 \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                                  \
+            printf("%d ", (int)IMAGE->data.TYPE[i][j]);                                                      \
+        } else {                                                                                             \
+            printf("%f ", (double)IMAGE->data.TYPE[i][j]);                                                   \
+        }                                                                                                    \
+    }                                                                                                        \
+    printf("\n");                                                                                            \
+}                                                                                                            \
+printf("\n");
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
+for(int i=0; i<NAME->numRows; i++) {                                                                         \
+    for(int j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+static int testFlatField(void);
+
+
+testDescription tests[] = {
+                              {testFlatField, 753, "pmFlatField", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+
+int testFlatField( void )
+{
+    // Test A - Divide input image by flat image
+    printPositiveTestHeader(stdout, "pmFlatField", "Test A - Divide input image by flat image");
+    CREATE_AND_SET_IMAGE(inImage,F64,6.0,3,3)
+    psReadout *inReadout = psReadoutAlloc();
+    inReadout->image = inImage;
+    PRINT_MATRIX(inImage,F64,"Input image:");
+    CREATE_AND_SET_IMAGE(flatImage1,F64,2.0,3,3)
+    psReadout *flatReadout = psReadoutAlloc();
+    flatReadout->image = flatImage1;
+    PRINT_MATRIX(flatImage1,F64,"Flat image:");
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test A - Returned false should be true");
+        return 1;
+    }
+    PRINT_MATRIX(inImage,F64, "Resulting image:");
+    printFooter(stdout, "pmFlatField", "Test A - Divide input image by flat image", true);
+    printf("\n\n\n");
+
+
+    // Test B - Mask flat image data
+    printPositiveTestHeader(stdout, "pmFlatField", "Test B - Mask flat image data");
+    PRINT_MATRIX(inImage, F64, "Input image:");
+    CREATE_AND_SET_IMAGE(flatImage2,F64,0.0,3,3)
+    PRINT_MATRIX(flatImage2, F64, "Flat image:");
+    flatReadout->image = flatImage2;
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test B - Returned false should be true");
+        return 2;
+    }
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA, "Resulting mask:");
+    PRINT_MATRIX(inImage,F64,"Resulting image:");
+    printFooter(stdout, "pmFlatField", "Test B - Mask flat image data", true);
+    printf("\n\n\n");
+
+
+    // Test C - Mask flat image data starting with non-null mask
+    printPositiveTestHeader(stdout, "pmFlatField", "Test C - Mask flat image data starting with non-null mask");
+    PRINT_MATRIX(inImage, F64, "Input image:");
+    flatImage2->data.F64[0][0] = 3.0;
+    flatImage2->data.F64[0][1] = -3.0;
+    PRINT_MATRIX(flatImage2, F64, "Flat image:");
+    CREATE_AND_SET_IMAGE(mask1,U8,0,3,3);
+    psFree(inReadout->mask);
+    inReadout->mask = mask1;
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test C - Returned false should be true");
+        return 3;
+    }
+    PRINT_MATRIX(flatImage2, F64, "Flat image out:");
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA,"Resulting mask:");
+    PRINT_MATRIX(inImage,F64,"Resulting image:");
+    printFooter(stdout, "pmFlatField", "Test C - Mask flat image data starting with non-null mask", true);
+    printf("\n\n\n");
+
+
+    // Test D - Attempt to use null flat readout
+    printNegativeTestHeader(stdout,"pmFlatField", "Test D - Attempt to use null flat readout",
+                            "Null not allowed for flat readout", 0);
+    if( pmFlatField(inReadout, NULL) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test D - Returned true should be false");
+        return 4;
+    }
+    printFooter(stdout, "pmFlatField", "Test D - Attempt to use null flat readout", true);
+    printf("\n\n\n");
+
+
+    // Test E - Attempt to use null input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test E - Attempt to use null input image",
+                            "Null not allowed for input image", 0);
+    psImage *temp = inReadout->image;
+    inReadout->image = NULL;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test E - Returned true should be false" );
+        return 5;
+    }
+    inReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test E - Attempt to use null input image", true);
+    printf("\n\n\n");
+
+
+    // Test F - Attempt tp use null flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test F - Attempt tp use null flat image",
+                            "Null not allowed for flat image", 0);
+    temp = flatReadout->image;
+    flatReadout->image = NULL;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test F - Returned true should be false" );
+        return 6;
+    }
+    flatReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test F - Attempt tp use null flat image", true);
+    printf("\n\n\n");
+
+
+    // Test G - Attempt to use input image bigger than flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test G - Attempt to use input image bigger than flat image",
+                            "Input image size exceeds that of flat image", 0);
+    CREATE_AND_SET_IMAGE(smallFlat,F64,0.0,2,2);
+    temp = flatReadout->image;
+    flatReadout->image = smallFlat;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test G - Returned true should be false");
+        return 7;
+    }
+    flatReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test G - Attempt to use input image bigger than flat image", true);
+    printf("\n\n\n");
+
+
+    // Test H - Attempt to use input image mask bigger than flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test H - Attempt to use input image mask bigger than flat image",
+                            "Input image mask size exceeds that of flat image", 0);
+    CREATE_AND_SET_IMAGE(largeMask,F64,0.0,4,4);
+    temp = inReadout->mask;
+    inReadout->mask = largeMask;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test H - Returned true should be false");
+        return 8;
+    }
+    inReadout->mask = temp;
+    printFooter(stdout, "pmFlatField", "Test H - Attempt to use input image mask bigger than flat image", true);
+    printf("\n\n\n");
+
+
+    // Test I - Attempt to use offset greater than input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test I - Attempt to use offset greater than input image",
+                            "Total offset >= input image size", 0);
+    *(int*)&inReadout->col0 = 50;
+    *(int*)&inReadout->row0 = 50;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test I - Returned true should be false");
+        return 9;
+    }
+    *(int*)&inReadout->col0 = 0;
+    *(int*)&inReadout->row0 = 0;
+    printFooter(stdout, "pmFlatField", "Test I - Attempt to use offset greater than input image", true);
+    printf("\n\n\n");
+
+
+    // Test J - Attempt to use complex input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test J - Attempt to use complex input image",
+                            "Complex types not allowed for input image", 0);
+    *(psElemType* ) & inReadout->image->type.type = PS_TYPE_C64;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test J - Returned true should be false");
+        return 10;
+    }
+    *(psElemType* ) & inReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test J - Attempt to use complex input image", true);
+    printf("\n\n\n");
+
+
+    // Test K - Attempt to use complex flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test K - Attempt to use complex flat image",
+                            "Complex types not allowed for flat image", 0);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_C64;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test K - Returned ture should be false");
+        return 11;
+    }
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test K - Attempt to use complex flat image", true);
+    printf("\n\n\n");
+
+
+    // Test L - Attempt to use non-equal input and flat image types
+    printNegativeTestHeader(stdout,"pmFlatField", "Test L - Attempt to use non-equal input and flat image types",
+                            "Input and flat image types differ", 0);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F32;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test L - Returned true should be false");
+        return 12;
+    }
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test L - Attempt to use non-equal input and flat image types", true);
+    printf("\n\n\n");
+
+
+    // Test M - Attempt to use non-mask type mask image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test M - Attempt to use non-mask type mask image",
+                            "Mask must be PS_TYPE_MASK type", 0);
+    *(psElemType* ) & inReadout->mask->type.type = PS_TYPE_F32;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test M - Returned true should be false");
+        return 13;
+    }
+    *(psElemType* ) & inReadout->mask->type.type = PS_TYPE_MASK;
+    printFooter(stdout, "pmFlatField", "Test M - Attempt to use non-mask type mask image", true);
+    printf("\n\n\n");
+
+
+    // Free memory
+    psFree(inReadout);
+    psFree(flatReadout);
+    //psFree(inImage);
+    psFree(flatImage1);
+    //psFree(flatImage1);
+    psFree(smallFlat);
+    psFree(largeMask);
+
+    return 0;
+}
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmMaskBadPixels.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmMaskBadPixels.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmMaskBadPixels.c	(revision 22108)
@@ -0,0 +1,280 @@
+/** @file tst_pmMaskBadPixels.c
+ *
+ *  @brief Contains the tests for pmMaskBadPixels:
+ *
+ *    Test A - Create mask based on maskVal argument
+ *    Test B - Create mask based on saturation argument
+ *    Test C - Create mask based on growVal and grow arguments
+ *    Test D - Auto Create mask based on maskVal argument
+ *    Test E - Attempt to use null mask
+ *    Test F - Attempt tp use null input image
+ *    Test G - Attempt to use input image bigger than mask
+ *    Test H - Attempt to use input image mask bigger than mask
+ *    Test I - Attempt to use offset greater than input image
+ *    Test J - Attempt to use complex input image
+ *    Test K - Attempt to use non-mask type mask image
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 01:30:16 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmMaskBadPixels.h"
+
+
+#define PRINT_MATRIX(IMAGE,TYPE,STRING)                                                                      \
+printf(STRING);                                                                                              \
+printf("\n");                                                                                                \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                     \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));                 \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                                  \
+            printf("%d", (int)IMAGE->data.TYPE[i][j]);                                                       \
+        } else {                                                                                             \
+            printf("%f", (double)IMAGE->data.TYPE[i][j]);                                                    \
+        }                                                                                                    \
+    }                                                                                                        \
+    printf("\n");                                                                                            \
+}                                                                                                            \
+printf("\n");
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
+for(int i=0; i<NAME->numRows; i++) {                                                                         \
+    for(int j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+static int testMaskBadPixels1(void);
+static int testMaskBadPixels2(void);
+static int testMaskBadPixels3(void);
+static int testMaskBadPixels4(void);
+static int testMaskBadPixels5(void);
+static int testMaskBadPixels6(void);
+static int testMaskBadPixels7(void);
+static int testMaskBadPixels8(void);
+static int testMaskBadPixels9(void);
+static int testMaskBadPixels10(void);
+static int testMaskBadPixels11(void);
+
+
+testDescription tests[] = {
+                              {testMaskBadPixels1, 885, "pmMaskBadPixels - Create mask based on maskVal argument", 0, false},
+                              {testMaskBadPixels2, 885, "pmMaskBadPixels - Create mask based on saturation argument", 0, false},
+                              {testMaskBadPixels3, 885, "pmMaskBadPixels - Create mask based on growVal and grow arguments", 0, false},
+                              {testMaskBadPixels4, 885, "pmMaskBadPixels - Auto create mask based on maskVal argument", 0, false},
+                              {testMaskBadPixels5, 885, "pmMaskBadPixels - Attempt to use null mask", 0, false},
+                              {testMaskBadPixels6, 885, "pmMaskBadPixels - Attempt tp use null input image", 0, false},
+                              {testMaskBadPixels7, 885, "pmMaskBadPixels - Attempt to use input image bigger than mask", 0, false},
+                              {testMaskBadPixels8, 885, "pmMaskBadPixels - Attempt to use input image mask bigger than mask", 0, false},
+                              {testMaskBadPixels9, 885, "pmMaskBadPixels - Attempt to use offset greater than input image", 0, false},
+                              {testMaskBadPixels10, 885, "pmMaskBadPixels - Attempt to use complex input image", 0, false},
+                              {testMaskBadPixels11, 885, "pmMaskBadPixels - Attempt to use non-mask type mask image", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+
+int testMaskBadPixels1( void )
+{
+    // Test A - Create mask based on maskVal argument
+    CREATE_AND_SET_IMAGE(inImage1,F64,0,50,50);
+    CREATE_AND_SET_IMAGE(mask1,U8,0,50,50)
+    //    psReadout *inReadout = psReadoutAlloc(0, 0, inImage1);
+    psReadout *inReadout = psReadoutAlloc();
+    inReadout->image = inImage1;
+    mask1->data.PS_TYPE_MASK_DATA[24][24]=1;
+    PRINT_MATRIX(mask1, U8, "Data mask:");
+    pmMaskBadPixels(inReadout, mask1, 1, 100.0, 0, 0);
+    PRINT_MATRIX(inReadout->mask, U8, "Resulting mask:");
+    psFree(mask1);
+    psFree(inReadout);
+
+    return 0;
+}
+
+int testMaskBadPixels2( void )
+{
+    // Test B - Create mask based on saturation argument
+    CREATE_AND_SET_IMAGE(inImage2,F64,150.0,50,50);
+    CREATE_AND_SET_IMAGE(mask2,U8,0,50,50)
+    //    psReadout *inReadout2 = psReadoutAlloc(0, 0, inImage2);
+    psReadout *inReadout2 = psReadoutAlloc();
+    inReadout2->image = inImage2;
+    PRINT_MATRIX(mask2, U8, "Data mask:");
+    pmMaskBadPixels(inReadout2, mask2, 0, 100.0, 0, 0);
+    PRINT_MATRIX(inReadout2->mask, U8, "Resulting mask:");
+    psFree(mask2);
+    psFree(inReadout2);
+
+    return 0;
+}
+
+int testMaskBadPixels3( void )
+{
+    // Test C - Create mask based on growVal and grow arguments
+    CREATE_AND_SET_IMAGE(inImage3,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask3,U8,0,50,50)
+    //    psReadout *inReadout3 = psReadoutAlloc(0, 0, inImage3);
+    psReadout *inReadout3 = psReadoutAlloc();
+    inReadout3->image = inImage3;
+    mask3->data.PS_TYPE_MASK_DATA[24][24]=1;
+    mask3->data.PS_TYPE_MASK_DATA[4][3]=1;
+    mask3->data.PS_TYPE_MASK_DATA[4][46]=1;
+    PRINT_MATRIX(mask3, U8, "Data mask:");
+    pmMaskBadPixels(inReadout3, mask3, 0, 100.0, 1, 10);
+    PRINT_MATRIX(inReadout3->mask, U8, "Resulting mask:");
+    psFree(mask3);
+    psFree(inReadout3);
+
+    return 0;
+}
+
+int testMaskBadPixels4( void )
+{
+    // Test D - Auto Create mask based on maskVal argument
+    CREATE_AND_SET_IMAGE(inImage4,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask4,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask4i,U8,0,50,50)
+    //    psReadout *inReadout4 = psReadoutAlloc(0, 0, inImage4);
+    psReadout *inReadout4 = psReadoutAlloc();
+    inReadout4->image = inImage4;
+    inReadout4->mask = mask4i;
+    mask4->data.PS_TYPE_MASK_DATA[24][24]=1;
+    PRINT_MATRIX(mask4, U8, "Data mask:");
+    pmMaskBadPixels(inReadout4, mask4, 0, 100.0, 1, 10);
+    PRINT_MATRIX(inReadout4->mask, U8, "Resulting mask:");
+    psFree(mask4);
+    psFree(inReadout4);
+
+    return 0;
+}
+
+int testMaskBadPixels5( void )
+{
+    // Test E - Attempt to use null mask
+    CREATE_AND_SET_IMAGE(inImage5,F64,50.0,50,50);
+    //    psReadout *inReadout5 = psReadoutAlloc(0, 0, inImage5);
+    psReadout *inReadout5 = psReadoutAlloc();
+    inReadout5->image = inImage5;
+    pmMaskBadPixels(inReadout5, NULL, 0, 100.0, 1, 10);
+    psFree(inReadout5);
+
+    return 0;
+}
+
+int testMaskBadPixels6( void )
+{
+    // Test F - Attempt tp use null input image
+    CREATE_AND_SET_IMAGE(mask6,U8,0,50,50)
+    //    psReadout *inReadout6 = psReadoutAlloc(0, 0, NULL);
+    psReadout *inReadout6 = psReadoutAlloc();
+    inReadout6->mask = mask6;
+    pmMaskBadPixels(inReadout6, mask6, 0, 100.0, 1, 10);
+    psFree(inReadout6);
+
+    return 0;
+}
+
+int testMaskBadPixels7( void )
+{
+    // Test G - Attempt to use input image bigger than mask
+    CREATE_AND_SET_IMAGE(inImage7,F64,0.0,60,60);
+    CREATE_AND_SET_IMAGE(mask7,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask7i,U8,0,50,50)
+    //    psReadout *inReadout7 = psReadoutAlloc(0, 0, inImage7);
+    psReadout *inReadout7 = psReadoutAlloc();
+    inReadout7->image = inImage7;
+    inReadout7->mask = mask7i;
+    pmMaskBadPixels(inReadout7, mask7, 0, 100.0, 1, 10);
+    psFree(mask7);
+    psFree(inReadout7);
+
+    return 0;
+}
+
+int testMaskBadPixels8( void )
+{
+    // Test H - Attempt to use input image mask bigger than mask
+    CREATE_AND_SET_IMAGE(inImage8,F64,0.0,50,50);
+    CREATE_AND_SET_IMAGE(mask8,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask8i,U8,0,60,60)
+    //    psReadout *inReadout8 = psReadoutAlloc(0, 0, inImage8);
+    psReadout *inReadout8 = psReadoutAlloc();
+    inReadout8->image = inImage8;
+    inReadout8->mask = mask8i;
+    pmMaskBadPixels(inReadout8, mask8, 0, 100.0, 1, 10);
+    psFree(mask8);
+    psFree(inReadout8);
+
+    return 0;
+}
+
+int testMaskBadPixels9( void )
+{
+    // Test I - Attempt to use offset greater than input image
+    CREATE_AND_SET_IMAGE(inImage9,F64,0.0,50,50);
+    CREATE_AND_SET_IMAGE(mask9,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask9i,U8,0,50,50)
+    //    psReadout *inReadout9 = psReadoutAlloc(0, 0, inImage9);
+    psReadout *inReadout9 = psReadoutAlloc();
+    inReadout9->image = inImage9;
+    inReadout9->mask = mask9i;
+    *(int*)&inReadout9->col0 = 150;
+    *(int*)&inReadout9->row0 = 150;
+    pmMaskBadPixels(inReadout9, mask9, 0, 100.0, 1, 10);
+    psFree(mask9);
+    psFree(inReadout9);
+
+    return 0;
+}
+
+int testMaskBadPixels10( void )
+{
+    // Test J - Attempt to use complex input image
+    CREATE_AND_SET_IMAGE(inImage10,C64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask10,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask10i,U8,0,50,50)
+    //    psReadout *inReadout10 = psReadoutAlloc(0, 0, inImage10);
+    psReadout *inReadout10 = psReadoutAlloc();
+    inReadout10->image = inImage10;
+    inReadout10->mask = mask10i;
+    pmMaskBadPixels(inReadout10, mask10, 0, 100.0, 1, 10);
+    psFree(mask10);
+    psFree(inReadout10);
+
+    return 0;
+}
+
+int testMaskBadPixels11( void )
+{
+    // Test K - Attempt to use non-mask type mask image
+    CREATE_AND_SET_IMAGE(inImage11,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask11,F64,0,50,50)
+    CREATE_AND_SET_IMAGE(mask11i,U8,0,50,50)
+    //    psReadout *inReadout11 = psReadoutAlloc(0, 0, inImage11);
+    psReadout *inReadout11 = psReadoutAlloc();
+    inReadout11->image = inImage11;
+    inReadout11->mask = mask11i;
+    pmMaskBadPixels(inReadout11, mask11, 0, 100.0, 1, 10);
+    psFree(mask11);
+    psFree(inReadout11);
+
+    return 0;
+}
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmNonLinear.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmNonLinear.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmNonLinear.c	(revision 22108)
@@ -0,0 +1,510 @@
+/** @file tst_pmNonLinear.c
+ *
+ *  @brief Contains the tests for pmNonLinear.c:
+ *
+ * test00: This code will create a simple polynomial, and call
+ * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
+ * N), (N, 1), (N, N)].  
+ *
+ * test01: This code will create simple table lookup vectors, and call
+ * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
+ * N), (N, 1), (N, N)].  
+ *
+ * test02, test03: This code tests the functions with various unallowable
+ * input parameters (NULLS) and incorrect vector sizes.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 23:39:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmNonLinear.h"
+static int test00(void);
+static int test01(void);
+static int test02(void);
+static int test03(void);
+testDescription tests[] = {
+                              {test00, 000, "pmNonLinearityPolynomial", true, false},
+                              {test01, 000, "pmNonLinearityLookup", true, false},
+                              {test02, 000, "pmNonLinearityPolynomial(): error/warning conditions", true, false},
+                              {test03, 000, "pmNonLinearityLookup(): error/warning conditions", true, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+#define NUM_ROWS 8
+#define NUM_COLS 8
+int doNonLinearityPolynomialTest(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = true;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = myImage;
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    myPoly->coeff[1] = 1.0;
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "doNonLinearityPolynomialTest");
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    myReadout = pmNonLinearityPolynomial(myReadout, myPoly);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = psPolynomial1DEval(myPoly, (float) (i + j));
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myPoly);
+    printFooter(stdout, "pmNonLinear", "doNonLinearityPolynomialTest", true);
+    return(testStatus);
+}
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doNonLinearityPolynomialTest(1, 1);
+    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, 1);
+    testStatus |= doNonLinearityPolynomialTest(1, NUM_ROWS);
+    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int doNonLinearityLookupTest(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = true;
+    int tableSize = PS_MAX(numCols, numRows)*2;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = myImage;
+    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "doNonLinearityLookupTest");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    for (i=0;i<tableSize;i++) {
+        in->data.F32[i] = (float) i;
+        out->data.F32[i] = (float) (2 * i);
+    }
+
+    myReadout = pmNonLinearityLookup(myReadout, in, out);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = (float) (2 * (i + j));
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(in);
+    psFree(out);
+    printFooter(stdout, "pmNonLinear", "doNonLinearityLookupTest", true);
+    return(testStatus);
+}
+
+int test01( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doNonLinearityLookupTest(1, 1);
+    testStatus |= doNonLinearityLookupTest(NUM_COLS, 1);
+    testStatus |= doNonLinearityLookupTest(1, NUM_ROWS);
+    testStatus |= doNonLinearityLookupTest (NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int test02( void )
+{
+    int i;
+    int j;
+    int testStatus = true;
+    psImage *myImage = psImageAlloc(NUM_COLS, NUM_ROWS, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *rc = NULL;
+    myReadout->image = myImage;
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    myPoly->coeff[1] = 1.0;
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "Testing bad input parameter conditions.");
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL input readout.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityPolynomial(NULL, myPoly);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL input readout->image.  Should generate error, return NULL.\n");
+    psImage *tmpImage = myReadout->image;
+    myReadout->image = NULL;
+    rc = pmNonLinearityPolynomial(myReadout, myPoly);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImage;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL polynomial.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityPolynomial(myReadout, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    psFree(myReadout);
+    psFree(myPoly);
+    return(testStatus);
+}
+
+
+int test03Init(psReadout *myReadout)
+{
+    for (psS32 i=0;i<NUM_ROWS;i++) {
+        for (psS32 j=0;j<NUM_COLS;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+    return(0);
+}
+
+int test03()
+{
+    int i;
+    int j;
+    int testStatus = true;
+    int tableSize = PS_MAX(NUM_COLS, NUM_ROWS)*3;
+    psImage *myImage = psImageAlloc(NUM_COLS, NUM_ROWS, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *rc = NULL;
+    myReadout->image = myImage;
+    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *inOne = psVectorAlloc(1, PS_TYPE_F32);
+    psVector *inSmall = psVectorAlloc(tableSize-1, PS_TYPE_F32);
+    psVector *inBig = psVectorAlloc(tableSize+1, PS_TYPE_F32);
+    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *outOne = psVectorAlloc(1, PS_TYPE_F32);
+    psVector *outSmall = psVectorAlloc(tableSize-1, PS_TYPE_F32);
+    psVector *outBig = psVectorAlloc(tableSize+1, PS_TYPE_F32);
+
+    test03Init(myReadout);
+    for (i=0;i<tableSize;i++) {
+        in->data.F32[i] = (float) i;
+        out->data.F32[i] = (float) (2 * i);
+        inBig->data.F32[i] = (float) i;
+        outBig->data.F32[i] = (float) (2 * i);
+        if (i < tableSize-1) {
+            inSmall->data.F32[i] = (float) i;
+            outSmall->data.F32[i] = (float) (2 * i);
+        }
+    }
+    inBig->data.F32[tableSize] = (float) tableSize;
+    outBig->data.F32[tableSize] = (float) (2 * tableSize);
+    inOne->data.F32[0] = 0.0;
+    outOne->data.F32[0] = 0.0;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL input psReadout.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(NULL, in, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL input psReadout->image.  Should generate error, return NULL.\n");
+    psImage *tmpImage = myReadout->image;
+    myReadout->image = NULL;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImage;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL inFlux psVector.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(myReadout, NULL, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL outFlux psVector.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(myReadout, in, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, in, outBig);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, in, outSmall);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inSmall, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inBig, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inSmall, outBig);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inBig, outSmall);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with inFlux psVector size 1.  Should generate error, return original psReadout.\n");
+    rc = pmNonLinearityLookup(myReadout, inOne, out);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() did not return the original psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) ((i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.\n");
+    test03Init(myReadout);
+    myReadout->image->data.F32[0][0] = -1;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if(i==0 && j==0) {
+                if(actual != 0.0) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n",i,j,actual,0.0);
+                }
+            } else {
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = false;
+                }
+            }
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.\n");
+    test03Init(myReadout);
+    myReadout->image->data.F32[NUM_ROWS-1][NUM_COLS-1] = 100;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if(i==(NUM_ROWS-1) && j==(NUM_COLS-1)) {
+                if(actual != (tableSize-1)*2) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n",i,j,actual,(tableSize-1)*2.0);
+                }
+            } else {
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = false;
+                }
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with image values not in vector.\n");
+    myReadout->image->data.F32[0][0] = 0.5;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            if(i==0 && j==0) {
+                expect = 1.0;
+            }
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    psFree(myReadout);
+    psFree(in);
+    psFree(inOne);
+    psFree(inSmall);
+    psFree(inBig);
+    psFree(out);
+    psFree(outOne);
+    psFree(outSmall);
+    psFree(outBig);
+
+    printFooter(stdout, "pmNonLinear", "Testing bad input parameter conditions.", true);
+    return(testStatus);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmObjects01.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmObjects01.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmObjects01.c	(revision 22108)
@@ -0,0 +1,1757 @@
+/** @file tst_pmFindObjects.c
+ *
+ *  @brief Contains the tests for pmSubtractSky.c:
+ *
+ * test00: This code will ...
+ *
+ *  @author GLG, MHPCC
+ *
+ * XXX: Must test
+ *       pmSourceRoughClass
+ *
+ * XXX: Must test output results for many other functions.
+ *
+ * XXX: There are many cases where row/col can be switched in the code.
+ * We must test that here by using non-square images.  All tests
+ * in this file should be run with non-square images.
+ *
+ * XXX: Memory leaks are not being caught.  If I allocated a psVector in these functions
+ * abd never deallocate, no error is generated.
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-04-01 21:39:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include "psTest.h"
+#include "pslib.h"
+#include "pmObjects.h"
+#define NUM_ROWS 10
+#define NUM_COLS 10
+#define ERROR_TOLERANCE 1.0
+static int test00(void);
+static int test01(void);
+static int test02(void);
+static int test03(void);
+static int test04(void);
+static int test05(void);
+static int test06(void);
+static int test07(void);
+static int test08(void);
+static int test09(void);
+static int test15(void);
+static int test16(void);
+static int test20(void);
+testDescription tests[] = {
+                              {test00, 000, "pmObjects: structure allocators and deallocators", true, false},
+                              {test01, 001, "pmObjects: psFindVectorPeaks()", true, false},
+                              {test02, 001, "pmObjects: psFindImagePeaks()", true, false},
+                              {test03, 001, "pmObjects: pmCullPeaks()", true, false},
+                              {test04, 001, "pmObjects: pmSourceLocalSky()", true, false},
+                              {test06, 001, "pmObjects: pmSourceSetPixelCircle()", true, false},
+                              {test05, 001, "pmObjects: pmSourceMoments()", true, false},
+                              {test07, 001, "pmObjects: pmMin()", true, false},
+                              {test08, 001, "pmObjects: pmSourceModelGuess()", true, false},
+                              {test09, 001, "pmObjects: pmSourceContour()", true, false},
+                              {test15, 001, "pmObjects: pmSourceAddModel()", true, false},
+                              {test16, 001, "pmObjects: pmSourceSubModel()", true, false},
+                              {test20, 001, "pmObjects: pmSourceSubModel()", true, false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+    test02();
+}
+
+/******************************************************************************
+test00(): Test the various allocators and deallocators.
+ *****************************************************************************/
+int test00( void )
+{
+    bool testStatus = true;
+    psTraceSetLevel(".", 0);
+
+    psPeak *tmpPeak = pmPeakAlloc(0, 0, 0.0, PM_PEAK_UNDEF);
+    if (tmpPeak == NULL) {
+        printf("TEST ERROR: pmPeakAlloc() returned a NULL psPeak\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpPeak);
+
+    psMoments *tmpMoments = pmMomentsAlloc();
+    if (tmpMoments == NULL) {
+        printf("TEST ERROR: pmMomentsAlloc() returned a NULL psMoments\n");
+        testStatus = false;
+    }
+    psFree(tmpMoments);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    psModel *tmpModel = pmModelAlloc(PS_MODEL_GAUSS);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    tmpModel = pmModelAlloc(PS_MODEL_PGAUSS);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    tmpModel = pmModelAlloc(PS_MODEL_TWIST_GAUSS);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    tmpModel = pmModelAlloc(PS_MODEL_WAUSS);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    tmpModel = pmModelAlloc(PS_MODEL_SERSIC);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    // XXX: Must test this with variety of models, and verify param length.
+    tmpModel = pmModelAlloc(PS_MODEL_SERSIC_CORE);
+    if (tmpModel == NULL) {
+        printf("TEST ERROR: pmModelAlloc() returned a NULL psModel\n");
+        testStatus = false;
+    }
+    // XXX: Test that values were set properly.
+    psFree(tmpModel);
+
+    psSource *tmpSource = pmSourceAlloc();
+    if (tmpSource == NULL) {
+        printf("TEST ERROR: pmSourceAlloc() returned a NULL psSource\n");
+        testStatus = false;
+    }
+    psFree(tmpSource);
+
+    return(testStatus);
+}
+
+#define VECTOR_SIZE 10
+bool test_pmFindVectorPeaks(int n)
+{
+    bool testStatus = true;
+    psVector *inData = psVectorAlloc(n, PS_TYPE_F32);
+    psVector *outData = NULL;
+
+    printf("-------------- Calling test_pmFindVectorPeaks on an %d size vector. --------------\n", n);
+    //
+    // Test first pixel peak.
+    //
+    printf("Test pmFindVectorPeaks() with a first-element peak.\n");
+    for (psS32 i = 0 ; i < n ; i++) {
+        inData->data.F32[i] = (float) (n-i);
+    }
+    inData->data.F32[0] = (float) n;
+
+    outData= pmFindVectorPeaks(inData, 0.0);
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != 1) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+        if (outData->data.U32[0] != 0) {
+            printf("TEST ERROR: Did not find peak at element 0.\n");
+            testStatus = false;
+        }
+        psFree(outData);
+    }
+
+    //
+    // Test first pixel peak, large threshold
+    //
+    printf("Test pmFindVectorPeaks() with a first-element peak, large threshold.\n");
+    for (psS32 i = 0 ; i < n ; i++) {
+        inData->data.F32[i] = (float) (n-i);
+    }
+    inData->data.F32[0] = (float) n;
+
+    outData= pmFindVectorPeaks(inData, (float) (n*n));
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != 0) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+        psFree(outData);
+
+        // Skip remaining tests if the input vector has length 1.
+        if (n == 1) {
+            psFree(inData);
+            return(testStatus);
+        }
+    }
+
+    //
+    // Test last pixel peak.
+    //
+    printf("Test pmFindVectorPeaks() with a last-element peak.\n");
+    for (psS32 i = 0 ; i < n ; i++) {
+        inData->data.F32[i] = (float) (i);
+    }
+    inData->data.F32[n-1] = (float) n;
+
+    outData= pmFindVectorPeaks(inData, 0.0);
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != 1) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+        if (outData->data.U32[0] != n-1) {
+            printf("TEST ERROR: Did not find peak at element %d.\n", n-1);
+            testStatus = false;
+        }
+        psFree(outData);
+    }
+
+    //
+    // Test last pixel peak, large threshold.
+    //
+    printf("Test pmFindVectorPeaks() with a last-element peak, large threshold.\n");
+    for (psS32 i = 0 ; i < n ; i++) {
+        inData->data.F32[i] = (float) (i);
+    }
+    inData->data.F32[n-1] = (float) n;
+
+    outData= pmFindVectorPeaks(inData, (float) (n*n));
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != 0) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+        psFree(outData);
+    }
+
+    //
+    // Test interior peaks.
+    // Set all even number elements to be peaks.
+    //
+    printf("Test pmFindVectorPeaks() with all even-numbered elements peak.\n");
+    for (psS32 i = 0 ; i < n ; i++) {
+        if (0 == i%2) {
+            inData->data.F32[i] = (float) (2 * i);
+        } else {
+            inData->data.F32[i] = (float) (i);
+        }
+    }
+    inData->data.F32[0] = (float) n;
+
+
+    outData= pmFindVectorPeaks(inData, 0.0);
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != n/2) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+
+        for (psS32 i = 0 ; i < outData->n ; i++) {
+            if (outData->data.U32[i] != (2 * i)) {
+                printf("TEST ERROR: the %d-th peak is element number %d\n", i, outData->data.U32[i]);
+                testStatus = false;
+            }
+        }
+        psFree(outData);
+    }
+
+    //
+    // Test interior peaks, with threshold = n*n.
+    // Should generate an empty output psVector.
+    //
+    printf("Test pmFindVectorPeaks() with all even-numbered elements peak, large threshold.\n");
+    outData= pmFindVectorPeaks(inData, (float) (n*n));
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks returned a NULL psVector.\n");
+        testStatus = false;
+    } else {
+
+        if (outData->n != 0) {
+            printf("TEST ERROR: outData->n is %d\n", outData->n);
+            testStatus = false;
+        }
+        psFree(outData);
+    }
+
+
+    psFree(inData);
+    return(testStatus);
+}
+
+
+int test01( void )
+{
+    bool testStatus = true;
+    psVector *tmpVec = NULL;
+    psVector *tmpVecF64 = psVectorAlloc(10, PS_TYPE_F64);
+    psVector *tmpVecEmpty = psVectorAlloc(0, PS_TYPE_F32);
+
+    psTraceSetLevel(".", 0);
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindVectorPeaks with NULL psVector.  Should generate error and return NULL.\n");
+    tmpVec = pmFindVectorPeaks(NULL, 0.0);
+    if (tmpVec != NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks() returned a non-NULL psVector.\n");
+        testStatus = false;
+        psFree(tmpVec);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindVectorPeaks with empty psVector.  Should generate error and return NULL.\n");
+    tmpVec = pmFindVectorPeaks(tmpVecEmpty, 0.0);
+    if (tmpVec != NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks() returned a non-NULL psVector.\n");
+        testStatus = false;
+        psFree(tmpVec);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindVectorPeaks with PS_TYPE_F64 psVector.  Should generate error and return NULL.\n");
+    tmpVec = pmFindVectorPeaks(tmpVecF64, 0.0);
+    if (tmpVec != NULL) {
+        printf("TEST ERROR: pmFindVectorPeaks() returned a non-NULL psVector.\n");
+        testStatus = false;
+        psFree(tmpVec);
+    }
+    testStatus&= test_pmFindVectorPeaks(1);
+    testStatus&= test_pmFindVectorPeaks(VECTOR_SIZE);
+
+    psFree(tmpVecF64);
+    psFree(tmpVecEmpty);
+    return(testStatus);
+}
+
+// XXX: Add tests for the PEAK_TYPE.
+// XXX: Add interior peaks, edge peaks, and flat peaks.
+bool test_pmFindImagePeaks(int numRows, int numCols)
+{
+    printf("-------------- Calling test_pmFindVectorPeaks on an %d-by-%d image. --------------\n", numRows, numCols);
+    bool testStatus = true;
+    psImage *inData = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psList *outData = NULL;
+
+    //
+    // Test first pixel peak.
+    //
+    for (psS32 i = 0 ; i < numRows ; i++) {
+        for (psS32 j = 0 ; j < numCols ; j++) {
+            inData->data.F32[i][j] = PS_SQR(i - numRows/2) + PS_SQR(j-numCols/2);
+        }
+    }
+    inData->data.F32[0][0] = PS_SQR(numRows) + PS_SQR(numCols);
+    inData->data.F32[0][numCols-1] = PS_SQR(numRows) + PS_SQR(numCols);
+    inData->data.F32[numRows-1][0] = PS_SQR(numRows) + PS_SQR(numCols);
+    inData->data.F32[numRows-1][numCols-1] = PS_SQR(numRows) + PS_SQR(numCols);
+    for (psS32 i = 0 ; i < numRows ; i++) {
+        for (psS32 j = 0 ; j < numCols ; j++) {
+            printf("(%.1f) ", inData->data.F32[i][j]);
+        }
+        printf("\n");
+    }
+
+    outData = pmFindImagePeaks(inData, 0.0);
+
+    if (outData == NULL) {
+        printf("TEST ERROR: pmFindImagePeaks returned a NULL psList.\n");
+        testStatus = false;
+    } else {
+        if (outData->size != 4) {
+            printf("TEST ERROR: pmFindImagePeaks found only %d peaks (should be 4)\n", outData->size);
+            testStatus = false;
+        }
+
+        psListElem *tmpPeakLE = (psListElem *) outData->head;
+        while (tmpPeakLE != NULL) {
+            psPeak *tmpPeak = (psPeak *) tmpPeakLE->data;
+            if (((tmpPeak->x == 0) || (tmpPeak->x == numRows-1)) &&
+                ((tmpPeak->y == 0) || (tmpPeak->y == numCols-1))) {}
+            else {
+                printf("TEST ERROR: Peak at (%d, %d) (%f)\n", tmpPeak->x, tmpPeak->y, tmpPeak->counts);
+                testStatus = false;
+            }
+            tmpPeakLE = tmpPeakLE->next;
+        }
+    }
+
+    psFree(inData);
+    psFree(outData);
+    return(testStatus);
+}
+
+
+int test02( void )
+{
+    bool testStatus = true;
+    psList *tmpList = NULL;
+    psImage *tmpImageF64 = psImageAlloc(10, 10, PS_TYPE_F64);
+    psImage *tmpImageEmpty = psImageAlloc(0, 0, PS_TYPE_F32);
+
+    psTraceSetLevel(".", 0);
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindImagePeaks with NULL psImage.  Should generate error and return NULL.\n");
+    tmpList = pmFindImagePeaks(NULL, 0.0);
+    if (tmpList != NULL) {
+        printf("TEST ERROR: pmFindImagePeaks() returned a non-NULL psImage.\n");
+        testStatus = false;
+        psFree(tmpList);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindImagePeaks with empty psImage.  Should generate error and return NULL.\n");
+    tmpList = pmFindImagePeaks(tmpImageEmpty, 0.0);
+    if (tmpList != NULL) {
+        printf("TEST ERROR: pmFindImagePeaks() returned a non-NULL psImage.\n");
+        testStatus = false;
+        psFree(tmpList);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmFindImagePeaks with PS_TYPE_F64 psImage.  Should generate error and return NULL.\n");
+    tmpList = pmFindImagePeaks(tmpImageF64, 0.0);
+    if (tmpList != NULL) {
+        printf("TEST ERROR: pmFindImagePeaks() returned a non-NULL psImage.\n");
+        testStatus = false;
+        psFree(tmpList);
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    //    testStatus&= test_pmFindImagePeaks(1, 1);
+    //    testStatus&= test_pmFindImagePeaks(2, 5);
+    //    testStatus&= test_pmFindImagePeaks(5, 2);
+    testStatus&= test_pmFindImagePeaks(10, 10);
+
+
+    psFree(tmpImageF64);
+    psFree(tmpImageEmpty);
+    return(testStatus);
+}
+
+/******************************************************************************
+test03(): We first test pmCullPeaks() with various NULL and unallowable input
+parameters.  Then we generate a list of peaks and test that pmCullPeaks()
+removes them correctly.
+ *****************************************************************************/
+int test03( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(NUM_COLS, NUM_ROWS, PS_TYPE_F32);
+    psList *outData = NULL;
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmCullPeaks with NULL psList.  Should generate error and return NULL.\n");
+    outData = pmCullPeaks(NULL, 0.0, NULL);
+    if (outData != NULL) {
+        printf("TEST ERROR: pmCulPeaks() returned a non-NULL psList.\n");
+        testStatus = false;
+    }
+
+    //
+    // Set peaks in input image.  All even-column and even-row pixels are
+    // set non-zero, all other pixels are set to zero.
+    //
+    psS32 numPeaksOrig = 0;
+    for (psS32 i = 0 ; i < NUM_ROWS ; i++) {
+        for (psS32 j = 0 ; j < NUM_COLS ; j++) {
+            if ((0 == i%2) && (0 == j%2)) {
+                imgData->data.F32[i][j] = (float) (i + 10);
+                numPeaksOrig++;
+            } else {
+                imgData->data.F32[i][j] = 0.0;
+            }
+        }
+    }
+    for (psS32 i = 0 ; i < NUM_ROWS ; i++) {
+        for (psS32 j = 0 ; j < NUM_COLS ; j++) {
+            printf("(%.1f) ", imgData->data.F32[i][j]);
+        }
+        printf("\n");
+    }
+    printf("Set %d peaks\n", numPeaksOrig);
+
+    //
+    // Call pmCullPeaks() with HUGE maxValue and NULL psRegion.  Should not
+    // remove any peaks.
+    //
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmCullPeaks with large maxValue and NULL psRegion.\n");
+    outData = pmFindImagePeaks(imgData, 0.0);
+    outData = pmCullPeaks(outData, PS_MAX_F32, NULL);
+
+    if (outData == NULL) {
+        printf("TEST ERROR: pmCullPeaks() returned a non-NULL psList.\n");
+        testStatus = false;
+        return(testStatus);
+    }
+    if (outData->size != numPeaksOrig) {
+        printf("TEST ERROR (0): pmCullPeaks incorrectly removed peaks\n");
+        printf("The pmCullPeaks() output had %d peaks, should have had %d peaks.\n", outData->size, numPeaksOrig);
+        testStatus = false;
+    }
+    psFree(outData);
+
+    //
+    // Call pmCullPeaks() with TINY maxValue and NULL psRegion.  Should
+    // remove all peaks.
+    //
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmCullPeaks with tiny maxValue and NULL psRegion.\n");
+    outData = pmFindImagePeaks(imgData, 0.0);
+    printf("pmFindImagePeaks found %d peaks\n", outData->size);
+    outData = pmCullPeaks(outData, 0.0, NULL);
+
+    if (outData == NULL) {
+        printf("TEST ERROR: pmCullPeaks() returned a non-NULL psList.\n");
+        testStatus = false;
+        return(testStatus);
+    }
+    if (outData->size != 0) {
+        printf("TEST ERROR (1): pmCullPeaks incorrectly removed peaks\n");
+        printf("The pmCullPeaks() output had %d peaks, should have had %d peaks.\n", outData->size, 0);
+        testStatus = false;
+    }
+    psFree(outData);
+
+    //
+    // Call pmCullPeaks() with HUGE maxValue and disjoint psRegion.  Should
+    // not remove any peaks.
+    //
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmCullPeaks with large maxValue and disjoint psRegion.\n");
+    outData = pmFindImagePeaks(imgData, 0.0);
+    printf("pmFindImagePeaks found %d peaks\n", outData->size);
+    psRegion *tmpRegion = psRegionAlloc(10000.0, 20000.0, 10000.0, 20000.0);
+    outData = pmCullPeaks(outData, PS_MAX_F32, tmpRegion);
+
+    if (outData == NULL) {
+        printf("TEST ERROR: pmCullPeaks() returned a non-NULL psList.\n");
+        testStatus = false;
+        return(testStatus);
+    }
+    if (outData->size != numPeaksOrig) {
+        printf("TEST ERROR (2): pmCullPeaks incorrectly removed peaks\n");
+        printf("The pmCullPeaks() output had %d peaks, should have had %d peaks.\n", outData->size, numPeaksOrig);
+        testStatus = false;
+    }
+    psFree(outData);
+    psFree(tmpRegion);
+
+    //
+    // Call pmCullPeaks() with HUGE maxValue and non-disjoint psRegion.  Should
+    // remove all peaks.
+    //
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmCullPeaks with large maxValue and non-disjoint psRegion.\n");
+    outData = pmFindImagePeaks(imgData, 0.0);
+    printf("pmFindImagePeaks found %d peaks\n", outData->size);
+    tmpRegion = psRegionAlloc(-PS_MAX_F32, PS_MAX_F32, -PS_MAX_F32, PS_MAX_F32);
+    outData = pmCullPeaks(outData, PS_MAX_F32, tmpRegion);
+
+    if (outData == NULL) {
+        printf("TEST ERROR: pmCullPeaks() returned a non-NULL psList.\n");
+        testStatus = false;
+        return(testStatus);
+    }
+    if (outData->size != 0) {
+        printf("TEST ERROR (3): pmCullPeaks incorrectly removed peaks\n");
+        printf("The pmCullPeaks() output had %d peaks, should have had %d peaks.\n", outData->size, 0);
+        testStatus = false;
+    }
+    psFree(outData);
+    psFree(tmpRegion);
+
+    printf("----------------------------------------------------------------------------------\n");
+    psFree(imgData);
+    return(testStatus);
+}
+
+#define TST04_NUM_ROWS 100
+#define TST04_NUM_COLS 100
+#define TST04_SKY 20.0
+#define TST04_INNER_RADIUS 3
+#define TST04_OUTER_RADIUS 5
+/******************************************************************************
+test04(): We first test pmSourceLocalSky() with various NULL and unallowable
+input parameters.
+ 
+XXX: Should we produce tests with boundary numbers for the inner/outer radius?
+ 
+XXX: Call this with varying sizes for the image.
+ *****************************************************************************/
+int test04( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST04_NUM_COLS, TST04_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST04_SKY;
+        }
+    }
+    psImage *imgDataF64 = psImageAlloc(TST04_NUM_COLS, TST04_NUM_ROWS, PS_TYPE_F64);
+    for (psS32 i = 0 ; i < imgDataF64->numRows; i++) {
+        for (psS32 j = 0 ; j < imgDataF64->numCols; j++) {
+            imgDataF64->data.F64[i][j] = 0.0;
+        }
+    }
+    psSource *rc = NULL;
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST04_NUM_ROWS / 2),
+                                  (psF32) (TST04_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with NULL psImage.  Should generate error and return NULL.\n");
+    rc = pmSourceLocalSky(NULL, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with wrong-type psImage.  Should generate error and return NULL.\n");
+    rc = pmSourceLocalSky(imgDataF64, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with NULL psPeak.  Should generate error and return NULL.\n");
+    rc = pmSourceLocalSky(imgData, NULL, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with innerRadius<0.0.  Should generate error and return NULL.\n");
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, -10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with innerRadius>outerRadius.  Should generate error and return NULL.\n");
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 5.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with subImage startRow < 0.  Should generate error and return NULL.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    tmpPeak->y = 1;
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with subImage endRow > numRows.  Should generate error and return NULL.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    tmpPeak->y = TST04_NUM_ROWS;
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with subImage startCol < 0.  Should generate error and return NULL.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    tmpPeak->x = 1;
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, 10.0, 20.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with subImage endCol > numCols.  Should generate error and return NULL.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    tmpPeak->x = TST04_NUM_COLS;
+    rc = pmSourceLocalSky(imgData, tmpPeak, PS_STAT_SAMPLE_MEAN, (psF32) TST04_INNER_RADIUS, (psF32) TST04_OUTER_RADIUS);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a non-NULL psSource.\n");
+        psFree(rc);
+        testStatus = false;
+    }
+
+
+    //
+    // XXX: The following code should be a separate function, and we should call it
+    // with a variety of image sizes, peaks.
+    //
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    rc = pmSourceLocalSky(imgData,
+                          tmpPeak,
+                          PS_STAT_SAMPLE_MEAN,
+                          (psF32) TST04_INNER_RADIUS,
+                          (psF32) TST04_OUTER_RADIUS);
+
+    if (rc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    } else {
+        if (rc->peak == NULL) {
+            printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource->peak.\n");
+            testStatus = false;
+        } else {
+            if (rc->peak->x != tmpPeak->x) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->peak->x was %d, should have been %d.\n", rc->peak->x, tmpPeak->x);
+                testStatus = false;
+            }
+
+            if (rc->peak->y != tmpPeak->y) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->peak->y was %d, should have been %d.\n", rc->peak->y, tmpPeak->y);
+                testStatus = false;
+            }
+
+            if (rc->peak->counts != tmpPeak->counts) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->peak->counts was %f, should have been %f.\n", rc->peak->counts, tmpPeak->counts);
+                testStatus = false;
+            }
+
+            if (rc->peak->class != tmpPeak->class) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->peak->class was %d, should have been %d.\n", rc->peak->class, tmpPeak->class);
+                testStatus = false;
+            }
+        }
+
+        if (rc->pixels == NULL) {
+            printf("TEST ERROR: pmSourceLocalSky() psSource->pixels was NULL.\n");
+            testStatus = false;
+        } else {
+            if (rc->pixels->numRows != (2 * TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->pixels->numRows was %d, should have been %d.\n",
+                       rc->pixels->numRows, (2 * TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->pixels->numCols != (2 * TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->pixels->numCols was %d, should have been %d.\n",
+                       rc->pixels->numCols, (2 * TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->pixels->col0 != (tmpPeak->x - TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->pixels->col0 was %d, should have been %d.\n",
+                       rc->pixels->col0, (tmpPeak->x - TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->pixels->row0 != (tmpPeak->y - TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->pixels->row0 was %d, should have been %d.\n",
+                       rc->pixels->row0, (tmpPeak->y - TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->pixels->type.type != PS_TYPE_F32) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->pixels->type was %d, should have been %d.\n",
+                       rc->pixels->type.type, PS_TYPE_F32);
+                testStatus = false;
+            }
+
+            // XXX: Test the rc->pixels-> row/col offsets.
+            // XXX: Test that the pixels corresponds to the source image pixels.
+        }
+
+        if (rc->mask == NULL) {
+            printf("TEST ERROR: pmSourceLocalSky() psSource->mask was NULL.\n");
+            testStatus = false;
+        } else {
+            if (rc->mask->numRows != (2 * TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->mask->numRows was %d, should have been %d.\n",
+                       rc->mask->numRows, (2 * TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->mask->numCols != (2 * TST04_OUTER_RADIUS)) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->mask->numCols was %d, should have been %d.\n",
+                       rc->mask->numCols, (2 * TST04_OUTER_RADIUS));
+                testStatus = false;
+            }
+
+            if (rc->mask->type.type != PS_TYPE_U8) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->mask->type was %d, should have been %d.\n",
+                       rc->mask->type.type, PS_TYPE_U8);
+                testStatus = false;
+            }
+
+            // XXX: Test the rc->mask-> row/col offsets.
+            // XXX: Test that the correct pixels were masked, not merely the number of masked pixels.
+            psS32 unmaskedPixels = 0;
+            psS32 maskedPixels = 0;
+
+            for (psS32 row = 0 ; row < rc->mask->numRows; row++) {
+                for (psS32 col = 0 ; col < rc->mask->numCols; col++) {
+                    if (rc->mask->data.U8[row][col] == 0) {
+                        unmaskedPixels++;
+                    } else {
+                        maskedPixels++;
+                    }
+                }
+            }
+            if (maskedPixels != PS_SQR(2*(TST04_INNER_RADIUS-1))) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->mask had %d masked pixels, should have been %d.\n",
+                       maskedPixels, PS_SQR(2*(TST04_INNER_RADIUS-1)));
+                testStatus = false;
+            }
+            if (unmaskedPixels != (PS_SQR(2*TST04_OUTER_RADIUS) - PS_SQR(2*(TST04_INNER_RADIUS-1)))) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->mask had %d masked pixels, should have been %d.\n",
+                       unmaskedPixels, (PS_SQR(2*TST04_OUTER_RADIUS) - PS_SQR(2*(TST04_INNER_RADIUS-1))));
+                testStatus = false;
+            }
+        }
+
+        if (rc->moments == NULL) {
+            printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource->moments.\n");
+            testStatus = false;
+        } else {
+            if (rc->moments->Sky != TST04_SKY) {
+                printf("TEST ERROR: pmSourceLocalSky() psSource->moments->Sky was %f, should have been %f.\n", rc->moments->Sky, TST04_SKY);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    psFree(rc);
+    psFree(imgData);
+    psFree(imgDataF64);
+    return(testStatus);
+}
+
+#define TST06_NUM_ROWS 100
+#define TST06_NUM_COLS 100
+#define TST06_SKY 20.0
+#define TST06_INNER_RADIUS 3
+#define TST06_OUTER_RADIUS 5
+/******************************************************************************
+test06(): We first test pmSourceLocalSky() with various NULL and unallowable
+input parameters.
+ 
+XXX: Should we produce tests with boundary numbers for the inner/outer radius?
+ 
+XXX: Call this with varying sizes for the image.
+ *****************************************************************************/
+int test06( void )
+{
+    bool testStatus = true;
+    psSource *tmpSource = NULL;
+    bool rc = false;
+    // Create the image used in this test.
+    psImage *imgData = psImageAlloc(TST06_NUM_COLS, TST06_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST06_SKY;
+        }
+    }
+    psImage *imgDataF64 = psImageAlloc(TST06_NUM_COLS, TST06_NUM_ROWS, PS_TYPE_F64);
+    for (psS32 i = 0 ; i < imgDataF64->numRows; i++) {
+        for (psS32 j = 0 ; j < imgDataF64->numCols; j++) {
+            imgDataF64->data.F64[i][j] = 0.0;
+        }
+    }
+
+    //
+    // Create a psPeak with the center pixel set to the peak.
+    //
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST06_NUM_ROWS / 2),
+                                  (psF32) (TST06_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    tmpSource = pmSourceLocalSky(imgData,
+                                 tmpPeak,
+                                 PS_STAT_SAMPLE_MEAN,
+                                 (psF32) TST06_INNER_RADIUS,
+                                 (psF32) TST06_OUTER_RADIUS);
+    if (tmpSource == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        psFree(imgData);
+        psFree(imgDataF64);
+        psFree(tmpSource);
+        testStatus = false;
+        return(testStatus);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with NULL psSource.  Should generate error and return NULL.\n");
+    rc = pmSourceSetPixelCircle(NULL, imgData, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+    // XXX: test with psSource->peaks NULL
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with NULL psImage.  Should generate error and return NULL.\n");
+    rc = pmSourceSetPixelCircle(tmpSource, NULL, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with wrong type psImage.  Should generate error and return NULL.\n");
+    rc = pmSourceSetPixelCircle(tmpSource, imgDataF64, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with radius < 0.0.  Should generate error and return NULL.\n");
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, -10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with subImage startCol < 0.  Should generate error and return NULL.\n");
+    tmpSource->peak->x = (psF32) (TST06_NUM_ROWS / 2);
+    tmpSource->peak->y = (psF32) (TST06_NUM_COLS / 2);
+    tmpSource->peak->x = 1;
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with subImage endCol > numCols.  Should generate error and return NULL.\n");
+    tmpSource->peak->x = (psF32) (TST06_NUM_ROWS / 2);
+    tmpSource->peak->y = (psF32) (TST06_NUM_COLS / 2);
+    tmpSource->peak->x = TST06_NUM_COLS;
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with subImage startRow < 0.  Should generate error and return NULL.\n");
+    tmpSource->peak->x = (psF32) (TST06_NUM_ROWS / 2);
+    tmpSource->peak->y = (psF32) (TST06_NUM_COLS / 2);
+    tmpSource->peak->y = 1;
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with subImage endRow > numRows.  Should generate error and return NULL.\n");
+    tmpSource->peak->x = (psF32) (TST06_NUM_ROWS / 2);
+    tmpSource->peak->y = (psF32) (TST06_NUM_COLS / 2);
+    tmpSource->peak->y = TST06_NUM_ROWS;
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, 10.0);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSetPixelCircle with valid data.\n");
+    tmpSource->peak->x = (psF32) (TST06_NUM_ROWS / 2);
+    tmpSource->peak->y = (psF32) (TST06_NUM_COLS / 2);
+    rc = pmSourceSetPixelCircle(tmpSource, imgData, 10.0);
+
+    if (rc == false) {
+        printf("TEST ERROR: pmSourceSetPixelCircle() returned FALSE.\n");
+        testStatus = false;
+    } else {
+        // XXX: Test correctness of the various psSetPixelCircle members.
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    psFree(imgData);
+    psFree(imgDataF64);
+    psFree(tmpSource);
+    return(testStatus);
+
+}
+
+#define TST05_NUM_ROWS 100
+#define TST05_NUM_COLS 100
+#define TST05_SKY 20.0
+#define TST05_INNER_RADIUS 3
+#define TST05_OUTER_RADIUS 5
+/******************************************************************************
+test05(): We first test pmSourceMoments() with various NULL and unallowable
+input parameters.
+ 
+XXX: Should we produce tests with boundary numbers for the inner/outer radius?
+ 
+XXX: Call this with varying sizes for the image.
+ 
+XXX: The actual values of the moments are not tested.
+ *****************************************************************************/
+int test05( void )
+{
+    bool testStatus = true;
+    psSource *tmpSource = NULL;
+    psSource *rc = NULL;
+    // Create the image used in this test.
+    psImage *imgData = psImageAlloc(TST05_NUM_COLS, TST05_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST05_SKY;
+        }
+    }
+
+    //
+    // Create a psPeak with the center pixel set to the peak.
+    //
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST05_NUM_ROWS / 2),
+                                  (psF32) (TST05_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    tmpSource = pmSourceLocalSky(imgData,
+                                 tmpPeak,
+                                 PS_STAT_SAMPLE_MEAN,
+                                 (psF32) TST05_INNER_RADIUS,
+                                 (psF32) TST05_OUTER_RADIUS);
+    if (tmpSource == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        psFree(imgData);
+        psFree(tmpSource);
+        testStatus = false;
+        return(testStatus);
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceMoments with NULL psSource.  Should generate error and return NULL.\n");
+    rc = pmSourceMoments(NULL, 10.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceMoments() returned a non-NULL psSource.\n");
+        testStatus = false;
+    }
+    // XXX: test with psSource->peaks NULL
+    // XXX: test with psSource->pixels NULL
+    // XXX: test with psSource->mask NULL
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceMoments with radius < 0.0.  Should generate error and return NULL.\n");
+    rc = pmSourceMoments(tmpSource, -10.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceMoments() returned a non-NULL psSource.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    psFree(imgData);
+    psFree(tmpSource);
+    return(testStatus);
+
+}
+
+/******************************************************************************
+test07(): We first test the various psMinLM_... routines with various NULL and
+unallowable input parameters.
+ 
+XXX: We don't verify the numbers.  Must do this.
+ *****************************************************************************/
+int test07( void )
+{
+    bool testStatus = true;
+    psF32 rc;
+    psVector *deriv = psVectorAlloc(7, PS_TYPE_F32);
+    psVector *params = psVectorAlloc(7, PS_TYPE_F32);
+    psVector *x = psVectorAlloc(2, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 7 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Gauss2D with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_Gauss2D(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Gauss2D() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Gauss2D with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Gauss2D(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Gauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Gauss2D with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Gauss2D(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Gauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    psFree(deriv);
+    psFree(params);
+
+    deriv = psVectorAlloc(7, PS_TYPE_F32);
+    params = psVectorAlloc(7, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 7 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_PsuedoGauss2D with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_PsuedoGauss2D(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_PsuedoGauss2D() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_PsuedoGauss2D with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_PsuedoGauss2D(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_PsuedoGauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_PsuedoGauss2D with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_PsuedoGauss2D(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_PsuedoGauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    psFree(deriv);
+    psFree(params);
+
+
+    deriv = psVectorAlloc(9, PS_TYPE_F32);
+    params = psVectorAlloc(9, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 9 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Wauss2D with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_Wauss2D(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Wauss2D() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Wauss2D with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Wauss2D(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Wauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Wauss2D with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Wauss2D(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Wauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    psFree(deriv);
+    psFree(params);
+
+    deriv = psVectorAlloc(11, PS_TYPE_F32);
+    params = psVectorAlloc(11, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 11 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_TwistGauss2D with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_TwistGauss2D(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_TwistGauss2D() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_TwistGauss2D with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_TwistGauss2D(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_TwistGauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_TwistGauss2D with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_TwistGauss2D(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_TwistGauss2D() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    psFree(deriv);
+    psFree(params);
+
+    deriv = psVectorAlloc(8, PS_TYPE_F32);
+    params = psVectorAlloc(8, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 8 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Sersic with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_Sersic(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Sersic() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Sersic with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Sersic(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Sersic() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_Sersic with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_Sersic(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_Sersic() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    psFree(deriv);
+    psFree(params);
+
+    deriv = psVectorAlloc(12, PS_TYPE_F32);
+    params = psVectorAlloc(12, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < 12 ; i++) {
+        deriv->data.F32[i] = 1.0;
+        params->data.F32[i] = 1.0;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_SersicCore with NULL deriv vector.  Should not generate error.\n");
+    rc = pmMinLM_SersicCore(NULL, params, x);
+    if (isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_SersicCore() returned a NAN psF32.\n");
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_SersicCore with NULL params vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_SersicCore(deriv, NULL, x);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_SersicCore() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmMinLM_SersicCore with NULL x vector.  Should generate error and return NAN.\n");
+    rc = pmMinLM_SersicCore(deriv, params, NULL);
+    if (!isnan(rc)) {
+        printf("TEST ERROR: pmMinLM_SersicCore() returned a non-NAN psF32 (%f).\n", rc);
+        testStatus = false;
+    }
+
+    psFree(deriv);
+    psFree(params);
+    psFree(x);
+    return(testStatus);
+}
+
+/******************************************************************************
+test08(): We first test pmSourceModelGuess() with various NULL and unallowable
+input parameters.
+ 
+XXX: We don't verify the numbers.
+ *****************************************************************************/
+int test08( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST04_NUM_COLS, TST04_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST04_SKY;
+        }
+    }
+    psSource *mySrc = NULL;
+    bool rc = false;
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST04_NUM_ROWS / 2),
+                                  (psF32) (TST04_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST04_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST04_NUM_COLS / 2);
+    mySrc = pmSourceLocalSky(imgData,
+                             tmpPeak,
+                             PS_STAT_SAMPLE_MEAN,
+                             (psF32) TST04_INNER_RADIUS,
+                             (psF32) TST04_OUTER_RADIUS);
+
+    if (mySrc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with NULL psSource.  Should generate error, return FALSE.\n");
+    rc = pmSourceModelGuess(NULL, imgData, PS_MODEL_GAUSS);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with NULL psImage.  Should generate error, return FALSE.\n");
+    rc = pmSourceModelGuess(mySrc, NULL, PS_MODEL_GAUSS);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with bad model type.  Should generate error, return FALSE.\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_UNDEFINED);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_GAUSS\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_GAUSS);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_PGAUSS\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_PGAUSS);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_TWIST_GAUSS\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_TWIST_GAUSS);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_WAUSS\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_WAUSS);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_SERSIC\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_SERSIC);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceModelGuess with PS_MODEL_SERSIC_CORE\n");
+    rc = pmSourceModelGuess(mySrc, imgData, PS_MODEL_SERSIC_CORE);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    psFree(mySrc);
+    //    psFree(tmpPeak);
+    psFree(imgData);
+    return(testStatus);
+}
+
+
+#define TST09_NUM_ROWS 70
+#define TST09_NUM_COLS 70
+#define TST09_SKY 5.0
+#define TST09_INNER_RADIUS 3
+#define TST09_OUTER_RADIUS 10
+#define LEVEL (TST09_SKY + 10.0)
+/******************************************************************************
+test09(): We first test pmSourceContour() with various NULL and unallowable
+input parameters.
+ 
+XXX: We don't verify the numbers.
+ *****************************************************************************/
+int test09( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST09_NUM_COLS, TST09_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST09_SKY;
+        }
+    }
+    psSource *mySrc = NULL;
+    psArray *rc = NULL;
+
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST09_NUM_ROWS / 2),
+                                  (psF32) (TST09_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST09_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST09_NUM_COLS / 2);
+    mySrc = pmSourceLocalSky(imgData,
+                             tmpPeak,
+                             PS_STAT_SAMPLE_MEAN,
+                             (psF32) TST09_INNER_RADIUS,
+                             (psF32) TST09_OUTER_RADIUS);
+
+    if (mySrc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    }
+
+    bool rcBool = pmSourceModelGuess(mySrc, imgData, PS_MODEL_GAUSS);
+    if (rcBool != true) {
+        printf("TEST ERROR: pmSourceModelGuess() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceContour with NULL psSource .  Should generate error, return NULL.\n");
+    rc = pmSourceContour(NULL, imgData, LEVEL, PS_CONTOUR_CRUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceContour() returned non-NULL.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceContour with NULL psImage .  Should generate error, return NULL.\n");
+    rc = pmSourceContour(mySrc, NULL, LEVEL, PS_CONTOUR_CRUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceContour() returned non-NULL.\n");
+        testStatus = false;
+    }
+
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceContour with acceptable data.\n");
+    printf("NOTE: must figure out the parameters for this test to be meaningful.\n");
+    mySrc->models->params[0] = TST09_SKY;
+    mySrc->models->params[1] = 15.0;
+    mySrc->models->params[2] = (psF32) (TST09_NUM_ROWS / 2);
+    mySrc->models->params[3] = (psF32) (TST09_NUM_COLS / 2);
+    mySrc->models->params[4] = 2.0;
+    mySrc->models->params[5] = 2.0;
+    mySrc->models->params[6] = 2.0;
+    rc = pmSourceContour(mySrc, imgData, LEVEL, PS_CONTOUR_CRUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSourceContour() returned NULL.\n");
+        testStatus = false;
+    }
+
+    psFree(rc);
+    psFree(mySrc);
+    //    psFree(tmpPeak);
+    psFree(imgData);
+    return(testStatus);
+}
+
+#define TST15_NUM_ROWS 100
+#define TST15_NUM_COLS 100
+#define TST15_SKY 10.0
+#define TST15_INNER_RADIUS 3
+#define TST15_OUTER_RADIUS 5
+/******************************************************************************
+test15(): We first test pmSourceAddModel() with various NULL and unallowable
+input parameters.
+ 
+XXX: We don't verify the numbers.
+ *****************************************************************************/
+int test15( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST15_NUM_COLS, TST15_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST15_SKY;
+        }
+    }
+    psSource *mySrc = NULL;
+    psBool rc = false;
+
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST15_NUM_ROWS / 2),
+                                  (psF32) (TST15_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST15_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST15_NUM_COLS / 2);
+    mySrc = pmSourceLocalSky(imgData,
+                             tmpPeak,
+                             PS_STAT_SAMPLE_MEAN,
+                             (psF32) TST15_INNER_RADIUS,
+                             (psF32) TST15_OUTER_RADIUS);
+
+    if (mySrc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    }
+
+    mySrc->models = pmModelAlloc(PS_MODEL_GAUSS);
+    mySrc->models->params[0] = 5.0;
+    mySrc->models->params[1] = 70.0;
+    mySrc->models->params[2] = (psF32) (TST15_NUM_ROWS / 2);
+    mySrc->models->params[3] = (psF32) (TST15_NUM_COLS / 2);
+    mySrc->models->params[4] = 1.0;
+    mySrc->models->params[5] = 1.0;
+    mySrc->models->params[6] = 2.0;
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceAddModel with NULL psImage.  Should generate error, return FALSE.\n");
+    rc = pmSourceAddModel(NULL, mySrc, true);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceAddModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceAddModel with NULL psSrc.  Should generate error, return FALSE.\n");
+    rc = pmSourceAddModel(imgData, NULL, true);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceAddModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceAddModel with acceptable data.\n");
+    rc = pmSourceAddModel(imgData, mySrc, true);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceAddModel() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    psFree(mySrc);
+    psFree(imgData);
+    return(testStatus);
+}
+
+#define TST16_NUM_ROWS 100
+#define TST16_NUM_COLS 100
+#define TST16_SKY 10.0
+#define TST16_INNER_RADIUS 3
+#define TST16_OUTER_RADIUS 5
+/******************************************************************************
+test16(): We first test pmSourceSubModel() with various NULL and unallowable
+input parameters.
+ 
+XXX: We don't verify the numbers.
+ *****************************************************************************/
+int test16( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST16_NUM_COLS, TST16_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST16_SKY;
+        }
+    }
+    psSource *mySrc = NULL;
+    psBool rc = false;
+
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST16_NUM_ROWS / 2),
+                                  (psF32) (TST16_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST16_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST16_NUM_COLS / 2);
+    mySrc = pmSourceLocalSky(imgData,
+                             tmpPeak,
+                             PS_STAT_SAMPLE_MEAN,
+                             (psF32) TST16_INNER_RADIUS,
+                             (psF32) TST16_OUTER_RADIUS);
+
+    if (mySrc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    }
+
+    mySrc->models = pmModelAlloc(PS_MODEL_GAUSS);
+    mySrc->models->params[0] = 5.0;
+    mySrc->models->params[1] = 70.0;
+    mySrc->models->params[2] = (psF32) (TST16_NUM_ROWS / 2);
+    mySrc->models->params[3] = (psF32) (TST16_NUM_COLS / 2);
+    mySrc->models->params[4] = 1.0;
+    mySrc->models->params[5] = 1.0;
+    mySrc->models->params[6] = 2.0;
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSubModel with NULL psImage.  Should generate error, return FALSE.\n");
+    rc = pmSourceSubModel(NULL, mySrc, true);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSubModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSubModel with NULL psSrc.  Should generate error, return FALSE.\n");
+    rc = pmSourceSubModel(imgData, NULL, true);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceSubModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceSubModel with acceptable data.\n");
+    rc = pmSourceSubModel(imgData, mySrc, true);
+    if (rc != true) {
+        printf("TEST ERROR: pmSourceSubModel() returned FALSE.\n");
+        testStatus = false;
+    }
+
+    psFree(mySrc);
+    psFree(imgData);
+    return(testStatus);
+}
+
+#define TST20_NUM_ROWS 100
+#define TST20_NUM_COLS 100
+#define TST20_SKY 10.0
+#define TST20_INNER_RADIUS 3
+#define TST20_OUTER_RADIUS 5
+/******************************************************************************
+test20(): We first test pmSourceSubModel() with various NULL and unallowable
+input parameters.
+ 
+XXX: We don't verify the numbers.
+ *****************************************************************************/
+int test20( void )
+{
+    bool testStatus = true;
+    psImage *imgData = psImageAlloc(TST20_NUM_COLS, TST20_NUM_ROWS, PS_TYPE_F32);
+    for (psS32 i = 0 ; i < imgData->numRows; i++) {
+        for (psS32 j = 0 ; j < imgData->numCols; j++) {
+            imgData->data.F32[i][j] = TST20_SKY;
+        }
+    }
+    psSource *mySrc = NULL;
+    psBool rc = false;
+
+    psPeak *tmpPeak = pmPeakAlloc((psF32) (TST20_NUM_ROWS / 2),
+                                  (psF32) (TST20_NUM_COLS / 2),
+                                  200.0,
+                                  PM_PEAK_LONE);
+
+    printf("Calling pmSourceLocalSky with valid data.\n");
+    tmpPeak->x = (psF32) (TST20_NUM_ROWS / 2);
+    tmpPeak->y = (psF32) (TST20_NUM_COLS / 2);
+    mySrc = pmSourceLocalSky(imgData,
+                             tmpPeak,
+                             PS_STAT_SAMPLE_MEAN,
+                             (psF32) TST20_INNER_RADIUS,
+                             (psF32) TST20_OUTER_RADIUS);
+
+    if (mySrc == NULL) {
+        printf("TEST ERROR: pmSourceLocalSky() returned a NULL psSource.\n");
+        testStatus = false;
+    }
+
+    mySrc->models = pmModelAlloc(PS_MODEL_GAUSS);
+
+
+    mySrc->models->params[0] = 5.0;
+    mySrc->models->params[1] = 70.0;
+    mySrc->models->params[2] = (psF32) (TST20_NUM_ROWS / 2);
+    mySrc->models->params[3] = (psF32) (TST20_NUM_COLS / 2);
+    mySrc->models->params[4] = 1.0;
+    mySrc->models->params[5] = 1.0;
+    mySrc->models->params[6] = 2.0;
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceFitModel with NULL psImage.  Should generate error, return FALSE.\n");
+    rc = pmSourceFitModel(mySrc, NULL);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceFitModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceFitModel with NULL psSource.  Should generate error, return FALSE.\n");
+    rc = pmSourceFitModel(NULL, imgData);
+    if (rc == true) {
+        printf("TEST ERROR: pmSourceFitModel() returned TRUE.\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------------\n");
+    printf("Calling pmSourceFitModel with acceptable data.\n");
+    rc = pmSourceFitModel(mySrc, imgData);
+    printf("pmSourceFitModel returned %d\n", rc);
+
+    // XXX: Memory leaks are not being tested
+    psVector *junk = psVectorAlloc(10, PS_TYPE_F32);
+    junk->data.F32[0] = 0.0;
+
+    psFree(mySrc);
+    psFree(imgData);
+    return(testStatus);
+}
+
+
+// this code will
+
+
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmReadoutCombine.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmReadoutCombine.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmReadoutCombine.c	(revision 22108)
@@ -0,0 +1,451 @@
+/** @file tst_pmReadoutCombine.c
+ *
+ *  test00() This routine will test the basic functionality.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-10 22:22:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: Untested:
+ * S16, S32 types
+ * Multiple input readouts with varying sizes and offsets.
+ * params->fracLow and params->fracHigh
+ * params->nKeep
+ * (gain > 0.0) && (readnoise >= 0.0) (applyZeroScale == true)
+ * (gain > 0.0) && (readnoise >= 0.0) (applyZeroScale == false)
+ *
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmReadoutCombine.h"
+static int test00(void);
+static int test01(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias(): input parameter error conditions", 0, false},
+                              {NULL}
+                          };
+
+#define NUM_READOUTS  10
+#define INPUT_NUM_ROWS 20
+#define INPUT_NUM_COLS 20
+#define VEC_ZERO 1.0
+#define VEC_SCALE 2.0
+
+psS32 VerifyTheOutput(psImage *output, psF32 expect)
+{
+    bool testStatus = true;
+
+    for (psS32 i = 0 ; i < output->numRows ; i++) {
+        for (psS32 j = 0 ; j < output->numCols ; j++) {
+            if (output->data.F32[i][j] != expect) {
+                printf("TEST ERROR: output[%d][%d] is %.2f, should be %f\n", i, j, output->data.F32[i][j], expect);
+                testStatus = false;
+            }
+        }
+    }
+    return(testStatus);
+}
+
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+/******************************************************************************
+simpleCombineNoOverlap(): this routine creates a list of NUM_READOUTS input
+readouts and calls pmReadoutCombine().
+ *****************************************************************************/
+
+int simpleCombineNoOverlap(psS32 numInputCols, psS32 numInputRows)
+{
+    int i;
+    int r;
+    psList *list = NULL;
+    int baseRowsReadout[NUM_READOUTS];
+    int baseColsReadout[NUM_READOUTS];
+    int baseRows[NUM_READOUTS];
+    int baseCols[NUM_READOUTS];
+    int numRows[NUM_READOUTS];
+    int numCols[NUM_READOUTS];
+    int minOutRow = 10000;
+    int minOutCol = 10000;
+    int maxOutRow = -1;
+    int maxOutCol = -1;
+    psImage *output = NULL;
+    psCombineParams *params = (psCombineParams *) psAlloc(sizeof(psCombineParams));
+    psVector *zero = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *scale = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    printPositiveTestHeader(stdout, "pmReadoutCombine", "simpleCombineNoOverlap");
+
+    for (i=0;i<NUM_READOUTS;i++) {
+        zero->data.F32[i] = VEC_ZERO;
+    }
+    for (i=0;i<NUM_READOUTS;i++) {
+        scale->data.F32[i] = VEC_SCALE;
+    }
+
+    params->stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    params->maskVal = 1;
+    params->fracLow = 0.0;
+    params->fracHigh = 10000.0;
+    params->nKeep = 0;
+
+    for (r=0;r<NUM_READOUTS;r++) {
+        baseRowsReadout[r] = r + 40;
+        baseColsReadout[r] = r + 42;
+        baseRows[r] = r;
+        baseCols[r] = r+2;
+        numRows[r] = 4 + (2 * r);
+        numCols[r] = 8 + (2 * r);
+
+        baseRowsReadout[r] = 0;
+        baseColsReadout[r] = 0;
+        baseRows[r] = 0;
+        baseCols[r] = 0;
+        numRows[r] = numInputRows;
+        numCols[r] = numInputCols;
+
+        psImage *tmpImage = psImageAlloc(numCols[r], numRows[r], PS_TYPE_F32);
+        PS_IMAGE_SET_F32(tmpImage, ((float) r));
+        *(int *) (& (tmpImage->row0)) = baseRows[r];
+        *(int *) (& (tmpImage->col0)) = baseCols[r];
+        /*
+                psReadout *tmpReadout = psReadoutAlloc(baseColsReadout[r],
+                                                       baseRowsReadout[r],
+                                                       tmpImage);
+        */
+        psReadout *tmpReadout = psReadoutAlloc();
+        tmpReadout->image = tmpImage;
+
+        minOutRow = PS_MIN(minOutRow, (baseRowsReadout[r] + baseRows[r]));
+        minOutCol = PS_MIN(minOutCol, (baseColsReadout[r] + baseCols[r]));
+        maxOutRow = PS_MAX(maxOutRow, (baseRowsReadout[r] + baseRows[r] + numRows[r]));
+        maxOutCol = PS_MAX(maxOutCol, (baseColsReadout[r] + baseCols[r] + numCols[r]));
+
+        if (r == 0) {
+            list = psListAlloc(tmpReadout);
+        } else {
+            psListAdd(list, PS_LIST_HEAD, tmpReadout);
+        }
+    }
+    printf("tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (%d, %d) (%d, %d)\n",
+           minOutRow, minOutCol, maxOutRow, maxOutCol);
+
+    output = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    psF32 NR = (psF32) NUM_READOUTS;
+    //    psF32 expectedPixel = ((((NR-1.0) * (NR/2.0)) / NR) + VEC_ZERO) * VEC_SCALE;
+    psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+    VerifyTheOutput(output, expectedPixel);
+
+    psFree(params->stats);
+    psFree(params);
+    psFree(output);
+    psFree(zero);
+    psFree(scale);
+
+    psListElem *tmpInput = (psListElem *) list->head;
+    while (NULL != tmpInput) {
+        psReadout *tmpReadout = (psReadout *) tmpInput->data;
+        psFree(tmpReadout);
+        tmpInput = tmpInput->next;
+    }
+    psFree(list);
+
+    printFooter(stdout, "pmReadoutCombine", "simpleCombineNoOverlap", true);
+    return(0);
+}
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= simpleCombineNoOverlap(1, 1);
+    testStatus |= simpleCombineNoOverlap(INPUT_NUM_COLS, 1);
+    testStatus |= simpleCombineNoOverlap(1, INPUT_NUM_ROWS);
+    testStatus |= simpleCombineNoOverlap(INPUT_NUM_COLS, INPUT_NUM_ROWS);
+
+    return(testStatus);
+}
+
+int test01()
+{
+    int i;
+    int r;
+    psList *list = NULL;
+    int baseRowsReadout[NUM_READOUTS];
+    int baseColsReadout[NUM_READOUTS];
+    int baseRows[NUM_READOUTS];
+    int baseCols[NUM_READOUTS];
+    int numRows[NUM_READOUTS];
+    int numCols[NUM_READOUTS];
+    int minOutRow = 10000;
+    int minOutCol = 10000;
+    int maxOutRow = -1;
+    int maxOutCol = -1;
+    psImage *output = NULL;
+    psImage *rc = NULL;
+    psCombineParams *params = (psCombineParams *) psAlloc(sizeof(psCombineParams));
+    psVector *zero = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *zeroHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *zeroBig = psVectorAlloc(NUM_READOUTS+1, PS_TYPE_F32);
+    psVector *zeroF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    psVector *scale = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *scaleHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *scaleBig = psVectorAlloc(NUM_READOUTS*2, PS_TYPE_F32);
+    psVector *scaleF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    int testStatus = true;
+    for (i=0;i<NUM_READOUTS;i++) {
+        zero->data.F32[i] = 3.0;
+        zeroBig->data.F32[i] = 3.0;
+        zero->data.F32[i] = VEC_ZERO;
+        zeroBig->data.F32[i] = VEC_ZERO;
+    }
+    for (i=0;i<NUM_READOUTS;i++) {
+        scale->data.F32[i] = 6.0;
+        scaleBig->data.F32[i] = 6.0;
+        scale->data.F32[i] = VEC_SCALE;
+        scaleBig->data.F32[i] = VEC_SCALE;
+    }
+    printPositiveTestHeader(stdout, "pmReadoutCombine", "Testing bad input parameter conditions");
+
+    params->stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    params->maskVal = 1;
+    params->fracLow = 0.0;
+    params->fracHigh = 10000.0;
+    params->nKeep = 0;
+
+    for (r=0;r<NUM_READOUTS;r++) {
+        baseRowsReadout[r] = 0;
+        baseColsReadout[r] = 0;
+        baseRows[r] = 0;
+        baseCols[r] = 0;
+        numRows[r] = INPUT_NUM_ROWS;
+        numCols[r] = INPUT_NUM_COLS;
+
+        psImage *tmpImage = psImageAlloc(numCols[r], numRows[r], PS_TYPE_F32);
+        PS_IMAGE_SET_F32(tmpImage, ((float) r));
+        *(int *) (& (tmpImage->row0)) = baseRows[r];
+        *(int *) (& (tmpImage->col0)) = baseCols[r];
+        /*
+                psReadout *tmpReadout = psReadoutAlloc(baseColsReadout[r],
+                                                       baseRowsReadout[r],
+                                                       tmpImage);
+        */
+        psReadout *tmpReadout = psReadoutAlloc();
+        tmpReadout->image = tmpImage;
+        minOutRow = PS_MIN(minOutRow, (baseRowsReadout[r] + baseRows[r]));
+        minOutCol = PS_MIN(minOutCol, (baseColsReadout[r] + baseCols[r]));
+        maxOutRow = PS_MAX(maxOutRow, (baseRowsReadout[r] + baseRows[r] + numRows[r]));
+        maxOutCol = PS_MAX(maxOutCol, (baseColsReadout[r] + baseCols[r] + numCols[r]));
+
+        if (r == 0) {
+            list = psListAlloc(tmpReadout);
+        } else {
+            psListAdd(list, PS_LIST_HEAD, tmpReadout);
+        }
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL zero vector.\n");
+    rc = pmReadoutCombine(NULL, list, params, NULL, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (0.0 + (0.0 + VEC_SCALE * (NR - 1)))) / NR;
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+
+        if (rc->type.type != scale->type.type) {
+            printf("TEST ERROR: output readout->image has incorrect type.\n");
+            testStatus = false;
+        }
+        psFree(rc);
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroHalf, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type zero vector.  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroF64, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zeroBig, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL scale vector.\n");
+    rc = pmReadoutCombine(output, list, params, zero, NULL, true, 0.0, 0.0);
+
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + 1.0 * (NR - 1)))) / NR;
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+
+        if (rc->type.type != scale->type.type) {
+            printf("TEST ERROR: output readout->image has incorrect type.\n");
+            testStatus = false;
+        }
+        psFree(rc);
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleHalf, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type scale vector.  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleF64, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleBig, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() insufficient size output image.  Should generate error, return NULL.\n");
+    output = psImageAlloc(1, 1, PS_TYPE_F32);
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    psFree(output);
+    output = NULL;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() row0/col0 too large.  Should generate error, return NULL.\n");
+    output = psImageAlloc(1, 1, PS_TYPE_F32);
+    *(psS32*)&output->row0 = 10000;
+    *(psS32*)&output->col0 = 10000;
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    psFree(output);
+    output = NULL;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL input list.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, NULL, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL params.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, NULL, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    psStatsOptions oldStatsOpts = params->stats->options |= PS_STAT_MIN;
+    printf("Calling pmReadoutCombine() with multiple stats->options.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats->options = oldStatsOpts;
+
+    printf("----------------------------------------------------------------------------\n");
+    psStats *oldStats = params->stats;
+    printf("Calling pmReadoutCombine() with NULL param->stats.  Should generate error, return NULL.\n");
+    params->stats = NULL;
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats = oldStats;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("============================================================================\n");
+
+    psFree(params->stats);
+    psFree(params);
+    //    psFree(output);
+    //    psFree(rc);
+    psFree(zero);
+    psFree(zeroHalf);
+    psFree(zeroBig);
+    psFree(zeroF64);
+    psFree(scale);
+    psFree(scaleHalf);
+    psFree(scaleBig);
+    psFree(scaleF64);
+    psListElem *tmpInput = (psListElem *) list->head;
+    while (NULL != tmpInput) {
+        psReadout *tmpReadout = (psReadout *) tmpInput->data;
+        psFree(tmpReadout);
+        tmpInput = tmpInput->next;
+    }
+    psFree(list);
+
+    printFooter(stdout, "pmReadoutCombine", "Testing bad input parameter conditions", true);
+    return(!testStatus);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractBias.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractBias.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractBias.c	(revision 22108)
@@ -0,0 +1,1093 @@
+/** @file tst_pmSubtractBias.c
+ *
+ *  @brief Contains the tests for pmSubtractBias.c:
+ *
+ * test00: This code will subtract full bias frames from the input image.
+ * test01: Multiple overscan regions, calculate a scalar statistic for
+ *  each, then subtract from the input image.
+ * test02: Calculate a column overscan vector and subtract it from each
+ *  column in the input image.
+ * test03: Calculate a row overscan vector and subtract it from each
+ *  row in the input image.
+ * test04: 
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-03-31 02:01:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmSubtractBias.h"
+static int test00(void);
+static int test01(void);
+static int test02(void);
+static int test03(void);
+static int test04(void);
+static int testX(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias", 0, false},
+                              {test02, 000, "pmSubtractBias", 0, false},
+                              {test03, 000, "pmSubtractBias", 0, false},
+                              {test04, 000, "pmSubtractBias", 0, false},
+                              {testX,  000, "pmSubtractBias", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+#define NUM_ROWS 8
+#define NUM_COLS 8
+/******************************************************************************
+doSubtractBiasFullFrame(): a sample psReadout as well as a bias image are
+created and the bias image is subtracted from the psReadout.
+ *****************************************************************************/
+int doSubtractBiasFullFrame(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    //    psReadout *myBias = psReadoutAlloc(numCols, numRows, tmpImage2);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *myBias = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    myBias->image = tmpImage2;
+
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractBiasFullFrame");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            myBias->image->data.F32[i][j] = 1.0;
+        }
+    }
+
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBias);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 1.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myBias);
+    printFooter(stdout, "pmSubtractBias", "doSubtractBiasFullFrame", true);
+    return(testStatus);
+}
+
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractBiasFullFrame(1, 1);
+    testStatus |= doSubtractBiasFullFrame(NUM_COLS, 1);
+    testStatus |= doSubtractBiasFullFrame(1, NUM_ROWS);
+    testStatus |= doSubtractBiasFullFrame(NUM_COLS, NUM_ROWS);
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are then subtracted
+from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscans(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractFullOverscans");
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ALL, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "doSubtractFullOverscans", true);
+    return(testStatus);
+}
+
+int test01( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscans(1, 1);
+    testStatus |= doSubtractFullOverscans(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscans(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscans(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumns(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_COLUMNS, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsPoly(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
+
+    myReadout = pmSubtractBias(myReadout, myPoly, list, PM_OVERSCAN_COLUMNS, stat,
+                               0, PM_FIT_POLYNOMIAL, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+    psFree(myPoly);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsSmall(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psImage *tmpImage2 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+    for (i=0;i<numRows/2;i++) {
+        for (j=0;j<numCols/2;j++) {
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_COLUMNS, stat,
+                               0, PM_FIT_POLYNOMIAL, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+
+int test02( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscanColumns(1, 1);
+    testStatus |= doSubtractFullOverscanColumns(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, NUM_ROWS);
+    /* These tests do not make sense until the SDRS is clarified.
+        testStatus |= doSubtractFullOverscanColumnsSmall(1, 1);
+        testStatus |= doSubtractFullOverscanColumnsSmall(1, NUM_ROWS);
+        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, 1);
+        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, NUM_ROWS);
+    */
+
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted row-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanRows(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Row Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Row Overscans", true);
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted row-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanRowsSmall(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psS32 OSnumRows = numRows-1;
+    if (OSnumRows == 0) {
+        OSnumRows = 1;
+    }
+    psS32 OSnumCols = numCols-1;
+    if (OSnumCols == 0) {
+        OSnumCols = 1;
+    }
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+    for (i=0;i<OSnumRows;i++) {
+        for (j=0;j<OSnumCols;j++) {
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Row Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
+                               0, PM_FIT_SPLINE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Row Overscans", true);
+    return(testStatus);
+}
+
+
+int test03( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscanRows(1, 1);
+    testStatus |= doSubtractFullOverscanRows(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanRows(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanRows(NUM_COLS, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanRowsSmall(1, 1);
+    testStatus |= doSubtractFullOverscanRowsSmall(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+
+
+int doSubtractOverscansTestInputCases(int numCols, int numRows)
+{
+    int i;
+    int j;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psImage *tmpImage3Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psImage *tmpImage4Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psReadout *rc = NULL;
+    psList *list;
+    psList *listShort;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psImage *tmpImage5 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myBias = psReadoutAlloc();
+    myBias->image = tmpImage5;
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Testing input parameter error conditions");
+
+    psImage *tmpImage5ShortRows = psImageAlloc(numCols, numRows-1, PS_TYPE_F32);
+    psReadout *myBiasShortRows = psReadoutAlloc();
+    myBiasShortRows->image = tmpImage5ShortRows;
+    psImage *tmpImage5ShortCols = psImageAlloc(numCols-1, numRows, PS_TYPE_F32);
+    psReadout *myBiasShortCols = psReadoutAlloc();
+    myBiasShortCols->image = tmpImage5ShortCols;
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+            myBias->image->data.F32[i][j] = 1.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    for (i=0;i<numRows-1;i++) {
+        for (j=0;j<numCols-1;j++) {
+            tmpImage2Short->data.F32[i][j] = 3.0;
+            tmpImage3Short->data.F32[i][j] = 4.0;
+            tmpImage4Short->data.F32[i][j] = 5.0;
+        }
+    }
+    listShort = psListAlloc(tmpImage2Short);
+    psListAdd(listShort, PS_LIST_HEAD, tmpImage3Short);
+    psListAdd(listShort, PS_LIST_HEAD, tmpImage4Short);
+    for (i=0;i<numRows-1;i++) {
+        for (j=0;j<numCols;j++) {
+            myBiasShortRows->image->data.F32[i][j] = 1.0;
+        }
+    }
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols-1;j++) {
+            myBiasShortCols->image->data.F32[i][j] = 1.0;
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ALL.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_ALL, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ROWS.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_ROWS, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_COLUMNS.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_COLUMNS, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with non-NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_NONE, stat, 0, PM_FIT_NONE, myBias);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    /* XXX: This does not seem to be a requirement.
+        printf("------------------------------------------------------------------\n");
+        printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
+        rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat,
+                            0, PM_FIT_NONE, myBias);
+     
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 1.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+     
+                // Restore myReadout for next test.
+                myReadout->image->data.F32[i][j] = (float) (i + j);
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with PM_OVERSCAN_NONE and PM_FIT_POLYNOMIAL.  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat, 0, PM_FIT_POLYNOMIAL, myBias);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with PM_OVERSCAN_ALL and PM_FIT_SPLINE.  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat, 0, PM_FIT_SPLINE, myBias);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with multiple stats->options.  Should generate Warning.\n");
+    stat->options|= PS_STAT_SAMPLE_MEDIAN;
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ALL, stat,
+                               0, PM_FIT_NONE, NULL);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 12.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+    stat->options = PS_STAT_SAMPLE_MEAN;
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_ROWS).  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_ROWS, stat,
+                        0, PM_FIT_NONE, NULL);
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_COLUMNS).  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_COLUMNS, stat,
+                        0, PM_FIT_NONE, NULL);
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize bias image (short rows).  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBiasShortRows);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize bias image (short columns).  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBiasShortCols);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with bogus PM_FIT.  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
+                               0, 54321, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with bogus overScanAxis.  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, list, 54321, stat,
+                               0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(tmpImage2Short);
+    psFree(tmpImage3Short);
+    psFree(tmpImage4Short);
+    psFree(myBias);
+    psFree(myBiasShortRows);
+    psFree(myBiasShortCols);
+    psFree(stat);
+    psFree(list);
+    psFree(listShort);
+
+    printFooter(stdout, "pmSubtractBias", "Testing input parameter error conditions", true);
+    return(testStatus);
+}
+
+int test04( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractOverscansTestInputCases(NUM_COLS, NUM_ROWS);
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsGeneric(int imageNumCols,
+        int imageNumRows,
+        int overscanNumCols,
+        int overscanNumRows,
+        pmOverscanAxis overscanaxis,
+        pmFit fit,
+        psS32 nBin)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+
+    psImage *tmpImage1 = psImageAlloc(imageNumCols, imageNumRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(imageNumCols, imageNumRows, tmpImage1);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    for (i=0;i<imageNumRows;i++) {
+        for (j=0;j<imageNumCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    psSpline1D *mySpline = NULL;
+
+
+    /*
+        if (overscanNumRows <= 0) {
+            overscanNumRows = 1;
+        }
+        if (overscanNumCols <= 0) {
+            overscanNumCols = 1;
+        }
+    */
+    psImage *tmpImage2 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psList *list;
+    for (i=0;i<overscanNumRows;i++) {
+        for (j=0;j<overscanNumCols;j++) {
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
+
+    if (fit == PM_FIT_NONE) {
+        myReadout = pmSubtractBias(myReadout, NULL, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    } else if (fit == PM_FIT_POLYNOMIAL) {
+        myReadout = pmSubtractBias(myReadout, myPoly, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    } else if (fit == PM_FIT_SPLINE) {
+        myReadout = pmSubtractBias(myReadout, mySpline, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    }
+
+    for (i=0;i<imageNumRows;i++) {
+        for (j=0;j<imageNumCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+    psFree(myPoly);
+    psFree(mySpline);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+
+int testX( void )
+{
+    int testStatus = 0;
+
+    // imageNumCols, imageNumRows, overscanNumCols, overscanNumRows,
+    // overscanaxis, fit, nBin
+
+    //
+    // Overscan images are same size, no fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_NONE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_NONE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_NONE, 1);
+
+    //
+    // Overscan images are same size, no fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_NONE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_NONE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_NONE, 2);
+    //
+    // Overscan images are too small, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+    //
+    // Overscan images are too small, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+    //
+    // Overscan images are same size, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+    //
+    // Overscan images are same size, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    return(testStatus);
+}
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractSky.c
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractSky.c	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/tst_pmSubtractSky.c	(revision 22108)
@@ -0,0 +1,365 @@
+/** @file tst_pmSubtractSky.c
+ *
+ *  @brief Contains the tests for pmSubtractSky.c:
+ *
+ * test00: This code will ...
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-03-31 20:41:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmSubtractSky.h"
+#define NUM_ROWS 512
+#define NUM_COLS 512
+#define POLY_X_ORDER 3
+#define POLY_Y_ORDER 3
+#define ERROR_TOLERANCE 1.0
+#define OBJECT_INTENSITY 2000.0
+static int test00(void);
+static int test01(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractSky", 0, false},
+                              {test01, 000, "pmSubtractSky: warning, error messages", 0, false},
+                              {NULL}
+                          };
+
+float func(int i, int j)
+{
+    return((float) (i + j));
+}
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+    //    test00();
+}
+
+/******************************************************************************
+ *****************************************************************************/
+int doSubtractSkySimple(int numCols, int numRows, int binFactor)
+{
+    int i;
+    int j;
+    int testStatus = 0;
+    psImage *tmpImageF32 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "doSubtractSkySimple");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+
+    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+                              binFactor, myStats, 10.0);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            if (ERROR_TOLERANCE < fabs(myReadout->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j, myReadout->image->data.F32[i][j]);
+                testStatus = 1;
+            }
+        }
+    }
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    printFooter(stdout, "pmSubtractSky", "doSubtractSkySimple", true);
+    return(testStatus);
+}
+
+/******************************************************************************
+ *****************************************************************************/
+int doSubtractSkyWithObjects(int numCols, int numRows, int binFactor)
+{
+    int i;
+    int j;
+    int testStatus = 0;
+    psImage *tmpImageF32 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+    psImage *trueImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psF32 errorTolerance = ERROR_TOLERANCE * ((psF32) binFactor);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "doSubtractSkyWithObjects");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+    // We insert a few bright spots in the image.
+    myReadout->image->data.F32[NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[3*NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[3*NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    PS_IMAGE_SET_F32(trueImage, 0.0);
+    trueImage->data.F32[NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[3*NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[3*NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+
+    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+                              binFactor, myStats, 2.0);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            if (errorTolerance < fabs(myReadout->image->data.F32[i][j] - trueImage->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j,
+                       myReadout->image->data.F32[i][j], trueImage->data.F32[i][j]);
+                testStatus = 1;
+            }
+        }
+    }
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    psFree(trueImage);
+    printFooter(stdout, "pmSubtractSky", "doSubtractSkyWithObjects", true);
+    return(testStatus);
+}
+
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    psTraceSetLevel(".", 0);
+
+    // Bin Factor == 1
+    printf("doSubtractSkySimple(1, 1, 1)\n");
+    testStatus |= doSubtractSkySimple(1, 1, 1);
+    printf("doSubtractSkySimple(NUM_COLS, 1, 1)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, 1, 1);
+
+    printf("doSubtractSkySimple(1, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkySimple(1, NUM_ROWS, 1);
+    printf("doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1);
+
+    // Bin Factor == 2
+    printf("doSubtractSkySimple(1, 1, 2)\n");
+    testStatus |= doSubtractSkySimple(1, 1, 2);
+    printf("doSubtractSkySimple(NUM_COLS, 1, 2)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, 1, 2);
+    printf("doSubtractSkySimple(1, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkySimple(1, NUM_ROWS, 2);
+    printf("doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2);
+
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 4)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8);
+
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256);
+
+    return(testStatus);
+}
+
+#define NUM_ROWS_SMALL 16
+#define NUM_COLS_SMALL 16
+int test01( void )
+{
+    int testStatus = 0;
+    psS32 i;
+    psS32 j;
+    psImage *tmpImageF32 = psImageAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, PS_TYPE_F32);
+    psImage *tmpImageF64 = psImageAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, PS_TYPE_F64);
+    //    psReadout *myReadout = psReadoutAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psReadout *rc = NULL;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "Testing bad input parameter conditions.");
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL psReadout.  Should error.\n\n");
+    rc = pmSubtractSky(NULL, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL psReadout->image.  Should error.\n\n");
+    myReadout->image = NULL;
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImageF32;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PS_TYPE_F64 psReadout->image.  Should error.\n\n");
+    myReadout->image = tmpImageF64;
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImageF32;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL fitSpec.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, NULL, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PM_FIT_NONE fit.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_NONE, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PM_FIT_SPLINE fit.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_SPLINE, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL myStats.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, NULL, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    psU64 oldOptions = myStats->options;
+    myStats->options = 0;
+    printf("Calling pmSubtractSky() with no myStats->options specified.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+    myStats->options = oldOptions;
+
+    printf("----------------------------------------------------------------\n");
+    oldOptions = myStats->options;
+    myStats->options = PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN;
+    printf("Calling pmSubtractSky() with multiple myStats->options specified.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+    myStats->options = oldOptions;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with 0 binFactor.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 0, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with -1 binFactor.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, -1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with -1.0 clipSD.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, -1.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with bogus psFit.  Should generate Error.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, 54321, 1, myStats, -1.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+
+    //    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+    //                              1, myStats, 2.0);
+
+
+    printf("----------------------------------------------------------------\n");
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    psFree(tmpImageF64);
+    printFooter(stdout, "pmSubtractSky", "Testing bad input parameter conditions.", true);
+    return(testStatus);
+}
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stderr	(revision 22108)
@@ -0,0 +1,29 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: Test Point Driver{pmFlatField}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Null not allowed for flat readout.
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Null not allowed for input image.
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Null not allowed for flat image.
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Input image size exceeds that of flat image: (3, 3) vs (2, 2)
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Input image mask size exceeds that of flat image: (4, 4) vs (3, 3)
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Total offset >= flat image size: (50, 50) vs (3, 3)
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Complex types not allowed for input image. Type: 2064
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Complex types not allowed for flat image. Type: 2064
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Input and flat image types differ: (1032 vs 1028)
+<DATE><TIME>|<HOST>|E|pmFlatField (FILE:LINENO)
+    Mask must be PS_TYPE_MASK type. Type: 1028
+
+---> TESTPOINT PASSED (Test Point Driver{pmFlatField} | tst_pmFlatField.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmFlatField.stdout	(revision 22108)
@@ -0,0 +1,236 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test A - Divide input image by flat image}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+6.000000 6.000000 6.000000 
+6.000000 6.000000 6.000000 
+6.000000 6.000000 6.000000 
+
+Flat image:
+2.000000 2.000000 2.000000 
+2.000000 2.000000 2.000000 
+2.000000 2.000000 2.000000 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test A - Divide input image by flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test B - Mask flat image data}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+Flat image:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+
+Resulting mask:
+8 8 8 
+8 8 8 
+8 8 8 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test B - Mask flat image data} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test C - Mask flat image data starting with non-null mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+Flat image:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+3.000000 -3.000000 0.000000 
+
+Flat image out:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+3.000000 0.000000 0.000000 
+
+Resulting mask:
+8 8 8 
+8 8 8 
+0 8 8 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+1.000000 3.000000 3.000000 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test C - Mask flat image data starting with non-null mask} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test D - Attempt to use null flat readout}     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for flat readout                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test D - Attempt to use null flat readout} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test E - Attempt to use null input image}      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for input image                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test E - Attempt to use null input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test F - Attempt tp use null flat image}       *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for flat image                            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test F - Attempt tp use null flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test G - Attempt to use input image bigger than flat image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input image size exceeds that of flat image                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test G - Attempt to use input image bigger than flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test H - Attempt to use input image mask bigger than flat image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input image mask size exceeds that of flat image           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test H - Attempt to use input image mask bigger than flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test I - Attempt to use offset greater than input image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Total offset >= input image size                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test I - Attempt to use offset greater than input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test J - Attempt to use complex input image}   *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Complex types not allowed for input image                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test J - Attempt to use complex input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test K - Attempt to use complex flat image}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Complex types not allowed for flat image                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test K - Attempt to use complex flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test L - Attempt to use non-equal input and flat image types} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and flat image types differ                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test L - Attempt to use non-equal input and flat image types} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test M - Attempt to use non-mask type mask image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Mask must be PS_TYPE_MASK type                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test M - Attempt to use non-mask type mask image} | tst_pmFlatField.c)
+
+
+
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 22108)
@@ -0,0 +1,113 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on maskVal argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on maskVal argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on saturation argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on saturation argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on growVal and grow argum *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on growVal and grow arguments} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Auto create mask based on maskVal argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Auto create mask based on maskVal argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use null mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Null not allowed for mask image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use null mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt tp use null input image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Null not allowed for input image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt tp use null input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use input image bigger than mask *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Input image size exceeds that of mask image: (60, 60) vs (50, 50)
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use input image bigger than mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use input image mask bigger than *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Input image mask size exceeds that of mask image: (60, 60) vs (50, 50)
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use input image mask bigger than mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use offset greater than input im *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Total offset >= mask image: (150, 150) vs (50, 50)
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use offset greater than input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use complex input image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Complex types not allowed for input image. Type: 2064
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use complex input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use non-mask type mask image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMaskBadPixels (FILE:LINENO)
+    Mask must be PS_TYPE_MASK type. Type: 1032
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use non-mask type mask image} | tst_pmMaskBadPixels.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 22108)
@@ -0,0 +1,416 @@
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00010000000000000000000000000000000000000000001000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000001111111111100000000000000000000
+11111110000000000000011111110000000000000001111111
+11111111100000000000000000000000000000000111111111
+11111111110000000000000000000000000000001111111111
+11111111111000000000000000000000000000011111111111
+11111111111100000000000000000000000000111111111111
+11111111111110000000000000000000000001111111111111
+11111111111110000000000000000000000001111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111110000000000000000000000001111111111111
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stderr	(revision 22108)
@@ -0,0 +1,72 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityPolynomial}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityPolynomial} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityLookup}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityLookup} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityPolynomial(): error/warning conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (FILE:LINENO)
+    Unallowable operation: inputReadout is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (FILE:LINENO)
+    Unallowable operation: inputReadout->image is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (FILE:LINENO)
+    Unallowable operation: input1DPoly is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityPolynomial(): error/warning conditions} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityLookup(): error/warning conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (FILE:LINENO)
+    Unallowable operation: inputReadout is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (FILE:LINENO)
+    Unallowable operation: inputReadout->image is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (FILE:LINENO)
+    Unallowable operation: inFlux is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (FILE:LINENO)
+    Unallowable operation: outFlux is NULL.
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (24, 25)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (24, 23)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (23, 24)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (25, 24)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (23, 25)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (25, 23)
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (FILE:LINENO)
+    pmNonLinearityLookup(): input vector less than 2 elements.  Returning inputReadout image.
+<DATE><TIME>|<HOST>|W|vectorBinDisectF32
+    vectorBinDisectF32(): ordinate -1.000000 is outside vector range (0.000000 - 23.000000).
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): 1 pixels outside table.
+<DATE><TIME>|<HOST>|W|vectorBinDisectF32
+    vectorBinDisectF32(): ordinate 100.000000 is outside vector range (0.000000 - 23.000000).
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): 1 pixels outside table.
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityLookup(): error/warning conditions} | tst_pmNonLinear.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmNonLinear.stdout	(revision 22108)
@@ -0,0 +1,115 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{Testing bad input parameter conditions.}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL input readout.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL input readout->image.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL polynomial.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL input psReadout.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL input psReadout->image.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL inFlux psVector.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL outFlux psVector.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with inFlux psVector size 1.  Should generate error, return original psReadout.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with image values not in vector.
+
+---> TESTPOINT PASSED (pmNonLinear{Testing bad input parameter conditions.} | tst_pmNonLinear.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stderr	(revision 22108)
@@ -0,0 +1,237 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: structure allocators and deallocators} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: structure allocators and deallocators} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: psFindVectorPeaks()}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmFindVectorPeaks (FILE:LINENO)
+    Unallowable operation: psVector vector or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmFindVectorPeaks (FILE:LINENO)
+    Unallowable operation: psVector vector has no elements.
+<DATE><TIME>|<HOST>|E|pmFindVectorPeaks (FILE:LINENO)
+    Unallowable operation: psVector vector has incorrect type.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: psFindVectorPeaks()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: psFindImagePeaks()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psImageAlloc (FILE:LINENO)
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|E|pmFindImagePeaks (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmFindImagePeaks (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmFindImagePeaks (FILE:LINENO)
+    Unallowable operation: psImage image has incorrect type.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: psFindImagePeaks()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmCullPeaks()}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmCullPeaks (FILE:LINENO)
+    Unallowable operation: peaks is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmCullPeaks()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceLocalSky()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Unallowable operation: psImage image has incorrect type.
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Unallowable operation: peak is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Error: (0.0 > innerRadius) (0.000000 -10.000000)
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Error: (innerRadius > outerRadius) (10.000000 5.000000)
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Sub image startRow is outside image boundaries (-19).
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Sub image endRow is outside image boundaries (120).
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Sub image startCol is outside image boundaries (-19).
+<DATE><TIME>|<HOST>|E|pmSourceLocalSky (FILE:LINENO)
+    Sub image endCol is outside image boundaries (105).
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceLocalSky()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceSetPixelCircle()}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Unallowable operation: source is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Unallowable operation: psImage image has incorrect type.
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Error: (0.0 > radius) (0.000000 -10.000000)
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Sub image startCol is outside image boundaries (-9).
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Sub image endCol is outside image boundaries (110).
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Sub image startRow is outside image boundaries (-9).
+<DATE><TIME>|<HOST>|E|pmSourceSetPixelCircle (FILE:LINENO)
+    Sub image endRow is outside image boundaries (110).
+<DATE><TIME>|<HOST>|W|pmSourceSetPixelCircle
+    WARNING: pmSourceSetPixelCircle(): image->pixels not NULL.  Freeing and reallocating.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceSetPixelCircle()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceMoments()}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceMoments (FILE:LINENO)
+    Unallowable operation: source is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceMoments (FILE:LINENO)
+    Error: (0.0 > radius) (0.000000 -10.000000)
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceMoments()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmMin()}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmMinLM_Gauss2D (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_Gauss2D (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_PsuedoGauss2D (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_PsuedoGauss2D (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_Wauss2D (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_Wauss2D (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_TwistGauss2D (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_TwistGauss2D (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_Sersic (FILE:LINENO)
+    This function is not implemented yet.
+<DATE><TIME>|<HOST>|E|pmMinLM_Sersic (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_Sersic (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_SersicCore (FILE:LINENO)
+    This function is not implemented yet.
+<DATE><TIME>|<HOST>|E|pmMinLM_SersicCore (FILE:LINENO)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmMinLM_SersicCore (FILE:LINENO)
+    Unallowable operation: psVector x or its data is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmMin()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceModelGuess()}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceModelGuess (FILE:LINENO)
+    Unallowable operation: source is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceModelGuess (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmModelAlloc (FILE:LINENO)
+    Undefined psModelType
+<DATE><TIME>|<HOST>|E|pmSourceModelGuess (FILE:LINENO)
+    Undefined psModelType
+<DATE><TIME>|<HOST>|W|pmSourceModelGuess
+    WARNING: source->models was non-NULL; calling psFree(source->models).
+<DATE><TIME>|<HOST>|W|pmSourceModelGuess
+    WARNING: source->models was non-NULL; calling psFree(source->models).
+<DATE><TIME>|<HOST>|W|pmSourceModelGuess
+    WARNING: source->models was non-NULL; calling psFree(source->models).
+<DATE><TIME>|<HOST>|W|pmSourceModelGuess
+    WARNING: source->models was non-NULL; calling psFree(source->models).
+<DATE><TIME>|<HOST>|W|pmSourceModelGuess
+    WARNING: source->models was non-NULL; calling psFree(source->models).
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceModelGuess()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceContour()}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceContour (FILE:LINENO)
+    Unallowable operation: source is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceContour (FILE:LINENO)
+    Unallowable operation: image is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceContour (FILE:LINENO)
+    Could not find contour edge (NAN)
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceContour()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceAddModel()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|p_pmSourceAddOrSubModel (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|p_pmSourceAddOrSubModel (FILE:LINENO)
+    Unallowable operation: src is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceAddModel()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceSubModel()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|p_pmSourceAddOrSubModel (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|p_pmSourceAddOrSubModel (FILE:LINENO)
+    Unallowable operation: src is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceSubModel()} | tst_pmObjects01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmObjects01.c                                          *
+*            TestPoint: Test Point Driver{pmObjects: pmSourceSubModel()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSourceFitModel (FILE:LINENO)
+    Unallowable operation: psImage image or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSourceFitModel (FILE:LINENO)
+    Unallowable operation: source is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmObjects: pmSourceSubModel()} | tst_pmObjects01.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmObjects01.stdout	(revision 22108)
@@ -0,0 +1,189 @@
+----------------------------------------------------------------------------------
+Calling pmFindVectorPeaks with NULL psVector.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmFindVectorPeaks with empty psVector.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmFindVectorPeaks with PS_TYPE_F64 psVector.  Should generate error and return NULL.
+-------------- Calling test_pmFindVectorPeaks on an 1 size vector. --------------
+Test pmFindVectorPeaks() with a first-element peak.
+Test pmFindVectorPeaks() with a first-element peak, large threshold.
+-------------- Calling test_pmFindVectorPeaks on an 10 size vector. --------------
+Test pmFindVectorPeaks() with a first-element peak.
+Test pmFindVectorPeaks() with a first-element peak, large threshold.
+Test pmFindVectorPeaks() with a last-element peak.
+Test pmFindVectorPeaks() with a last-element peak, large threshold.
+Test pmFindVectorPeaks() with all even-numbered elements peak.
+Test pmFindVectorPeaks() with all even-numbered elements peak, large threshold.
+----------------------------------------------------------------------------------
+Calling pmFindImagePeaks with NULL psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmFindImagePeaks with empty psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmFindImagePeaks with PS_TYPE_F64 psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+-------------- Calling test_pmFindVectorPeaks on an 10-by-10 image. --------------
+(200.0) (41.0) (34.0) (29.0) (26.0) (25.0) (26.0) (29.0) (34.0) (200.0) 
+(41.0) (32.0) (25.0) (20.0) (17.0) (16.0) (17.0) (20.0) (25.0) (32.0) 
+(34.0) (25.0) (18.0) (13.0) (10.0) (9.0) (10.0) (13.0) (18.0) (25.0) 
+(29.0) (20.0) (13.0) (8.0) (5.0) (4.0) (5.0) (8.0) (13.0) (20.0) 
+(26.0) (17.0) (10.0) (5.0) (2.0) (1.0) (2.0) (5.0) (10.0) (17.0) 
+(25.0) (16.0) (9.0) (4.0) (1.0) (0.0) (1.0) (4.0) (9.0) (16.0) 
+(26.0) (17.0) (10.0) (5.0) (2.0) (1.0) (2.0) (5.0) (10.0) (17.0) 
+(29.0) (20.0) (13.0) (8.0) (5.0) (4.0) (5.0) (8.0) (13.0) (20.0) 
+(34.0) (25.0) (18.0) (13.0) (10.0) (9.0) (10.0) (13.0) (18.0) (25.0) 
+(200.0) (32.0) (25.0) (20.0) (17.0) (16.0) (17.0) (20.0) (25.0) (200.0) 
+----------------------------------------------------------------------------------
+Calling pmCullPeaks with NULL psList.  Should generate error and return NULL.
+(10.0) (0.0) (10.0) (0.0) (10.0) (0.0) (10.0) (0.0) (10.0) (0.0) 
+(0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) 
+(12.0) (0.0) (12.0) (0.0) (12.0) (0.0) (12.0) (0.0) (12.0) (0.0) 
+(0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) 
+(14.0) (0.0) (14.0) (0.0) (14.0) (0.0) (14.0) (0.0) (14.0) (0.0) 
+(0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) 
+(16.0) (0.0) (16.0) (0.0) (16.0) (0.0) (16.0) (0.0) (16.0) (0.0) 
+(0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) 
+(18.0) (0.0) (18.0) (0.0) (18.0) (0.0) (18.0) (0.0) (18.0) (0.0) 
+(0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) (0.0) 
+Set 25 peaks
+----------------------------------------------------------------------------------
+Calling pmCullPeaks with large maxValue and NULL psRegion.
+----------------------------------------------------------------------------------
+Calling pmCullPeaks with tiny maxValue and NULL psRegion.
+pmFindImagePeaks found 25 peaks
+----------------------------------------------------------------------------------
+Calling pmCullPeaks with large maxValue and disjoint psRegion.
+pmFindImagePeaks found 25 peaks
+----------------------------------------------------------------------------------
+Calling pmCullPeaks with large maxValue and non-disjoint psRegion.
+pmFindImagePeaks found 25 peaks
+----------------------------------------------------------------------------------
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with NULL psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with wrong-type psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with NULL psPeak.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with innerRadius<0.0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with innerRadius>outerRadius.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with subImage startRow < 0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with subImage endRow > numRows.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with subImage startCol < 0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with subImage endCol > numCols.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with NULL psSource.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with NULL psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with wrong type psImage.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with radius < 0.0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with subImage startCol < 0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with subImage endCol > numCols.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with subImage startRow < 0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with subImage endRow > numRows.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceSetPixelCircle with valid data.
+----------------------------------------------------------------------------------
+----------------------------------------------------------------------------------
+Calling pmSourceMoments with NULL psSource.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceMoments with radius < 0.0.  Should generate error and return NULL.
+----------------------------------------------------------------------------------
+----------------------------------------------------------------------------------
+Calling pmMinLM_Gauss2D with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Gauss2D with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Gauss2D with NULL x vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_PsuedoGauss2D with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_PsuedoGauss2D with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_PsuedoGauss2D with NULL x vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Wauss2D with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Wauss2D with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Wauss2D with NULL x vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_TwistGauss2D with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_TwistGauss2D with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_TwistGauss2D with NULL x vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Sersic with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Sersic with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_Sersic with NULL x vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_SersicCore with NULL deriv vector.  Should not generate error.
+----------------------------------------------------------------------------------
+Calling pmMinLM_SersicCore with NULL params vector.  Should generate error and return NAN.
+----------------------------------------------------------------------------------
+Calling pmMinLM_SersicCore with NULL x vector.  Should generate error and return NAN.
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with NULL psSource.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with NULL psImage.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with bad model type.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_GAUSS
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_PGAUSS
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_TWIST_GAUSS
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_WAUSS
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_SERSIC
+----------------------------------------------------------------------------------
+Calling pmSourceModelGuess with PS_MODEL_SERSIC_CORE
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+Calling pmSourceContour with NULL psSource .  Should generate error, return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceContour with NULL psImage .  Should generate error, return NULL.
+----------------------------------------------------------------------------------
+Calling pmSourceContour with acceptable data.
+NOTE: must figure out the parameters for this test to be meaningful.
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+Calling pmSourceAddModel with NULL psImage.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceAddModel with NULL psSrc.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceAddModel with acceptable data.
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+Calling pmSourceSubModel with NULL psImage.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceSubModel with NULL psSrc.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceSubModel with acceptable data.
+Calling pmSourceLocalSky with valid data.
+----------------------------------------------------------------------------------
+Calling pmSourceFitModel with NULL psImage.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceFitModel with NULL psSource.  Should generate error, return FALSE.
+----------------------------------------------------------------------------------
+Calling pmSourceFitModel with acceptable data.
+pmSourceFitModel returned 0
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stderr	(revision 22108)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: Test Point Driver{pmSubtractBias(): input parameter error conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    zero vector has incorrect size (5).  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Unallowable operation: psVector zero has incorrect type.
+<DATE><TIME>|<HOST>|W|pmReadoutCombine
+    WARNING: the zero vector too many elements (11)
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    scale vector has incorrect size (5).  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Unallowable operation: psVector scale has incorrect type.
+<DATE><TIME>|<HOST>|W|pmReadoutCombine
+    WARNING: the scale vector has too many elements (20)
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Output image (1, 1) is too small to hold combined images.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Output image offset is larger then input image offset.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Unallowable operation: inputs is NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Unallowable operation: params is NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Multiple statistical options have been requested.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (FILE:LINENO)
+    Unallowable operation: params->stats is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias(): input parameter error conditions} | tst_pmReadoutCombine.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmReadoutCombine.stdout	(revision 22108)
@@ -0,0 +1,79 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (1, 1)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (1, 20)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (20, 1)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (20, 20)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{Testing bad input parameter conditions}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL zero vector.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length zero vector (too small).  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect type zero vector.  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length zero vector (too big).  Should generate warning.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL scale vector.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length scale vector (too small).  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect type scale vector.  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length scale vector (too big).  Should generate warning.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() insufficient size output image.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() row0/col0 too large.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL input list.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL params.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with multiple stats->options.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL param->stats.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+============================================================================
+
+---> TESTPOINT PASSED (pmReadoutCombine{Testing bad input parameter conditions} | tst_pmReadoutCombine.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stderr	(revision 22108)
@@ -0,0 +1,132 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE and overscans does not equal NULL.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|GenNewStatOptions
+    WARNING: pmSubtractBias.c: GenNewStatOptions(): Too many statistics options have been specified
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.
+<DATE><TIME>|<HOST>|E|psSubtractFrame (FILE:LINENO)
+    bias image does not have enough rows.  Returning in image
+<DATE><TIME>|<HOST>|E|psSubtractFrame (FILE:LINENO)
+    bias image does not have enough columns.  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    fit is unallowable (54321).  Returning in image.
+<DATE><TIME>|<HOST>|E|pmSubtractBias (FILE:LINENO)
+    overScanAxis is unallowable (54321).  Returning in image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractBias.stdout	(revision 22108)
@@ -0,0 +1,432 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Testing input parameter error conditions}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ALL.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ROWS.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_COLUMNS.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with non-NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with PM_OVERSCAN_NONE and PM_FIT_POLYNOMIAL.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with PM_OVERSCAN_ALL and PM_FIT_SPLINE.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with multiple stats->options.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_ROWS).  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_COLUMNS).  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize bias image (short rows).  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize bias image (short columns).  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with bogus PM_FIT.  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with bogus overScanAxis.  Should generate Error.
+------------------------------------------------------------------
+
+---> TESTPOINT PASSED (pmSubtractBias{Testing input parameter error conditions} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stderr
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stderr	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stderr	(revision 22108)
@@ -0,0 +1,62 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: Test Point Driver{pmSubtractSky}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|p_psVectorSampleStdev
+    WARNING: p_psVectorSampleStdev(): only one valid psVector elements (1).  Setting stats->sampleStdev = 0.0.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|p_psVectorSampleStdev
+    WARNING: p_psVectorSampleStdev(): only one valid psVector elements (1).  Setting stats->sampleStdev = 0.0.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractSky} | tst_pmSubtractSky.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: Test Point Driver{pmSubtractSky: warning, error messages}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSubtractSky (FILE:LINENO)
+    Unallowable operation: psReadout in or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSubtractSky (FILE:LINENO)
+    Unallowable operation: psReadout in or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSubtractSky (FILE:LINENO)
+    Unallowable operation: psImage in has incorrect type.
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): input parameter stats is NULL
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): no stats->options was requested
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: Multiple statistical options have been requested.
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): binFactor is 0
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): binFactor is -1
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): clipSD is -1.000000
+<DATE><TIME>|<HOST>|E|pmSubtractSky (FILE:LINENO)
+    psFit is unallowable (54321).  Returning in image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractSky: warning, error messages} | tst_pmSubtractSky.c)
+
Index: /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stdout
===================================================================
--- /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stdout	(revision 22108)
+++ /tags/ipp-1-X/rel5_1/psModules/test/verified/tst_pmSubtractSky.stdout	(revision 22108)
@@ -0,0 +1,219 @@
+doSubtractSkySimple(1, 1, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, 1, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, 1, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, 1, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 4)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{Testing bad input parameter conditions.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL psReadout.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL psReadout->image.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PS_TYPE_F64 psReadout->image.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL fitSpec.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PM_FIT_NONE fit.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PM_FIT_SPLINE fit.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL myStats.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with no myStats->options specified.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with multiple myStats->options specified.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with 0 binFactor.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with -1 binFactor.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with -1.0 clipSD.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with bogus psFit.  Should generate Error.
+
+----------------------------------------------------------------
+
+---> TESTPOINT PASSED (pmSubtractSky{Testing bad input parameter conditions.} | tst_pmSubtractSky.c)
+
